Creating a Dynamic Starfield in Actionscript 3 Using the Flint Particle System
9 Jun
Spent a few hours this past weekend sqeezing every last bit of efficiency out of a starfield generator for Space Survivor. Fortunately, this was made extremely easy with Richard Lord’s very fine Flint Particle System.
The basic concept:
- Set up 4 particle emitters just outside the 4 edges of the screen
- Feed the Starfield a velocity vector from your ship’s movement engine
- use the velocity vector to give each generated particle a velocity opposite that of the ship
- use the built-in garbage collector of the Flint Particle System to destroy stars that go off screen
There are still some issues with it, like pre-filling the screen with stars, but here’s a demo of it in action. Code is below the fold:
To use the starfield generator, simply ad the starfield to your stage or a clip with:
_starField = new StarField(_clip.stage, _width, _height, 0, 0);
_clip.addChild(_starField.renderer);
_starField.start();
Where _width and _height are the width and height of your viewport.
And then in your game loop:
_starField.updateTargetVelocity(velX, velY);
Where velX and velY are the X and Y components of the velocity vector of your Object in Space.
And finally, here is the Starfield Class:
package SpaceSurvivor.starfields
{
import flash.display.Stage;
import flash.geom.Point;
import org.flintparticles.actions.*;
import org.flintparticles.counters.*;
import org.flintparticles.displayObjects.Dot;
import org.flintparticles.emitters.Emitter;
import org.flintparticles.initializers.*;
import org.flintparticles.renderers.*;
import org.flintparticles.zones.*;
public class StarField extends Emitter
{
private var _width:uint;
private var _height:uint;
private var _stage:Stage;
private var _targetVelocityAction:TargetVelocity;
private var _mult:int;
private var _starCount:Steady;
private var _isPaused:Boolean = false;
public function StarField(stage, width, height, velX, velY)
{
_width = width;
_height = height;
_stage = stage;
renderer = new DisplayObjectRenderer();
_starCount = new Steady(50, 100);
counter = _starCount;
addInitializer(new ImageClass(Dot, 1, 0x777777));
var multi:MultiZone = new MultiZone();
multi.addZone(new LineZone(new Point(-5,-5), new Point(_width+5,-5)));
multi.addZone(new LineZone(new Point(_width+5,-5), new Point(_width+5, _height+5)));
multi.addZone(new LineZone(new Point(_width+5, _height+5), new Point(-5, _height+5)));
multi.addZone(new LineZone(new Point(-5, _height+5), new Point(-5,-5)));
addInitializer(new Position(multi));
addInitializer(new ScaleInit( 0.5, 1.5 ) );
_targetVelocityAction = new TargetVelocity(velX, velY, 10);
addAction(_targetVelocityAction);
addAction(new Move());
addAction(new DeathOffStage());
}
public function updateTargetVelocity(_velX, _velY):void
{
if(_velX == 0 && _velY == 0) {
pause();
_isPaused = true;
} else if (_isPaused) {
resume();
_isPaused = false;
}
_targetVelocityAction.targetVelocityX = -_velX;
_targetVelocityAction.targetVelocityY = -_velY;
}
}
}

Recent Comments