Flash Hyperspace Star Field Tutorial

In this Flash tutorial we are going to make a nice "star field" effect. All you Star Trek junkies could call it the "warp speed effect". Use it for all your flying-through-particles needs. Are you ready to get your nerd on!

Hyperspace Star Field

The Flash plugin is required to view this example.

The effect is done using two functions, AddStar and FlyingStar. I'll explain everything in detail in this article. If you'd rather jump into the code and play, skip to the end and download the project.

The first step is setting a few control parameters. The following variables control our hyperspace travel effect. I've tried to comment thoroughly, so everything should be self explanatory.

// star control variables
var initVel:Number     = 7; // the starting speed of the star in pixels
var accel:Number       = 1.1; // the star's acceleration off the Stage
var alphaChange:Number = 10; // the fade in rate

// myInterval controls how quickly stars are added to the Stage
// the smaller the number, the more stars you'll have
var myInterval:Object  = setInterval(AddStar, 10); 

// maxOffset is the distance from center stage to a corner
// it is used to calculate the size of the star when it is "born"
var maxOffset:Number   = Math.sqrt(Math.pow((Stage.width/2),2) + Math.pow((Stage.height/2),2));

var i:Number           = 0; // star index

// create a container for all of our new stars
this.createEmptyMovieClip("universe_mc", 10); 

A star is born

The AddStar function places a star on the Stage and sets it up for flying. For this to work, you need a MovieClip called "star" set to Export For ActionScript in your library.

The star can be whatever you want it to be, a dot, a smiley face, a dancing banana. You're the boss.

As you can see in the code, we first attach the star to the universe_mc MovieClip that we made earlier. Next we place it randomly on the Stage by setting its _x and _y. I also wanted the stars to fade in, so I set the _alpha to zero here.

Once the star is placed, we need to figure out how big to make it and what direction to send it flying off the Stage. The size is based on how close it is to the center of the stage. The stars that show up in front of you will look bigger than ones that appear farther out to the edges. That's a personal choice, feel free to resize your stars however you like.

Figuring out the direction the stars should fly is the trickiest part of this script. You'll need to pull out your old trig book, or copy the code below. Basically we calculate the angle between the vertical axis and the line from the star to Stage center. Using that angle we calculate the star's velocity in the _x and _y directions. The stars will now travel in a straight line away from the center of the Stage.

Having the stars fly away from the center of the Stage is key to this effect, so make sure you get it right. Everything else just adds to the effect.

The final line in this block sets the star's onEnterFrame to the FlyingStar function. This function controls the motion of the star. We'll talk more about it next.

function AddStar() {
	// a star is born
	var curStar:MovieClip = universe_mc.attachMovie("star", "star_"+i, i);
	++i;
	
	// initialize the baby star
	curStar._x     = Math.random() * Stage.width;
	curStar._y     = Math.random() * Stage.height;
	curStar._alpha = 0;
	
	// calculate which angle star will fly
	// the angle is based on the position of the star from 
	// the center of the stage.
	var xOffset:Number     = curStar._x - (Stage.width/2);
	var yOffset:Number     = curStar._y - (Stage.height/2);
	var totalOffset:Number = Math.sqrt( xOffset*xOffset + yOffset*yOffset ); 
	var velAngle:Number    = Math.atan2(yOffset, xOffset);
	curStar._xVel = initVel * Math.cos( velAngle );
	curStar._yVel = initVel * Math.sin( velAngle );
	curStar._xscale = (maxOffset - totalOffset)/7;
	curStar._yscale = (maxOffset - totalOffset)/7;
	
	// fly away little star
	curStar.onEnterFrame = FlyingStar;
}

Wish upon a flying star

We've done all the hard work of placing our star and figuring out its velocity. Now all that's left is to send it flying. The FlyingStar function will shoot our stars on their merry way. Again, I'll step through this function for you and explain how it works.

The first part of the FlyingStar moves the position of the star based on the x and y velocities we calculated earlier. To make it look like we're really flying, we increase the speed of the star on each frame. This makes it accelerate off the page. To do the initial fade in, we increase the _alpha each frame until it is at 100.

If you wanted to get really fancy, you could also add a blur value to the star as it approached the edge of the Stage. I'll leave that to you to figure out on your own. If you get stumped, just shoot me an email.

Finally we check to see if the star has flown off the Stage. If it has, we remove it from the movie. Not doing this will allow the movie to use more and more memory with each star, eventually bogging down the whole computer. When you are dynamically adding infinite numbers of MovieClips to a movie, be sure to be deleting them just as fast.

function FlyingStar () : Void {
	// move the star
	this._x += this._xVel;
	this._y += this._yVel;
	
	// accelerate the star
	this._xVel *= accel;
	this._yVel *= accel;
	
	// fade the star in
	if (this._alpha < 100) this._alpha += alphaChange;
	else this._alpha = 100;
	
	// check if the star has left the stage
	// if it has, remove it so you don't hog memory
	if (  (this._x < -this._width) || 
		  (this._x > (Stage.width + this._width)) ||
		  (this._y < -this._height) ||
		  (this._y > (Stage.height + this._height))  ) {
		this.removeMovieClip();
	}
}

Warp speed ahead

Now you have everything you need to fly through space. Change variables we set up at the beginning to get different effects. Feel free to experiment all you want. If you really screw something up, just delete it all and start again. If only the real universe were so simple.

This project is published under the Creative Commons Attribution 3.0 License. Feel free to use it however you like. I always appreciate links back. If you have any problems with the scripts, please let me know.

Please post links to any Flash movies you've made using this tutorial. I'd love to see how it gets used in the wild.

This entry was posted in actionscript, Flash, Tutorials and tagged , , , . Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • bobotron

    This is great. Good explanation!

    I want to reverse the hyperdrive so they are all getting drawn to the middle. I did this by changing the x y coordinates to -= rather than +=, but how do I adjust the code at the end to remove them from the stage once they get close to the middle? Right now they cross the middle and keep going the other direction.

    • http://orangeSPLoTCH.com mattc

      An easy way to do this would be to check if the star is somewhere in the middle of the screen. The trick is including an appropriate fudge factor, since it is very unlikely that they will land right in the middle. The following code should do the trick.

      	// check if the star is in the middle of the stage
      	// if it is, remove it so you don't hog memory
      	var fudgeFactor:Number = 10;
      	if ( ((this._x < (Stage.width/2 + fudgeFactor) &&
      	      (this._x > (Stage.width/2 - fudgeFactor))) ||
      	     ((this._y < (Stage.height/2 + fudgeFactor) &&
      	      (this._y > (Stage.height/2 - fudgeFactor)))  ) {
      		this.removeMovieClip();
      	}

      You could make the x and y fudgeFactor values different if you needed to. This code would make a square window that they would disappear into. Please note that I am typing this up without having tested it, so it’s very likely I have typos or other bugs in it, but hopefully it will get you on your feet.

      If you want to get really fancy, you can calculate the distance from the center with a little trig and remove it if the distance is less than a certain number. This would give you a circle tunnel that the stars disappear around instead of the rectangular box that the above code does.

      Thanks for the feedback and good luck!

  • Leah

    Hey i used ur code and for some reason when i put other layer/stuff with it, the star are on top. And i’ve arranged my layers in order so everything is above the starfield. But nothing worked. Do u know how i can u fix my little problem? Thanks

  • http://orangeSPLoTCH.com mattc

    The reason the stars are showing up on top of everything is because we are creating the universe_mc dynamically and adding it to the stage. To keep the stars isolated to a specific layer, you’ll need to place a MovieClip in that layer and name it universe_mc and remove the following lines of the code:

    // create a container for all of our new stars
    this.createEmptyMovieClip("universe_mc", 10);

    Any layers above the layer you have the universe_mc on will show up over the stars. You can use this method to mask the star layer as well.

    If you are still having problems, feel free to contact me offline.

  • Leah

    Thanks for ur help :)

  • CyrilB

    Hello.
    First, excuse me for my english.
    I’ve the same problem than Leah but, even following your tips, i can’t make it work.
    I’ve created a layer in wich i’ve inserted a movieclip named universe_mc ; i’ve tested it inserting an action in the movieclip (with #include “StarField.as” or the complete script (excepting the line this.createEmptyMovieClip(“universe_mc”, 10);).
    In this state, no stars appears.
    Could you help me ?
    Thanks

  • http://orangeSPLoTCH.com mattc

    It sounds like the code isn’t finding the universe_mc MovieClip. Try adding a trace statement to your code to make sure the universe_mc is a valid object. Something like
    trace('universe_mc = ' + universe_mc);

    My guess is that it will show up as null. Go ahead and contact me offline and I’ll see if I can help you get it working.

  • Steve Jobs

    “Space the final frontier…”

  • van

    mattc, thanks a million for this. I searched far and wide and this is the only starfield tut out there that both works and makes sense.

    I had the same problem as leah and CyrilB. It seems that if you create a MC it doesn’t work at all unless you name the instance ‘universe_mc’ as well. This produces stars, but they’re generated about 200 pixels off to the right of the stage, so most of them never make it to the stage and live their short lives without ever being seen. Only the lucky few make it a few pixels onto the stage before petering out.

    I’ve looked at the code and traced some things but can’t figure this out. I’d really like to run two starfields simultaneously so….any ideas?

    Thanks,
    Van

  • http://orangeSPLoTCH.com mattc

    At the top of the AddStar function you’ll see this line:

    	var curStar:MovieClip = universe_mc.attachMovie("star", "star_"+i, i);

    This is where it attaches a new star to the universe_mc MovieClip and is the reason that this only works if the clip is named universe_mc.

    I’m guessing that the stars are being generated about 200 px off to the right of the stage because your universe_mc is not located at the extreme left edge of the screen, but instead starts about 200 px over to the right. If you move it to the left edge of the stage it should work.

    As for doing two starfields simultaneously, that’s a little trickier. I’ll send you an email so we can go over it offline.

  • Paul David Fisher