Tuesday, January 6, 2009

Tutorial 5: making the ship move (using our Vector2D class)

By the end of this tutorial, we will have this:


press A and D to rotate, and W to apply thrust

Wahey! 5 tutorials and finally something!

How'd I do it? Well, with our funky new Vector2D class it was very simple.

First, let's add a new key to listen to in the HumanPilot class. Remember our HumanPilot class, and how it inherits from Pilot? We wrote two variables for Pilot: _commandRotate and _commandThrust. Well in the HumanPilot class, for the event handlers we will write the following:

In the keyDownHandler we add the line:

if (event.keyCode == 87) _commandThrust = true; //W

and in the keyUpHandler we add:

if (event.keyCode == 87) _commandThrust = false; //W

So now pressing W will set the _commandThrust Boolean to true. So what will the thrust command do to our ship?

We need to add a few things to our Ship class: a few variables that define the Ship movement - its maximum speed, its acceleration, and finally its velocity. You know the difference between velocity and speed? Velocity's a vector, and speed is a number. Wow. Aren't you glad you learned that?

Then in the updateShip function, we're going to add a couple of things - we need it to react to commandThrust being true in the ship's Pilot, and we need to actually move the ship.

So we have two new methods: applyThrust() which creates a Vector2D based on the direction the ship is facing, and whose length is the ship acceleration. We then add this new vector to the velocity vector.

Notice that maxSpeed is divided by 25.0 (one second) because speed is distance/time. But acceleration is divided by 25.0 * 25.0, because acceleration is defined by distance over time squared. See? Physics. Oooooh.

Then we have moveShip(), which limits the ship's speed to it's maxSpeed (max is one of the few acceptable abbreviations. Again thanks intimidating conventions page).

This will be the last time I post the entirety of a class - they'll be getting bigger and bigger, especially the Ship class (it actually gets pretty chaotic, hence all the clear commenting I'm going to do). I'll just start uploading the entire project for you to peruse at your leisure. Here's the class, have a good, concentrated look at it:

////////////////////////////////////////////////////////////////////////////////
//
// AWOOGAMUFFIN
// Copyright er... I don't understand copyright. I think uploading this code
// possibly robs me of all rights. Just be nice - if you use my code, mention
// where you got it from, yeah?
//
// NOTICE: Awoogamuffin permits you to use, modify, and distribute this file
// in accordance with the terms of the license agreement accompanying it.
//
// Hahahaha, I just copied that from the conventions page (like everything I
// do). There's no license agreement. Stop looking for it.
//
// SHIP CLASS - chaos and craziness and head-aches
//
////////////////////////////////////////////////////////////////////////////////

package ships
{
import flash.display.*;
import flash.events.*;
import pilots.*;
import Maths.Vector2D;

public class Ship extends Sprite
{
//--------------------------------------------------------------------------
//
// VARIABLES
//
//--------------------------------------------------------------------------

//----------------------------------
// ship movement
//----------------------------------
private var _turnRate:Number = 300.0/25.0;
private var _maxSpeed:Number = 400.0/25.0;
private var _acceleration:Number = 250.0/(25.0 * 25.0);
private var _velocity:Vector2D = new Vector2D();


//----------------------------------
// visual
//----------------------------------
private var _shipImage:MovieClip;

//----------------------------------
// pilots
//----------------------------------
private var _controllingPilot:Pilot;

//--------------------------------------------------------------------------
//
// CONSTRUCTOR
//
//--------------------------------------------------------------------------

public function Ship()
{
_controllingPilot = new HumanPilot();
_controllingPilot.ship = this;

_shipImage = new blueLightFighterImage();
addChild(_shipImage);

x = 275;
y = 200;

//see bottom of file for updateShip
addEventListener(Event.ENTER_FRAME, updateShip)
}

//--------------------------------------------------------------------------
//
// GETTERS AND SETTERS
//
//--------------------------------------------------------------------------

public function get turnRate():Number
{
return _turnRate;
}

public function get velocity():Vector2D
{
return _velocity;
}

//--------------------------------------------------------------------------
//
// METHODS
//
//--------------------------------------------------------------------------

public function applyThrust()
{
var thrust:Vector2D = Vector2D.newVectorFromAngle(rotation);
thrust.length = _acceleration;
_velocity.addVector(thrust);
}

public function moveShip()
{
//first check that velocity is not above maxSpeed
if(_velocity.lengthSquared > _maxSpeed * _maxSpeed)
{
velocity.length = _maxSpeed;
}

x += _velocity.x;
y += _velocity.y;

//this next bit is just to make the ship bounce off the edges off the
//stage
if(x < 10 || x > 540)
{
x < 10 ? x = 10 : x = 540;
_velocity.x *= -0.3;
}
if(y < 10 || y > 390)
{
y < 10 ? y = 10 : y = 390;
_velocity.y *= -0.3;
}
}

//--------------------------------------------------------------------------
//
// EVENT HANDLERS
//
//--------------------------------------------------------------------------

public function updateShip(event:Event)
{
rotation += _controllingPilot.commandRotation;
if(_controllingPilot.commandThrust) applyThrust();

moveShip();
}
}
}

So there's a section that simply makes the ship bounce off the edges off the screen, which will be removed later. Oh and I also changed the background colour a little so that you can see the size of the stage (which I think i'll be changing eventually). Tadaaaa! Next step - let's have some enemy ships, and let's have them fly after us enthusiastically.

Oh, and here is the zip file of the entire project.

No comments:

Post a Comment