public function new()
super(Math.floor(FlxG.width / 2 - 8), Math.floor(FlxG.height / 2 - 8));
loadRotatedGraphic("assets/ship.png", 32, -1, false, true);
width *= 0.75;
height *= 0.75;
Note the #if flash conditional block. Remember that Haxe can build to several target platforms — and sometimes, some code may not work on a specific platform. This is where conditionals are used.
centerOffsets() is a convenient function that helps you set your game object’s origin to the center when its width or height has changed.
override public function update():Void
if (FlxG.keys.anyPressed(["A", "LEFT"]))
angularVelocity -= 240;
if (FlxG.keys.anyPressed(["D", "RIGHT"]))
angularVelocity += 240;
if (FlxG.keys.anyPressed(["W", "UP"]))
var bullet:FlxSprite = PlayState.bullets.recycle();
bullet.reset(x + (width - bullet.width) / 2, y + (height - bullet.height) / 2);
FlxAngle.rotatePoint(150, 0, 0, 0, bullet.angle, bullet.velocity);
bullet.velocity.x *= 2;
bullet.velocity.y *= 2;
angularVelocity and acceleration is part of FlxObject . One determines the rotation velocity, and another is the movement velocity. For most games which involve any sort of movement, you may end up using these two variables a lot. Check out the API for more info.
The code within the block above confused me at first — for example, where did angle come from? Oh, that’s because we set angularVelocity when we press the LEFT/RIGHT keys, and that affects the angle variable.
What about acceleration.set(); ? What does it do? Quite honestly, I don’t know. Removing that line doesn’t affect anything. In fact, if you look at the top of the code, there’s a _thrust variable that is never used. I guess the author made changes to the code a couple of times and forgot to remove redundant code.
When you press the UP key, the ship is supposed to accelerate. How does the code FlxAngle.rotatePoint(90, 0, 0, 0, angle, acceleration); affect movement when the function is called “rotatePoint”? Well, that’s because, if you look at the API, we’re passing the acceleration variable into the optional ?point:FlxPoint = null parameter. The value 90 is supposed to be the ship acceleration speed.
So what’s actually happening in rotatePoint() ? Referring to the API, here’s what it does, in point form:
- The X and Y values of (90, 0) is the default movement vector — in this case 90 in x-axis. The value 90 is the acceleration speed of the ship. Note that in Haxe, 0 degrees is right, -90 (or 270) is up, and +90 is down.
- The PivotX and PivotY values of (0, 0) are the rotation’s pivot points. In this case, it’s the center of the player’s ship.
- The Angle value is the ship’s current angle.
- The ?point value is the a FlxPoint (a container for X/Y values) to store the result rotation in.
Assuming the ship’s angle is -45 degrees (facing north-east), the function will take the default movement vector (90, 0) and rotate it around the pivot (0, 0) by -45 degrees, which results in the rotated X/Y vector. The result value is then conveniently assigned into the acceleration variable — which makes the ship move.
In the last part of the code, note the player’s bullet logic. Just like the asteroids, bullets are part of FlxTypedGroup and used like object pools. When the player presses SPACE (spacebar), a bullet is recycled for reuse, then fired in a velocity based on the player’s ship angle.
In the next part, we shall study the last source file, and wrap up this tutorial series.