<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7441051931482313977</id><updated>2011-04-21T16:31:34.635-07:00</updated><title type='text'>So you want to program a Flash game...</title><subtitle type='html'>A series of tutorials showing how to program a game in ActionScript 3 using Adobe Flash.

The game is a 2D space shooter, but it's going to be incredibly cool.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://flashgametutorials.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://flashgametutorials.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Awoogamuffin</name><uri>http://www.blogger.com/profile/03868669228439003143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Z1AHsdfvZf0/SuMEF5uPYSI/AAAAAAAAADc/RGp1kyDoL9A/S220/dreg.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7441051931482313977.post-4192280960113118609</id><published>2009-01-12T06:37:00.000-08:00</published><updated>2009-01-12T11:48:49.515-08:00</updated><title type='text'>Tutorial 7: new ships and Artifical Intelligence</title><content type='html'>Right, now that preloader nonsense is out of the way, let's get another ship up on the screen.&lt;br /&gt;&lt;br /&gt;This is what we'll have by the end of this tutorial:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;embed pluginspage=" http://www.macromedia.com/go/getflashplayer" src="http://sites.google.com/site/awoogamuffin/flashfiles/07ai.swf" type="application/x-shockwave-flash" height="400" width="550"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:78%;"&gt;press A and D to rotate, and W to apply thrust.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Get the whole zip file &lt;a href="http://sites.google.com/site/awoogamuffin/projectdirectories/07spaceGame.zip"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;New ship types. To inherit or not to inherit?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here's an interesting issue I've had. I want to make different kinds of ships. In the example above I have blueLightFighter and redLightFighter. Now, how do I define these?&lt;br /&gt;&lt;br /&gt;Before the Tragedy, I had them as classes that extended the Ship class, so I'd just write var myShip:Ship = new blueLightFighter();&lt;br /&gt;&lt;br /&gt;But since then, reading about OOP has got me worried about using inheritance when I don't need to. The thing is, blueLightFigher and redLightFighter have totally identical methods. In fact, the only difference they have is in the initial values for their attributes (such as maxSpeed or acceleration). Even with more complex ships, that may have multiple cannons and missile launchers, the only thing that's different is their constructor.&lt;br /&gt;&lt;br /&gt;This led me to think that maybe I should simply pass in a variable which tells the Ship constructor what values it should use for the ship attributes. Something like var myShip:Ship = new Ship(Ship.BLUE_LIGHT_FIGHTER). The Ship.BLUE_LIGHT_FIGHTER is a public static constant (which means it can be accessed through the class definition) which will then call a function within the Ship class that sets the attributes.&lt;br /&gt;&lt;br /&gt;But now we have another issue. I know for a fact that later on I'm going to start writing ship classes that do extend the methods of Ship - for example a great big carrier will actually have a rotationAcceleration value as well (as in it eases into rotation). Also, I'll be overriding collision detection methods. So then things would get complicated if I have to start writing:&lt;br /&gt;&lt;br /&gt;var myFighter:Ship = new Ship(Ship.BLUE_LIGHT_FIGHTER); //just change the ship attributes&lt;br /&gt;var myCarrier:Ship = new carrierShip(Ship.BLUE_CARRIER); //carrierShip extends the Ship class&lt;br /&gt;&lt;br /&gt;urgh. I prefer simply calling a new class each time. As in:&lt;br /&gt;&lt;br /&gt;myShip:Ship = new blueLightFighter();&lt;br /&gt;myOtherShip:Ship = new blueCarrier();&lt;br /&gt;&lt;br /&gt;Keeps things consistent. So even though my smaller ships don't need to extend the Ship class, they will do, to keep things simple when I start scripting my levels later on. All clear? Good, let's make some new ships.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Making a few changes to the Ship class.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So now in my game I'll never actually call new Ship(), but the name of a ship type that extends the Ship class. In the Ship constructor, I'll contain a call to a setShipAttributes() function (I hope it's purpose is self-explanatory). Within the Ship class, setShipAttributes is empty - it will be defined in the classes that inherit from it.&lt;br /&gt;&lt;br /&gt;I'm also going to add a few things - each ship will have a _shipType variable. This will be useful in the future for things like AI. I plan to use the classic rock-paper-sizzors form of game design regarding units - as in shipA is deadly against shipB, but vulnerable to shipC (which in turn might be vulnerable to shipB etc. etc.). So I don't want the AI just attacking the nearest ship - that ship might be the worst kind of ship to fight. Instead, it will look for the ship types it is most effective against...&lt;br /&gt;&lt;br /&gt;Also, let's add some arguments for the ship constructor - it's initial position and rotation.&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;//--------------------------------------------------------------------------&lt;br /&gt;//&lt;br /&gt;//  CONSTRUCTOR&lt;br /&gt;//&lt;br /&gt;//--------------------------------------------------------------------------&lt;br /&gt;  &lt;br /&gt;public function Ship(x:Number = 0, y:Number = 0, rotation:Number = 0)&lt;br /&gt;{&lt;br /&gt;   this.x = x;&lt;br /&gt;   this.y = y;&lt;br /&gt;   this.rotation = rotation;&lt;br /&gt;     &lt;br /&gt;   setShipAttributes();&lt;br /&gt;     &lt;br /&gt;   _aiPilot = new AIPilot(this);&lt;br /&gt;   _controllingPilot = _aiPilot;&lt;br /&gt;     &lt;br /&gt;   //see bottom of file for updateShip&lt;br /&gt;   addEventListener(Event.ENTER_FRAME, updateShip)&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;A nice thing about flash is that if you set a value for the arguments of a function, those arguments are now optional. So I could say var myShip:Ship = new blueLightFighter(20,50,45) to have a ship at position [20,50] and facing and angle of 45 degrees, but if I just write new blueLightFighter(20,50) there won't be an error - the constructor will merely use the default value of 0 degrees for rotation. Cool, eh?&lt;br /&gt;&lt;br /&gt;I've also added the public static consts for shipTypes. I've made them integers, so that I can classify them (as in all ship types below 10 are fighters, between 10 and 20 are corvettes, between 20 and 30 are frigates etc.). Also, integer comparisons are faster than string comparisons...&lt;br /&gt;&lt;br /&gt;So now let's create two new .as documents: blueLightFighter.as and redLightFighter.as. These will both be very simple classes, that inherit from Ship and simply override the setShipAttributes function. Here's blueLightFighter for example:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;//&lt;br /&gt;//  AWOOGAMUFFIN&lt;br /&gt;//  Copyright er... I don't understand copyright. I think uploading this code&lt;br /&gt;//  possibly robs me of all rights. Just be nice - if you use my code, mention&lt;br /&gt;//  where you got it from, yeah?&lt;br /&gt;//&lt;br /&gt;//  NOTICE: Awoogamuffin permits you to use, modify, and distribute this file&lt;br /&gt;//  in accordance with the terms of the license agreement accompanying it.&lt;br /&gt;//&lt;br /&gt;//  Hahahaha, I just copied that from the conventions page (like everything I&lt;br /&gt;//  do). There's no license agreement. Stop looking for it.&lt;br /&gt;//&lt;br /&gt;//  BLUE LIGHT FIGHTER&lt;br /&gt;//&lt;br /&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;package ships&lt;br /&gt;{&lt;br /&gt;   import pilots.*;&lt;br /&gt;&lt;br /&gt;   public class BlueLightFighter extends Ship&lt;br /&gt;   {&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  CONSTRUCTOR&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;  &lt;br /&gt;      public function BlueLightFighter(x:Number = 0, y:Number = 0, rotation:Number = 0.0)&lt;br /&gt;      {&lt;br /&gt;         super(x, y, rotation);&lt;br /&gt;      }&lt;br /&gt;  &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  OVERRIDDEN METHODS&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;  &lt;br /&gt;      override protected function setShipAttributes()&lt;br /&gt;      {&lt;br /&gt;         _shipType = Ship.BLUE_LIGHT_FIGHTER;&lt;br /&gt;     &lt;br /&gt;         //attributes specific to the blue light fighter class&lt;br /&gt;         shipImage = new blueLightFighterImage();&lt;br /&gt;         _turnRate = 300.0/25.0;&lt;br /&gt;         _maxSpeed = 450.0/25.0;&lt;br /&gt;         _acceleration = 100.0/(25.0 * 25.0);&lt;br /&gt;     &lt;br /&gt;         //give the ship a mind of its own:&lt;br /&gt;         _aiPilot = new AIPilot(this);&lt;br /&gt;     &lt;br /&gt;         addChild(shipImage);&lt;br /&gt;      }&lt;br /&gt;   } &lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;You might be full of wonder and excitement at the line _aiPilot = new AIPilot(), as indeed you should be.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Writing the AIPilot class:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now it's ridiculous how much time I sank into the AI before the tragedy. You get hooked up on all these tricky little details that any average user would probably never notice, but that grate against your soul. Keeping things simple and realistic is key, but ever so difficult to enforce.&lt;br /&gt;&lt;br /&gt;So we're going to write the AIPilot class. This will extend the Pilot class, so all it will do is interpret the situation, then set commandRotation and commandThrust to the valid setting - it will never actually modify the ship itself (hence the use of private variables). For now, all I'm going to have the AIPilot do is turn to face the targeted ship, and once it is facing the ship, apply thrust.&lt;br /&gt;&lt;br /&gt;So first of all, back in the Pilot class, we add the variable:&lt;br /&gt;&lt;br /&gt;private var _target:Ship;&lt;br /&gt;&lt;br /&gt;And we give this a getter and setter. The setter is important - because later whenever you set a new target for a Pilot, this will modify settings in the Pilot's previous target, as well at the new target. All this will happen in the setter, and I won't have to worry about it. For now, it doesn't do anything other than set the Pilot's _target variable...&lt;br /&gt;&lt;br /&gt;Right, so we add an updatePilot() function in our AIPilot class, and within it we do a little trigonometry to figure out the angle between the ship and its target - we can use this with the angle getter function for our Vector2D class. We then write a function faceAngle which will turn the ship towards the desired angle, and it returns a Boolean: true if the ship is now facing its target, false otherwise. So we'll simply have the AIPilot apply thrust when faceAngle returns true. Brilliant.&lt;br /&gt;&lt;br /&gt;Here's the AIPilot class:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;//&lt;br /&gt;//  AWOOGAMUFFIN&lt;br /&gt;//  Copyright er... I don't understand copyright. I think uploading this code&lt;br /&gt;//  possibly robs me of all rights. Just be nice - if you use my code, mention&lt;br /&gt;//  where you got it from, yeah?&lt;br /&gt;//&lt;br /&gt;//  NOTICE: Awoogamuffin permits you to use, modify, and distribute this file&lt;br /&gt;//  in accordance with the terms of the license agreement accompanying it.&lt;br /&gt;//&lt;br /&gt;//  Hahahaha, I just copied that from the conventions page (like everything I&lt;br /&gt;//  do). There's no license agreement. Stop looking for it.&lt;br /&gt;//&lt;br /&gt;//  AIPilot - the A stands for "Aaaaaaargh!"&lt;br /&gt;//&lt;br /&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;package pilots&lt;br /&gt;{&lt;br /&gt;   import ships.*;&lt;br /&gt;   import Maths.Vector2D;&lt;br /&gt;   &lt;br /&gt;   public class AIPilot extends Pilot&lt;br /&gt;   {      &lt;br /&gt;      public function AIPilot(ship:Ship)&lt;br /&gt;      {&lt;br /&gt;         super();&lt;br /&gt;         _ship = ship;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  METHODS&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      //called from the ship class&lt;br /&gt;      public function updatePilot()&lt;br /&gt;      {&lt;br /&gt;         //start by reseting all commands&lt;br /&gt;         resetCommands();&lt;br /&gt;         &lt;br /&gt;         //for now, we'll just have the AIPilot chase after its target&lt;br /&gt;         if(_target != null)&lt;br /&gt;         {&lt;br /&gt;            /* calculate angle between ship and target. I should probably put this sort of thing&lt;br /&gt;            in a trigonometry class */&lt;br /&gt;            var targetAngle:Number = 0.0;&lt;br /&gt;            var relativePosition:Vector2D = new Vector2D(_target.x - _ship.x, _target.y - _ship.y);&lt;br /&gt;            targetAngle = relativePosition.angle;&lt;br /&gt;            &lt;br /&gt;            //so turn ship towards this angle, and if it reaches it, apply thrust&lt;br /&gt;            if(faceAngle(targetAngle)) _commandThrust = true;&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;         &lt;br /&gt;      //faceAngle - will turn ship towards targetAngle, and if it reaches said angle it returns true&lt;br /&gt;      public function faceAngle(angle:Number):Boolean&lt;br /&gt;      {&lt;br /&gt;         //calculate the difference between target angle and the ship's angle&lt;br /&gt;         var difference:Number = angle - _ship.rotation;&lt;br /&gt;         var absDifference:Number = Math.abs(difference);&lt;br /&gt;         &lt;br /&gt;         //next part is a bit tricky due to the fact that we have a switch between 180 and -180&lt;br /&gt;         //first, if target is within turn rate of AI ship it'll go for it!&lt;br /&gt;         if(absDifference &lt;= _ship.turnRate || absDifference &gt;= (360 - _ship.turnRate))&lt;br /&gt;         {&lt;br /&gt;            //now the ship only turns the required number of degrees - which is less than the ship's&lt;br /&gt;            //turn rate&lt;br /&gt;            _commandRotation = difference;&lt;br /&gt;            return true; //ship facing angle&lt;br /&gt;         }&lt;br /&gt;            &lt;br /&gt;         //otherwise it will rotate to face target ship&lt;br /&gt;         else&lt;br /&gt;         {&lt;br /&gt;            //so first check if it needs to turn right&lt;br /&gt;            if(difference &gt; 0 &amp;&amp; absDifference &lt; 180 || absDifference &gt; 180 &amp;&amp; difference &lt; 0)&lt;br /&gt;            {&lt;br /&gt;               _commandRotation = _ship.turnRate;&lt;br /&gt;            }&lt;br /&gt;            //ok, so turn left then&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;               _commandRotation = -_ship.turnRate;&lt;br /&gt;            }&lt;br /&gt;         }&lt;br /&gt;         return false; //ship not facing angle yet&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      public function resetCommands()&lt;br /&gt;      {&lt;br /&gt;         _commandRotation = 0.0;&lt;br /&gt;         _commandThrust = false;&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now I think this AIPilot class is so wonderful that every ship should have one. Remember in Ship.as we had _controllingPilot? Well let's add an _aiPilot variable as well. This will be added to every ship in the constructor (as we saw earlier). This will be the default controllingPilot for all ships, so back in the Ship class, we add the line _controllingPilot = _aiPilot.&lt;br /&gt;&lt;br /&gt;Why don't we just put _aiPilot = new AIPilot() in the Ship class? It would be more efficient than having to write it in each ship class I make from now on, right? Well, the thing is I know that the AIPilot for a little fighter will function very differently from that AIPilot for an artillery ship. Yes, in the future, we will be extending AIPilot as well, and in each ship class, we'll be telling it what kind of AIPilot to create in the setShipAttributes function. See? Thinking ahead...&lt;br /&gt;&lt;br /&gt;In the updateShip function we also need to add: aiPilot.updatePilot().&lt;br /&gt;&lt;br /&gt;Fine, here's the whole Ship class... I'll just make it so you have to scroll through it - that way it doesn't take up most of this blog entry:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left; height: 400px;"&gt;&lt;pre&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;//&lt;br /&gt;//  AWOOGAMUFFIN&lt;br /&gt;//  Copyright er... I don't understand copyright. I think uploading this code&lt;br /&gt;//  possibly robs me of all rights. Just be nice - if you use my code, mention&lt;br /&gt;//  where you got it from, yeah?&lt;br /&gt;//&lt;br /&gt;//  NOTICE: Awoogamuffin permits you to use, modify, and distribute this file&lt;br /&gt;//  in accordance with the terms of the license agreement accompanying it.&lt;br /&gt;//&lt;br /&gt;//  Hahahaha, I just copied that from the conventions page (like everything I&lt;br /&gt;//  do). There's no license agreement. Stop looking for it.&lt;br /&gt;//&lt;br /&gt;//  SHIP CLASS - chaos and craziness and head-aches&lt;br /&gt;//&lt;br /&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;package ships&lt;br /&gt;{&lt;br /&gt;   import flash.display.*;&lt;br /&gt;   import flash.events.*;&lt;br /&gt;   import pilots.*;&lt;br /&gt;   import Maths.Vector2D;&lt;br /&gt;   &lt;br /&gt;   public class Ship extends Sprite&lt;br /&gt;   {&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  CLASS VARIABLES&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      public static const BLUE_LIGHT_FIGHTER = 1;&lt;br /&gt;      public static const RED_LIGHT_FIGHTER = 2;&lt;br /&gt;      &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  VARIABLES&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      //----------------------------------&lt;br /&gt;      //  ship movement&lt;br /&gt;      //----------------------------------&lt;br /&gt;      protected var _turnRate:Number = 300.0/25.0;&lt;br /&gt;      protected var _maxSpeed:Number = 400.0/25.0;&lt;br /&gt;      protected var _acceleration:Number = 250.0/(25.0 * 25.0);&lt;br /&gt;      protected var _velocity:Vector2D = new Vector2D();&lt;br /&gt;      &lt;br /&gt;      //----------------------------------&lt;br /&gt;      //  identifiers&lt;br /&gt;      //----------------------------------&lt;br /&gt;      protected var _shipType:int;&lt;br /&gt;      &lt;br /&gt;      //----------------------------------&lt;br /&gt;      //  visual&lt;br /&gt;      //----------------------------------&lt;br /&gt;      protected var shipImage:Sprite;&lt;br /&gt;      &lt;br /&gt;      //----------------------------------&lt;br /&gt;      //  pilots&lt;br /&gt;      //----------------------------------&lt;br /&gt;      private var _controllingPilot:Pilot;&lt;br /&gt;      protected var _aiPilot:AIPilot;&lt;br /&gt;      &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  CONSTRUCTOR&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      public function Ship(x:Number = 0, y:Number = 0, rotation:Number = 0)&lt;br /&gt;      {&lt;br /&gt;         this.x = x;&lt;br /&gt;         this.y = y;&lt;br /&gt;         this.rotation = rotation;&lt;br /&gt;         &lt;br /&gt;         setShipAttributes();&lt;br /&gt;         &lt;br /&gt;         _controllingPilot = _aiPilot;&lt;br /&gt;         &lt;br /&gt;         //see bottom of file for updateShip&lt;br /&gt;         addEventListener(Event.ENTER_FRAME, updateShip)&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  GETTERS AND SETTERS&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      public function get turnRate():Number&lt;br /&gt;      {&lt;br /&gt;         return _turnRate;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      public function get velocity():Vector2D&lt;br /&gt;      {&lt;br /&gt;         return _velocity;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      public function get aiPilot():AIPilot&lt;br /&gt;      {&lt;br /&gt;         return _aiPilot;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      public function get shiptype():int&lt;br /&gt;      {&lt;br /&gt;         return _shipType;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      public function set controllingPilot(pilot:Pilot)&lt;br /&gt;      {&lt;br /&gt;         _controllingPilot = pilot;&lt;br /&gt;         pilot.ship = this;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  METHODS&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      public function applyThrust()&lt;br /&gt;      {&lt;br /&gt;         var thrust:Vector2D = Vector2D.newVectorFromAngle(rotation);&lt;br /&gt;         thrust.length = _acceleration;&lt;br /&gt;         _velocity.addVector(thrust);&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      public function moveShip()&lt;br /&gt;      {&lt;br /&gt;         //first check that velocity is not above maxSpeed&lt;br /&gt;         if(_velocity.lengthSquared &gt; _maxSpeed * _maxSpeed)&lt;br /&gt;         {&lt;br /&gt;            _velocity.length = _maxSpeed;&lt;br /&gt;         }&lt;br /&gt;         &lt;br /&gt;         x += _velocity.x;&lt;br /&gt;         y += _velocity.y;&lt;br /&gt;         &lt;br /&gt;         //this next bit is just to make the ship bounce off the edges off the&lt;br /&gt;         //stage&lt;br /&gt;         if(x &lt; 10 || x &gt; 540)&lt;br /&gt;         {&lt;br /&gt;            x &lt; 10 ? x = 10 : x = 540;&lt;br /&gt;            _velocity.x *= -0.3;&lt;br /&gt;         }&lt;br /&gt;         if(y &lt; 10 || y &gt; 390)&lt;br /&gt;         {&lt;br /&gt;            y &lt; 10 ? y = 10 : y = 390;&lt;br /&gt;            _velocity.y *= -0.3;&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      protected function setShipAttributes()&lt;br /&gt;      {&lt;br /&gt;         //this is performed by child classes.&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  EVENT HANDLERS&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      public function updateShip(event:Event)&lt;br /&gt;      {&lt;br /&gt;         _aiPilot.updatePilot();&lt;br /&gt;         &lt;br /&gt;         rotation += _controllingPilot.commandRotation;&lt;br /&gt;         if(_controllingPilot.commandThrust) applyThrust();&lt;br /&gt;         &lt;br /&gt;         moveShip();&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Now back in the document class, in our startGame function we add these lines:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;public function startGame()&lt;br /&gt;{&lt;br /&gt;   //create the player ship&lt;br /&gt;   var myShip:Ship = new BlueLightFighter(100,300);&lt;br /&gt;   addChild(myShip);&lt;br /&gt;&lt;br /&gt;   //assign the human player as the ship's pilot&lt;br /&gt;   var humanPilot:HumanPilot = new HumanPilot();&lt;br /&gt;   myShip.controllingPilot = humanPilot;&lt;br /&gt;&lt;br /&gt;   //now let's make a red fighter&lt;br /&gt;   var enemyShip:Ship = new RedLightFighter(300,100);&lt;br /&gt;   addChild(enemyShip);&lt;br /&gt;&lt;br /&gt;   //this is silly - in the future part of that aiPilot's functionality will be to select it's own targets&lt;br /&gt;   enemyShip.aiPilot.target = myShip;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;One more thing, we need the HumanPilot class to know that it is controlling myShip, so in the Ship class, for the set controllingPilot() function we now have:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;public function set controllingPilot(pilot:Pilot)&lt;br /&gt;{&lt;br /&gt;   _controllingPilot = pilot;&lt;br /&gt;   pilot.ship = this;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And the result is an angry little red ship chasing after the blue ship and bumping against the edges of the screen. Not much of a game I admit, but things are coming along...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7441051931482313977-4192280960113118609?l=flashgametutorials.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://flashgametutorials.blogspot.com/feeds/4192280960113118609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://flashgametutorials.blogspot.com/2009/01/tutorial-7-new-ships-and-artifical.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/4192280960113118609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/4192280960113118609'/><link rel='alternate' type='text/html' href='http://flashgametutorials.blogspot.com/2009/01/tutorial-7-new-ships-and-artifical.html' title='Tutorial 7: new ships and Artifical Intelligence'/><author><name>Awoogamuffin</name><uri>http://www.blogger.com/profile/03868669228439003143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Z1AHsdfvZf0/SuMEF5uPYSI/AAAAAAAAADc/RGp1kyDoL9A/S220/dreg.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7441051931482313977.post-4246609940243191007</id><published>2009-01-10T06:21:00.000-08:00</published><updated>2009-01-10T17:29:13.190-08:00</updated><title type='text'>Tutorial 6: writing a preloader for AS3. Argh! Urgh!</title><content type='html'>Click &lt;a href="http://sites.google.com/site/awoogamuffin/projectdirectories/06spaceGame.zip"&gt;here&lt;/a&gt; to download the full project.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Needlessly long introduction:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This tutorial was supposed to be about creating new ships, and I was happily trundling down that road when a person called bluemagica in &lt;a href="http://board.flashkit.com/board/showthread.php?t=785920"&gt;the flash kit forums&lt;/a&gt; asked me why I was exporting my blueLightFighterImage symbol on the first frame (when you tick the export for Actionscript box in the properties menu, the export on first frame box is also ticked automatically) thereby instantly revealing my pitiful ignorance because I had to ask what the whole "export on first frame" option actually meant.&lt;br /&gt;&lt;br /&gt;Then &lt;a href="http://psvilans.wrongbananas.net/"&gt;Pazil&lt;/a&gt; came along and informed me that the export on first frame option means that the .swf will load up this symbol right at the start, before anything happens. This is bad. Why is it bad? Trust me, it's bad. Really, just believe me. Can't you just listen to me and cease this endless questioning? Fine, I'll explain.&lt;br /&gt;&lt;br /&gt;You've probably played a few flash games already. If you haven't, I order you immediately to go play &lt;a href="http://armorgames.com/play/1426/pillage-the-village"&gt;Pillage the Village&lt;/a&gt; which is probably the best thing to ever happen to me in my life.&lt;br /&gt;&lt;br /&gt;Anyway, so you've played these games, and you've noticed that at the beginning you have a little screen with a nice graphic and a progress bar showing you how much of the game has been loaded. In the funky parlance of our trade, this is called the &lt;span style="font-weight: bold;"&gt;preloader&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I hadn't thought about this problem. Before the Tragedy I hadn't had any problems because all my symbols were vector graphics. I chose vector graphics because they are so small - at the cost of a bit more processor crunching. My game never went above 70k, so there was next to no load time. But I appreciate that some of you might prefer to use great big bitmaps for your ships and whatnot, and don't forget that later we'll be wanting sound and maybe music, and all this needs to be loaded. So here was a problem that needed to be nipped in the bud.&lt;br /&gt;&lt;br /&gt;The unfortunate thing about the export on first frame option is that everything will be loaded before the preloader starts. This results in a blank white screen for as long as the game is loading, during which you'll lose some of your potential players, some of whom might become fans, some of whom might become groupies, which let's face it, is why we're programming, right? Chicks. Yup.&lt;br /&gt;&lt;br /&gt;So we don't want these library symbols to be exported on the first frame. We want them exported after the preloader starts.&lt;br /&gt;&lt;br /&gt;This is where I became upset.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Why I became upset:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;At the &lt;a href="http://flashgametutorials.blogspot.com/2008/12/first-of-all-i-highly-recommend-you.html"&gt;beginning of this series of tutorials&lt;/a&gt; I proudly declared that I would not be using the main timeline. It would all be gloriously Object Orientated fun. Now OOP is in contrast to sequential programming, and a timeline by it's very nature is sequential. So booooo timeline, I say.&lt;br /&gt;&lt;br /&gt;It turns out that if you untick the export on first frame option, the symbol simply will not be &lt;span style="font-weight: bold;"&gt;embedded&lt;/span&gt; into your .swf unless it is included in the timeline. I searched for countless minutes for a way to export library symbols with AS3, but to no avail. I wanted something where in the document class I'd have:&lt;br /&gt;&lt;br /&gt;create preloader&lt;br /&gt;start importing library symbols (while updating preloader)&lt;br /&gt;when everything has been loaded, start the game.&lt;br /&gt;&lt;br /&gt;But there's no action script function for "load library symbols". The only way to tell the compiler that I want those symbols involved in the game is to manually place them onto the stage at a frame which isn't frame one. Uurruurrrgh! Yucky.&lt;br /&gt;&lt;br /&gt;I really don't like this. It feels wrong, somehow. Dirty. Unethical even. But hey, I'm sick of fruitless google searches, so this is how we're going to do things. After hours of experimentation (far more than were necessary, more on that later) this is what I came up with:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Making the preloader:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So first of all, let's go to our blueLightFighterImage symbol, and un-tick that export on first frame box. Then in the main time-line we have to - urgh - insert a keyframe on frame 2. Within that frame, we'll place our blueLightFighter Image. Doesn't matter where, or what rotation, just so long as it's there. This frame will never actually be seen by anyone - but it will be checked by the compiler, which will then load it into memory. It's so hacky it makes me want to cry.&lt;br /&gt;&lt;br /&gt;Even worse, just to rub salt into the wound, we could right click on frame one, go to add actions, and noooo! code in the main timeline! We write:&lt;br /&gt;&lt;br /&gt;stop();&lt;br /&gt;&lt;br /&gt;Admittedly, I could actually just write this in the Document class, but I really feel like wallowing in self-pity, succumbing to the daemons of user-friendly interfaces.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Z1AHsdfvZf0/SWi4Xm-kaAI/AAAAAAAAABc/R8o1b8-9B2M/s1600-h/06timelineCode.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 248px;" src="http://1.bp.blogspot.com/_Z1AHsdfvZf0/SWi4Xm-kaAI/AAAAAAAAABc/R8o1b8-9B2M/s400/06timelineCode.gif" alt="" id="BLOGGER_PHOTO_ID_5289680478086129666" border="1" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;nooooooooooooo!&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;We then need to add an empty keyframe to frame 3. I'll explain why later.&lt;br /&gt;&lt;br /&gt;While we're modifying our blueLightFighterImage, I'm also going to set the base class to &lt;a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/Sprite.html"&gt;Sprite&lt;/a&gt;, not &lt;a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/MovieClip.html"&gt;MovieClip&lt;/a&gt; - I originally had it as MovieClip so that I could animate the ship explosion, but I've decided against that, and I have some funky plans. Making the ship a Sprite is easier on the memory. Bare in mind that this means back in the &lt;a href="http://flashgametutorials.blogspot.com/2008/12/tutorial-2-making-ship-appear-on-screen.html"&gt;Ship.as&lt;/a&gt; file we need to modify var shipImage:MovieClip to var shipImage:Sprite otherwise we get errors... I've also made a couple of other small changes in the Ship class, such as private variables which won't have a getter or setter applied no longer have the underscore before their names. Check out the &lt;a href="http://sites.google.com/site/awoogamuffin/projectdirectories/06spaceGame.zip"&gt;zip file&lt;/a&gt; of the entire project to have a look around if you want.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Z1AHsdfvZf0/SWi4XMXUp4I/AAAAAAAAABU/226x441putM/s1600-h/06properties.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 364px; height: 400px;" src="http://3.bp.blogspot.com/_Z1AHsdfvZf0/SWi4XMXUp4I/AAAAAAAAABU/226x441putM/s400/06properties.gif" alt="" id="BLOGGER_PHOTO_ID_5289680470942197634" border="1" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;don't export in first frame, and set the base class to sprite&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Now that icky wysiwyg nonsense is done, we can go back into the beautiful, pure simplicity of code. We're going to write a preloader class!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;The pre-loader class:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After scouring the internet, I've borrowed heavily from a post by a person called plutocrat on a &lt;a href="http://www.actionscript.org/forums/showthread.php3?t=137349"&gt;thread in the actionscript.org forums&lt;/a&gt;. I suggest you have a read to learn about potential issues and whatnot.&lt;br /&gt;&lt;br /&gt;The preloader knows how much has been loaded by accessing the root.loaderInfo class. I want the preloader to be a separate entity, so I'm going to have to use spaceGame.instance (remember &lt;a href="http://flashgametutorials.blogspot.com/2009/01/tutorial-3-getting-user-input-and.html"&gt;tutorial 3&lt;/a&gt;?) to access the root (or stage - I'm not entirely sure what the difference between root and stage is).&lt;br /&gt;&lt;br /&gt;Also, this is obviously a class that I'm going to be using often - for future games. Though the preloader for each game will presumably be different, the basics are the same. So I write a preloader class with a default display (all it does is create a black bar that extends across the bottom of the screen) which functions that can be &lt;span style="font-weight: bold;"&gt;overridden&lt;/span&gt; (more on that later) by a class which &lt;span style="font-weight: bold;"&gt;extends&lt;/span&gt; the preloader. This new class can be specific to the game, and have all the funky graphics it wants. Such is the beauty of OOP.&lt;br /&gt;&lt;br /&gt;I'll make a new package called preloaders which will contain both the generic preloader and later the one specific to this game.&lt;br /&gt;&lt;br /&gt;So this is my Preloader class (I don't capitalise the L because p is a prefix so I consider preloader to be one word. You might prefer to call it preLoader, but then you need to be consistent. So a function called unlock should be called unLock... similarly I need to be consistent in my naming).&lt;br /&gt;&lt;br /&gt;Here's the class:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;//&lt;br /&gt;//  AWOOGAMUFFIN&lt;br /&gt;//  Copyright er... I don't understand copyright. I think uploading this code&lt;br /&gt;//  possibly robs me of all rights. Just be nice - if you use my code, mention&lt;br /&gt;//  where you got it from, yeah?&lt;br /&gt;//&lt;br /&gt;//  NOTICE: Awoogamuffin permits you to use, modify, and distribute this file&lt;br /&gt;//  in accordance with the terms of the license agreement accompanying it.&lt;br /&gt;//&lt;br /&gt;//  Hahahaha, I just copied that from the conventions page (like everything I&lt;br /&gt;//  do). There's no license agreement. Stop looking for it.&lt;br /&gt;//&lt;br /&gt;//  PRELOADER - something I plan to recycle for each game I create&lt;br /&gt;//  I have borrowed heavily from code written by user plutocrat provided&lt;br /&gt;//  on actionscript.org forums on this thread:&lt;br /&gt;//  http://www.actionscript.org/forums/showthread.php3?t=137349&lt;br /&gt;//&lt;br /&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;package preloaders&lt;br /&gt;{&lt;br /&gt;  import flash.display.*;&lt;br /&gt;  import flash.events.*;&lt;br /&gt; &lt;br /&gt;  public class Preloader extends MovieClip&lt;br /&gt;  {&lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;     //&lt;br /&gt;     //  VARIABLES&lt;br /&gt;     //&lt;br /&gt;     //--------------------------------------------------------------------------     &lt;br /&gt;&lt;br /&gt;     protected var display:Sprite = new Sprite();&lt;br /&gt;    &lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;     //&lt;br /&gt;     //  CONSTRUCTOR&lt;br /&gt;     //&lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;    &lt;br /&gt;     public function Preloader()&lt;br /&gt;     {&lt;br /&gt;        createDisplay();&lt;br /&gt;        addChild(display);&lt;br /&gt;       &lt;br /&gt;        //accessing the root through my document class instance&lt;br /&gt;        SpaceGame.instance.root.loaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);&lt;br /&gt;        SpaceGame.instance.root.loaderInfo.addEventListener(Event.COMPLETE, completeHandler);&lt;br /&gt;     }&lt;br /&gt;    &lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;     //&lt;br /&gt;     //  METHODS&lt;br /&gt;     //&lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;     /* the following functions just provide a basic default. With later games,&lt;br /&gt;     I'll be writing preladers that inherit from this one, and override the&lt;br /&gt;     following functions to create displays specific to that game */&lt;br /&gt;    &lt;br /&gt;     public function createDisplay()&lt;br /&gt;     {&lt;br /&gt;        //to be created in child classes. Here it will just be a rectangle defined&lt;br /&gt;        //in the next function&lt;br /&gt;     }&lt;br /&gt;    &lt;br /&gt;     public function updateDisplay(percent:Number)&lt;br /&gt;     {&lt;br /&gt;        //thanks to plutocrat for revealing to me this "with" thing&lt;br /&gt;        with (display.graphics)&lt;br /&gt;        {&lt;br /&gt;           clear();&lt;br /&gt;           beginFill(0x000000);&lt;br /&gt;           drawRect(10,stage.stageHeight - 20,percent/100 * (stage.stageWidth - 10),10);&lt;br /&gt;        }&lt;br /&gt;     }&lt;br /&gt;    &lt;br /&gt;     public function removeDisplay()&lt;br /&gt;     {&lt;br /&gt;        removeChild(display);&lt;br /&gt;     }&lt;br /&gt;    &lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;     //&lt;br /&gt;     //  EVENT HANDLERS&lt;br /&gt;     //&lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;    &lt;br /&gt;     public function progressHandler(e:ProgressEvent)&lt;br /&gt;     {&lt;br /&gt;        updateDisplay(e.bytesLoaded/e.bytesTotal * 100);&lt;br /&gt;     }&lt;br /&gt;    &lt;br /&gt;     public function completeHandler(e:Event)&lt;br /&gt;     {&lt;br /&gt;        removeDisplay();&lt;br /&gt;        dispatchEvent(new Event(Event.COMPLETE));&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Talking a bit about Events:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Something of interest in this class is my use of &lt;a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/events/Event.html"&gt;events&lt;/a&gt;. The &lt;a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/LoaderInfo.html"&gt;loaderInfo&lt;/a&gt; class automatically sends out an event whenever it makes progress, and also when it completes loading (it dispatches several other events, such as initialisation and errors, which you can read about in the &lt;a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/class-summary.html"&gt;Flash documentation&lt;/a&gt;). Event.COMPLETE refers to a static string variable. If you write trace(Event.COMPLETE) anywhere in your code (you need to have imported flash.events.*) you'll get "complete". That's all it is - a string. Why use Event.COMPLETE then? Why not just type&lt;br /&gt;&lt;br /&gt;addEventListener("complete", completeHandler).&lt;br /&gt;&lt;br /&gt;Well, that would actually work. The problem is the very real possibility that you make a typo and write:&lt;br /&gt;&lt;br /&gt;addEventListener("compltee", completeHandler).&lt;br /&gt;&lt;br /&gt;This means your event listener will be waiting for the string "compltee" to be dispatched before it calls completeHandler, and obviously this will never happen, and your code will not work. You won't get any warning either - the compiler doesn't know that "compltee" is wrong, so you're none the wiser. On the other hand, if you write:&lt;br /&gt;&lt;br /&gt;addEventListener(Event.COMPLTEE, completeHandler)&lt;br /&gt;&lt;br /&gt;The compiler will see that in the Event class there is no static const COMPLTEE and will throw an error, informing you immediately of your mistake. It's just a time-saver to be honest, but in this trade, time saving can drastically improve your mood.&lt;br /&gt;&lt;br /&gt;I've also used dispatchEvent - when the preloader has finished, it shouts out "I've finished" with the line dispatchEvent(Event.COMPLETE). There's no reason for me not to use the static const Event.COMPLETE - in fact, it increases readability, and keeps the code consistent.&lt;br /&gt;&lt;br /&gt;I'll be discussing events in greater detail in a future tutorial.&lt;br /&gt;&lt;br /&gt;Back in the SpaceGame.as we'll create a preloader instance, and listen for that Event.COMPLETE before we start the game. I've written a new function startGame() which contains the code that used to be in the SpaceGame constructor.&lt;br /&gt;&lt;br /&gt;Also, when the preloader has finished, we need to jump to frame 3, because the symbols we put in frame 2 can only be used in later frames (oh how desperately sequential!). So we bight the bullet and write gotoAndStop(3). Read about &lt;a href="http://en.wikipedia.org/wiki/Goto"&gt;goto statements&lt;/a&gt; to see how bad they are. Wikipedia has a whole section on "criticism of goto usage".&lt;br /&gt;&lt;br /&gt;Here's the spaceGame class:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;//&lt;br /&gt;//  AWOOGAMUFFIN&lt;br /&gt;//  Copyright er... I don't understand copyright. I think uploading this code&lt;br /&gt;//  possibly robs me of all rights. Just be nice - if you use my code, mention&lt;br /&gt;//  where you got it from, yeah?&lt;br /&gt;//&lt;br /&gt;//  NOTICE: Awoogamuffin permits you to use, modify, and distribute this file&lt;br /&gt;//  in accordance with the terms of the license agreement accompanying it.&lt;br /&gt;//&lt;br /&gt;//  Hahahaha, I just copied that from the conventions page (like everything I&lt;br /&gt;//  do). There's no license agreement. Stop looking for it.&lt;br /&gt;//&lt;br /&gt;//  DOCUMENT CLASS - hopefully mostly empty at all times&lt;br /&gt;//&lt;br /&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;package&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;  import flash.display.*;&lt;br /&gt;  import flash.events.*;&lt;br /&gt; &lt;br /&gt;  import ships.Ship;&lt;br /&gt;  import Maths.Vector2D;&lt;br /&gt;  import preloaders.*;&lt;br /&gt; &lt;br /&gt;  public class SpaceGame extends MovieClip&lt;br /&gt;  {&lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;     //&lt;br /&gt;     //  STATIC VARIABLES (CLASS PROPERTIES)&lt;br /&gt;     //&lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;    &lt;br /&gt;     /*this will allow other classes to access the instance&lt;br /&gt;     of the document class created at the beginning of the game */&lt;br /&gt;     private static var _instance:SpaceGame;&lt;br /&gt;    &lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;     //&lt;br /&gt;     //  STATIC METHODS (CLASS METHODS)&lt;br /&gt;     //&lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;    &lt;br /&gt;     public static function get instance():SpaceGame&lt;br /&gt;     {&lt;br /&gt;        return _instance;&lt;br /&gt;     }&lt;br /&gt;    &lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;     //&lt;br /&gt;     //  VARIABLES&lt;br /&gt;     //&lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;    &lt;br /&gt;     private var preloader:Preloader;&lt;br /&gt;    &lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;     //&lt;br /&gt;     //  CONSTRUCTOR&lt;br /&gt;     //&lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;    &lt;br /&gt;     public function SpaceGame()&lt;br /&gt;     {&lt;br /&gt;        _instance = this;&lt;br /&gt;       &lt;br /&gt;        preloader = new Preloader();&lt;br /&gt;        addChild(preloader);&lt;br /&gt;       &lt;br /&gt;        preloader.addEventListener(Event.COMPLETE, preloaderCompleteHandler);&lt;br /&gt;     }&lt;br /&gt;    &lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;     //&lt;br /&gt;     //  METHODS&lt;br /&gt;     //&lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;    &lt;br /&gt;     public function startGame()&lt;br /&gt;     {&lt;br /&gt;        var myShip:Ship = new Ship();&lt;br /&gt;        addChild(myShip);&lt;br /&gt;     }&lt;br /&gt;    &lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;     //&lt;br /&gt;     //  EVENT HANDLERS&lt;br /&gt;     //&lt;br /&gt;     //--------------------------------------------------------------------------&lt;br /&gt;    &lt;br /&gt;     public function preloaderCompleteHandler(e:Event)&lt;br /&gt;     {&lt;br /&gt;        //always remove event listeners so that Garbage Collection can work&lt;br /&gt;        preloader.removeEventListener(Event.COMPLETE, preloaderCompleteHandler);&lt;br /&gt;        //don't need the preloader anymore&lt;br /&gt;        removeChild(preloader);&lt;br /&gt;        preloader = null;&lt;br /&gt;       &lt;br /&gt;        //have to do this for the symbols to be accessible. Ugly ugly ugly&lt;br /&gt;        gotoAndStop(3);&lt;br /&gt;       &lt;br /&gt;        //let's get on with it!&lt;br /&gt;        startGame();&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Great. But when we test the game, we see no preloader. How do check it's working?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Testing the preloader. Awoogamuffin wastes his precious time:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Sometimes my noob status really costs me a lot of time and energy. There are certain aspects of Flash that you just need to know about, and I don't. An example is the "disable keyboard shortcuts" option in the control menu when testing a movie. In fact, I'm going to go back to tutorial 2 to tell people they need to do that for the A key to register in the test movie.&lt;br /&gt;&lt;br /&gt;In this case, it was the fact that I was unaware that in the View menu while testing a movie, you can simulate download. It's brilliant. You can select download speed to see how long it would take, and obviously it allows you to test your preloader! Whee. Unfortunately for me I had a perfectly functional preloader for a long time, but thought it wasn't working because I couldn't get it to show up. Then I stumbled across &lt;a href="http://www.newgrounds.com/bbs/topic/699675"&gt;this post&lt;/a&gt; in the NewGrounds forum, and all became clear.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Z1AHsdfvZf0/SWi5xiljTGI/AAAAAAAAABk/VYiJw_AXyIw/s1600-h/06simulatedownload.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 273px;" src="http://4.bp.blogspot.com/_Z1AHsdfvZf0/SWi5xiljTGI/AAAAAAAAABk/VYiJw_AXyIw/s400/06simulatedownload.gif" alt="" id="BLOGGER_PHOTO_ID_5289682023095684194" border="1" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;Now there's an option I wish I'd known about earlier&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Also, my little blueLightFighterImage is tiny. So I go ahead and stick a great big image in the library (remembering to drag it onto the stage at frame 2), and test it with the "simulate Download" option. It seems to work! Wahoo! We have a preloader.&lt;br /&gt;&lt;br /&gt;Later on, I'll go ahead an extend the preloader to make something funky for this game. But that'll be later. First, we actually need a game.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7441051931482313977-4246609940243191007?l=flashgametutorials.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://flashgametutorials.blogspot.com/feeds/4246609940243191007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://flashgametutorials.blogspot.com/2009/01/tutorial-6-writing-preloader-for-as3.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/4246609940243191007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/4246609940243191007'/><link rel='alternate' type='text/html' href='http://flashgametutorials.blogspot.com/2009/01/tutorial-6-writing-preloader-for-as3.html' title='Tutorial 6: writing a preloader for AS3. Argh! Urgh!'/><author><name>Awoogamuffin</name><uri>http://www.blogger.com/profile/03868669228439003143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Z1AHsdfvZf0/SuMEF5uPYSI/AAAAAAAAADc/RGp1kyDoL9A/S220/dreg.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Z1AHsdfvZf0/SWi4Xm-kaAI/AAAAAAAAABc/R8o1b8-9B2M/s72-c/06timelineCode.gif' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7441051931482313977.post-4461911625488524407</id><published>2009-01-06T10:58:00.000-08:00</published><updated>2009-01-10T17:29:58.345-08:00</updated><title type='text'>Tutorial 5: making the ship move (using our Vector2D class)</title><content type='html'>By the end of this tutorial, we will have this:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;embed pluginspage=" http://www.macromedia.com/go/getflashplayer" src="http://sites.google.com/site/awoogamuffin/flashfiles/04movement.swf" type="application/x-shockwave-flash" height="400" width="550"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:78%;"&gt;press A and D to rotate, and W to apply thrust&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Wahey! 5 tutorials and finally something!&lt;br /&gt;&lt;br /&gt;How'd I do it? Well, with our funky new Vector2D class it was very simple.&lt;br /&gt;&lt;br /&gt;First, let's add a new key to listen to in the HumanPilot class. Remember our &lt;a href="http://flashgametutorials.blogspot.com/2009/01/tutorial-3-part-2-writing-humanpilot.html"&gt;HumanPilot class&lt;/a&gt;, and how it &lt;span style="font-weight: bold;"&gt;inherits&lt;/span&gt; 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:&lt;br /&gt;&lt;br /&gt;In the keyDownHandler we add the line:&lt;br /&gt;&lt;br /&gt;if (event.keyCode == 87) _commandThrust = true; //W&lt;br /&gt;&lt;br /&gt;and in the keyUpHandler we add:&lt;br /&gt;&lt;br /&gt;if (event.keyCode == 87) _commandThrust = false; //W&lt;br /&gt;&lt;br /&gt;So now pressing W will set the _commandThrust Boolean to true. So what will the thrust command do to our ship?&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://in.answers.yahoo.com/question/index?qid=20060925020535AAkA9s3"&gt;difference between velocity and speed&lt;/a&gt;? Velocity's a vector, and speed is a number. Wow. Aren't you glad you learned that?&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://en.wikipedia.org/wiki/Acceleration"&gt;acceleration&lt;/a&gt; is defined by &lt;a href="http://en.wikipedia.org/wiki/Metre_per_second_squared"&gt;distance over time squared&lt;/a&gt;. See? Physics. Oooooh.&lt;br /&gt;&lt;br /&gt;Then we have moveShip(), which limits the ship's speed to it's maxSpeed (max is one of the few acceptable abbreviations. Again thanks &lt;a href="http://opensource.adobe.com/wiki/display/flexsdk/Coding+Conventions"&gt;intimidating conventions page&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;//&lt;br /&gt;//  AWOOGAMUFFIN&lt;br /&gt;//  Copyright er... I don't understand copyright. I think uploading this code&lt;br /&gt;//  possibly robs me of all rights. Just be nice - if you use my code, mention&lt;br /&gt;//  where you got it from, yeah?&lt;br /&gt;//&lt;br /&gt;//  NOTICE: Awoogamuffin permits you to use, modify, and distribute this file&lt;br /&gt;//  in accordance with the terms of the license agreement accompanying it.&lt;br /&gt;//&lt;br /&gt;//  Hahahaha, I just copied that from the conventions page (like everything I&lt;br /&gt;//  do). There's no license agreement. Stop looking for it.&lt;br /&gt;//&lt;br /&gt;//  SHIP CLASS - chaos and craziness and head-aches&lt;br /&gt;//&lt;br /&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;package ships&lt;br /&gt;{&lt;br /&gt;   import flash.display.*;&lt;br /&gt;   import flash.events.*;&lt;br /&gt;   import pilots.*;&lt;br /&gt;   import Maths.Vector2D;&lt;br /&gt;   &lt;br /&gt;   public class Ship extends Sprite&lt;br /&gt;   {&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  VARIABLES&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      //----------------------------------&lt;br /&gt;      //  ship movement&lt;br /&gt;      //----------------------------------&lt;br /&gt;      &lt;b&gt;private var _turnRate:Number = 300.0/25.0;&lt;br /&gt;      private var _maxSpeed:Number = 400.0/25.0;&lt;br /&gt;      private var _acceleration:Number = 250.0/(25.0 * 25.0);&lt;br /&gt;      private var _velocity:Vector2D = new Vector2D();&lt;/b&gt;&lt;br /&gt;      &lt;br /&gt;      //----------------------------------&lt;br /&gt;      //  visual&lt;br /&gt;      //----------------------------------&lt;br /&gt;      private var _shipImage:MovieClip;&lt;br /&gt;      &lt;br /&gt;      //----------------------------------&lt;br /&gt;      //  pilots&lt;br /&gt;      //----------------------------------&lt;br /&gt;      private var _controllingPilot:Pilot;&lt;br /&gt;      &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  CONSTRUCTOR&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      public function Ship()&lt;br /&gt;      {&lt;br /&gt;         _controllingPilot = new HumanPilot();&lt;br /&gt;         _controllingPilot.ship = this;&lt;br /&gt;         &lt;br /&gt;         _shipImage = new blueLightFighterImage();&lt;br /&gt;         addChild(_shipImage);&lt;br /&gt;         &lt;br /&gt;         x = 275;&lt;br /&gt;         y = 200;&lt;br /&gt;         &lt;br /&gt;         //see bottom of file for updateShip&lt;br /&gt;         addEventListener(Event.ENTER_FRAME, updateShip)&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  GETTERS AND SETTERS&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      public function get turnRate():Number&lt;br /&gt;      {&lt;br /&gt;         return _turnRate;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      public function get velocity():Vector2D&lt;br /&gt;      {&lt;br /&gt;         return _velocity;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  METHODS&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      &lt;b&gt;public function applyThrust()&lt;/b&gt;&lt;br /&gt;      {&lt;br /&gt;         var thrust:Vector2D = Vector2D.newVectorFromAngle(rotation);&lt;br /&gt;         thrust.length = _acceleration;&lt;br /&gt;         _velocity.addVector(thrust);&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      &lt;b&gt;public function moveShip()&lt;/b&gt;&lt;br /&gt;      {&lt;br /&gt;         //first check that velocity is not above maxSpeed&lt;br /&gt;         if(_velocity.lengthSquared &gt; _maxSpeed * _maxSpeed)&lt;br /&gt;         {&lt;br /&gt;            velocity.length = _maxSpeed;&lt;br /&gt;         }&lt;br /&gt;         &lt;br /&gt;         x += _velocity.x;&lt;br /&gt;         y += _velocity.y;&lt;br /&gt;         &lt;br /&gt;         //this next bit is just to make the ship bounce off the edges off the&lt;br /&gt;         //stage&lt;br /&gt;         if(x &lt; 10 || x &gt; 540)&lt;br /&gt;         {&lt;br /&gt;            x &lt; 10 ? x = 10 : x = 540;&lt;br /&gt;            _velocity.x *= -0.3;&lt;br /&gt;         }&lt;br /&gt;         if(y &lt; 10 || y &gt; 390)&lt;br /&gt;         {&lt;br /&gt;            y &lt; 10 ? y = 10 : y = 390;&lt;br /&gt;            _velocity.y *= -0.3;&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  EVENT HANDLERS&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      public function updateShip(event:Event)&lt;br /&gt;      {&lt;br /&gt;         rotation += _controllingPilot.commandRotation;&lt;br /&gt;         &lt;b&gt;if(_controllingPilot.commandThrust) applyThrust();&lt;/b&gt;&lt;br /&gt;         &lt;br /&gt;         &lt;b&gt;moveShip();&lt;/b&gt;&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Oh, and here is the &lt;a href="http://sites.google.com/site/awoogamuffin/projectdirectories/spaceGame.zip"&gt;zip file&lt;/a&gt; of the entire project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7441051931482313977-4461911625488524407?l=flashgametutorials.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://flashgametutorials.blogspot.com/feeds/4461911625488524407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://flashgametutorials.blogspot.com/2009/01/tutorial-5-making-ship-move-using-our.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/4461911625488524407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/4461911625488524407'/><link rel='alternate' type='text/html' href='http://flashgametutorials.blogspot.com/2009/01/tutorial-5-making-ship-move-using-our.html' title='Tutorial 5: making the ship move (using our Vector2D class)'/><author><name>Awoogamuffin</name><uri>http://www.blogger.com/profile/03868669228439003143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Z1AHsdfvZf0/SuMEF5uPYSI/AAAAAAAAADc/RGp1kyDoL9A/S220/dreg.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7441051931482313977.post-4593857509548699419</id><published>2009-01-05T16:36:00.000-08:00</published><updated>2009-01-12T15:04:24.524-08:00</updated><title type='text'>Tutorial 4: writing a vector class (excitement)</title><content type='html'>We want to make the ship fly around, but how does this work? Well it's the same control scheme that's been confusing people since &lt;a href="http://en.wikipedia.org/wiki/Asteroids_%28video_game%29"&gt;Asteroids&lt;/a&gt; - the ship maintains a certain velocity, that can only be changed by applying a force (thrust) in the direction the ship is facing. Sounds like physics. Sounds like vectors.&lt;br /&gt;&lt;br /&gt;Vectors? If you don't know what I'm talking about, you have some serious &lt;a href="http://en.wikipedia.org/wiki/Euclidean_vector"&gt;reading to do&lt;/a&gt;, because I'm not doing a maths tutorial here. This is programming. Yes it is.&lt;br /&gt;&lt;br /&gt;I want to program a useful little Vector2D class. Where to put it? Yes, another package! Now we use the &lt;a href="http://www.miraztutorials.com/how-to-use-math-in-flash-professional-cs3-and-actionscript-3/"&gt;Math class&lt;/a&gt; within flash for all our basic Mathematic needs (like squareRoot and power etc.) but not Vector2D. So I'm going to create a package that is quintessentially British: Maths. If you're worried that you might get confused between Maths and Math, call it myMath or squirrelEggs, though I do want to point out that logical names are by far the best. You might think sometimes that my function names are stupidly long, but I prefer a long name than a name I can't remember. Generally abbreviations should be avoided for this reason.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Z1AHsdfvZf0/SWKq3XG2KvI/AAAAAAAAABM/PKWCctBDY6A/s1600-h/04directories.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 109px;" src="http://4.bp.blogspot.com/_Z1AHsdfvZf0/SWKq3XG2KvI/AAAAAAAAABM/PKWCctBDY6A/s400/04directories.gif" alt="" id="BLOGGER_PHOTO_ID_5287976780558641906" border="1" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;Brazil's a brilliant film&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;I'm going to be using this Vector2D class a lot, so I want to make it as simple to use as possible. That's why I'm going to use setters and getters for things like angle and length. So what are these damn things?&lt;br /&gt;&lt;br /&gt;Well &lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=04_OO_Programming_07.html"&gt;getters and setters&lt;/a&gt; are just function calls that do not need arguments. Also, you don't actually need a variable within the class for the getters and setters to get and set. For example, my Vector2D class will not have an angle variable, but you'll be able to get it and set it all the same (that's all done by playing with the x and y values).&lt;br /&gt;&lt;br /&gt;I'm going to be extending the &lt;a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/geom/Point.html#clone%28%29"&gt;Point class&lt;/a&gt;, because it shares a lot of functionality with vectors (as in, it has an x and y value, as well as length). We just want to add some stuff.&lt;br /&gt;&lt;br /&gt;Point happily provides us with a get length function, but not a set length function. What it does is provide us with a normalize function which allows you to set the length to anything you want. &lt;a href="http://mathworld.wolfram.com/NormalizedVector.html"&gt;This is not what normalise means&lt;/a&gt; (besides, they spell it normalize the Yankee bastards). Infuriatingly my text editor refuses to accept that normalise with an s is the correct spelling.&lt;br /&gt;&lt;br /&gt;So what I've done is given length a setter, and I've created my own noramalise function which, as it should, reduces the vector to the length of 1 unit. Note that &lt;a href="http://mathworld.wolfram.com/NormalVector.html"&gt;normalised and normal vectors are not the same&lt;/a&gt; (we'll be using normal vectors, of sorts, further down the line). Confused yet? Hope not.&lt;br /&gt;&lt;br /&gt;I've made a couple of static functions. Remember that? In fact, go read that &lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=04_OO_Programming_07.html"&gt;link&lt;/a&gt; about methods you ignored earlier when I was talking about getters and setters, it tells you all about them (calls them class methods). I'm using them mostly to provide me with alternative constructors (to create a vector based on an angle, or copying another vector).&lt;br /&gt;&lt;br /&gt;Quick note to somebody better than me - I would love to be able to override the Point.clone() function, but of course I would need it to return a Vector2D as opposed to a Point, and overriding functions have to return the same type. Is there some clever solution to this? I've vaguely read about overloading, but only to the point that it's not supported in ActionScript 3.&lt;br /&gt;&lt;br /&gt;For those of you who don't know what override means, don't worry, we'll get to it soon.&lt;br /&gt;&lt;br /&gt;Right, most of the rest of this tutorial will take place in comment form - here is the entire Vector2D class in all its wonderfulness, and notice my funky commenting scheme for clarity. As the classes get bigger and more complex, this kind of clarity is really useful. I've tried to get things right based on the &lt;a href="http://opensource.adobe.com/wiki/display/flexsdk/Coding+Conventions"&gt;intimidating programming conventions page&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;Hopefully the comments in this code should explain everything (if you're confused about anything, feel free to ask me questions in the blog comments).&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;//&lt;br /&gt;//  AWOOGAMUFFIN&lt;br /&gt;//  Copyright er... I don't understand copyright. I think uploading this code&lt;br /&gt;//  possibly robs me of all rights. Just be nice - if you use my code, mention&lt;br /&gt;//  where you got it from, yeah?&lt;br /&gt;//&lt;br /&gt;//  NOTICE: Awoogamuffin permits you to use, modify, and distribute this file&lt;br /&gt;//  in accordance with the terms of the license agreement accompanying it.&lt;br /&gt;//&lt;br /&gt;//  Hahahaha, I just copied that from the conventions page (like everything I&lt;br /&gt;//  do). There's no license agreement. Stop looking for it.&lt;br /&gt;//&lt;br /&gt;//  VECTOR2D - wonderful stuff with maths&lt;br /&gt;//&lt;br /&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;package Maths //call it myMath if you don't like the subtle British s&lt;br /&gt;{&lt;br /&gt;   import flash.display.*;&lt;br /&gt;   import flash.geom.Point;&lt;br /&gt;&lt;br /&gt;   /* I've decided to make Vector2D extend Point so that I can use the x and y&lt;br /&gt;   values it inherits */&lt;br /&gt;   &lt;br /&gt;   public class Vector2D extends Point&lt;br /&gt;   {&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  STATIC METHODS (CLASS METHODS)&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      /* that funky title you saw up there? Got that idea from the AS3 coding&lt;br /&gt;      conventions page... I think it looks cool. I've also tried to respect&lt;br /&gt;      the order they suggest but I get confused... the url for the convention&lt;br /&gt;      page is http://opensource.adobe.com/wiki/display/flexsdk/Coding+Conventions */&lt;br /&gt;      &lt;br /&gt;      /* these methods are basically alternative constructors, hence the term "new"&lt;br /&gt;      before each function name */&lt;br /&gt;      &lt;br /&gt;      //so we'd have: var myVector:Vector2D = Vector2D.newVectorFromAngle(90)&lt;br /&gt;      &lt;br /&gt;      //returns a normal vector pointing in the directions specified by angle&lt;br /&gt;      public static function newVectorFromAngle(angle:Number):Vector2D&lt;br /&gt;      {&lt;br /&gt;         var radians:Number = (angle - 90) * Math.PI / 180;&lt;br /&gt;         return new Vector2D(Math.cos(radians), Math.sin(radians));&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      public static function newVectorClone(vector:Vector2D):Vector2D&lt;br /&gt;      {&lt;br /&gt;         return new Vector2D(vector.x, vector.y);&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  CONSTRUCTOR&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      public function Vector2D(x = 0.0, y = 0.0)&lt;br /&gt;      {&lt;br /&gt;         this.x = x;&lt;br /&gt;         this.y = y;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  GETTERS AND SETTERS&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      /* I'm using getters and setters for dealing with vector length to make it&lt;br /&gt;      easier to code with vectors in the future */&lt;br /&gt;      &lt;br /&gt;      //returns the angle in which a vector is facing...&lt;br /&gt;      public function get angle():Number&lt;br /&gt;      {&lt;br /&gt;         /* first you have to normalise. If you know the vector is normal it's more&lt;br /&gt;         efficient to directly call getAngleFromNormal */&lt;br /&gt;         var normalisedVector:Vector2D = newVectorClone(this);&lt;br /&gt;         if(normalisedVector.normalise()) return normalisedVector.getAngleFromNormalised();&lt;br /&gt;         else return 0;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      public function set angle(angle:Number):void&lt;br /&gt;      {&lt;br /&gt;         var temp:Vector2D = newVectorFromAngle(angle);&lt;br /&gt;         temp.multiply(length);&lt;br /&gt;         this.copyVector(temp);&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      /* The Point class already has a length property, but it's read only, and I&lt;br /&gt;      want to be able to set it. The Point class has function called normalize()&lt;br /&gt;      which will set it to any length, but that's just wrong! A normalised vector&lt;br /&gt;      specifically has lengh 1, so I've written my own normalise function, and it's&lt;br /&gt;      spelt correctly too! see http://mathworld.wolfram.com/NormalizedVector.html */&lt;br /&gt;      public function set length(value:Number)&lt;br /&gt;      {&lt;br /&gt;         //see below for the normalise and multiply functions&lt;br /&gt;         if (normalise()) multiply(value);&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //getting the length squared is less espensive because it avoids Math.sqrt&lt;br /&gt;      public function get lengthSquared():Number&lt;br /&gt;      {&lt;br /&gt;         if (x == 0 &amp;&amp; y == 0) return 0;&lt;br /&gt;         else return x * x + y * y;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      //&lt;br /&gt;      //  METHODS&lt;br /&gt;      //&lt;br /&gt;      //--------------------------------------------------------------------------&lt;br /&gt;      &lt;br /&gt;      // does anyone know if it's possible to override + * and = operands?&lt;br /&gt;      &lt;br /&gt;      /* add is already a function for Point - it produces a new Point, but here I&lt;br /&gt;      just want to modify the current vector */&lt;br /&gt;      public function addVector(vector:Vector2D)&lt;br /&gt;      {&lt;br /&gt;         x += vector.x;&lt;br /&gt;         y += vector.y;&lt;br /&gt;      }&lt;br /&gt;      //Point has a function offset(x:Number, y:Number). Plus is just for two vectors&lt;br /&gt;      &lt;br /&gt;      public function multiply(factor:Number)&lt;br /&gt;      {&lt;br /&gt;         x *= factor;&lt;br /&gt;         y *= factor;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      /* Again, Point already has an equals function, but it's used for comparison as&lt;br /&gt;      opposed to assigning values... */&lt;br /&gt;      public function assignValues(x:Number, y:Number)&lt;br /&gt;      {&lt;br /&gt;         this.x = x;&lt;br /&gt;         this.y = y;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      public function copyVector(vector:Vector2D)&lt;br /&gt;      {&lt;br /&gt;         x = vector.x;&lt;br /&gt;         y = vector.y;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      //dot multiplication used for getting projection and whatnot&lt;br /&gt;      public function dot(vector:Vector2D):Number&lt;br /&gt;      {&lt;br /&gt;         return x * vector.x + y * vector.y;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //I'm only writing this because I can't override clone()&lt;br /&gt;      public function cloneVector2D():Vector2D&lt;br /&gt;      {&lt;br /&gt;         return new Vector2D(x, y);&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //sets vector length to one, or returns false if the vector is 0 length&lt;br /&gt;      public function normalise():Boolean&lt;br /&gt;      {&lt;br /&gt;         if (!(x == 0 &amp;&amp; y == 0))&lt;br /&gt;         {&lt;br /&gt;            var vectorLength:Number = Math.sqrt(x * x + y * y);&lt;br /&gt;            x /= vectorLength;&lt;br /&gt;            y /= vectorLength;&lt;br /&gt;            return true;&lt;br /&gt;         }&lt;br /&gt;         else&lt;br /&gt;         {&lt;br /&gt;            return false;&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      //returns the angle in which a normalised vector is facing...&lt;br /&gt;      //stupidly long name, but it's logical and I can remember it&lt;br /&gt;      public function getAngleFromNormalised():Number&lt;br /&gt;      {&lt;br /&gt;         /* look up acos and asin to learn how this works... it's all fun with&lt;br /&gt;         trigonometry! */&lt;br /&gt;         var temp:int;&lt;br /&gt;         Math.asin(-x) &gt; 0 ? temp = -1 : temp = 1;&lt;br /&gt;         var radians:Number = Math.acos(-y);&lt;br /&gt;         return (radians * 180 / Math.PI) * temp;&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Right, so now we want to check that all these functions work. So in the SpaceGame.as file I make some Vector2Ds and call their methods, then trace the results to see if they are as they should be. They are! Wahooo! I've commented the trace results but feel free to check it out yourself...&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;//THE DOCUMENT CLASS&lt;br /&gt;package&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;   import flash.display.*;&lt;br /&gt;   import flash.events.*;&lt;br /&gt;   &lt;br /&gt;   import ships.Ship;&lt;br /&gt;   import Maths.Vector2D;&lt;br /&gt;   &lt;br /&gt;   public class SpaceGame extends MovieClip&lt;br /&gt;   {&lt;br /&gt;      /*this will allow other classes to access the instance&lt;br /&gt;      of the document class created at the beginning of the game */&lt;br /&gt;      private static var _instance:SpaceGame;&lt;br /&gt;         &lt;br /&gt;      public static function get instance():SpaceGame&lt;br /&gt;      {&lt;br /&gt;         return _instance;&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      public function SpaceGame()&lt;br /&gt;      {&lt;br /&gt;         _instance = this;&lt;br /&gt;         &lt;br /&gt;         var myShip:Ship = new Ship();&lt;br /&gt;         addChild(myShip);&lt;br /&gt;         &lt;br /&gt;         //testing Vector class:&lt;br /&gt;         &lt;br /&gt;         //testing constructors&lt;br /&gt;         var vector1:Vector2D = new Vector2D();&lt;br /&gt;         trace("Basic constructor: "+vector1); //calls the Point toString() function which returns (x=0, y=0)&lt;br /&gt;         &lt;br /&gt;         var vector2 = new Vector2D(3,-4);&lt;br /&gt;         trace("Vector 2: "+vector2); //(x=3, y=-4)&lt;br /&gt;         trace("Vector2 length: "+vector2.length); //5. basic Pythagorus at work here&lt;br /&gt;         trace("Vector2 length squared: "+vector2.lengthSquared); //25. Yup. that's 5 * 5&lt;br /&gt;         &lt;br /&gt;         vector1.assignValues(0,3);&lt;br /&gt;         trace("Vector1 assigned values: "+vector1); //(x=0, y=3)&lt;br /&gt;         &lt;br /&gt;         vector1.addVector(vector2);&lt;br /&gt;         trace("vector1 += vector2: "+vector1);&lt;br /&gt;         &lt;br /&gt;         vector1 = Vector2D.newVectorFromAngle(45);&lt;br /&gt;         trace("normalised vector at 45 degrees: "+vector1); //(x=0.7071067811865476, y=-0.7071067811865475) - remember this&lt;br /&gt;         &lt;br /&gt;         vector1 = Vector2D.newVectorClone(vector2);&lt;br /&gt;         trace("vector1 constructor copying vector2: "+vector1); //(x=3, y=-5)&lt;br /&gt;         &lt;br /&gt;         vector1.assignValues(0,2.3456);&lt;br /&gt;         vector1.length = 6.0;&lt;br /&gt;         trace("vector1 assigning length to 6: "+vector1); //(x=0, y=6)&lt;br /&gt;         &lt;br /&gt;         vector1.multiply(2);&lt;br /&gt;         trace("vector1 * 2: "+vector1);&lt;br /&gt;         &lt;br /&gt;         vector1.angle = 45;&lt;br /&gt;         trace("vector1 angle assigned to 45: "+vector1); //(x=8.485281374238571, y=-8.48528137423857)&lt;br /&gt;         trace("vector1 length: "+vector1.length); //12&lt;br /&gt;         trace("vector1 angle: "+vector1.angle); //45.00000000000001&lt;br /&gt;         &lt;br /&gt;         vector1.normalise();&lt;br /&gt;         trace("vector1 normalised: "+vector1);//(x=0.7071067811865476, y=-0.7071067811865475) - remember from earlier?&lt;br /&gt;         trace("vector1 lenght: "+vector1.length); //1. The distance a normalised vector should be :-D&lt;br /&gt;         &lt;br /&gt;         trace("vector1 dot vector2: "+vector1.dot(vector2)); //4.949747468305833&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Great, we have a lovely new Vector2D class, so its time to use it, right? We want to make this damn ship move, no? That'll be for the next tutorial!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7441051931482313977-4593857509548699419?l=flashgametutorials.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://flashgametutorials.blogspot.com/feeds/4593857509548699419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://flashgametutorials.blogspot.com/2009/01/tutorial-4-writing-vector-class.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/4593857509548699419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/4593857509548699419'/><link rel='alternate' type='text/html' href='http://flashgametutorials.blogspot.com/2009/01/tutorial-4-writing-vector-class.html' title='Tutorial 4: writing a vector class (excitement)'/><author><name>Awoogamuffin</name><uri>http://www.blogger.com/profile/03868669228439003143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Z1AHsdfvZf0/SuMEF5uPYSI/AAAAAAAAADc/RGp1kyDoL9A/S220/dreg.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Z1AHsdfvZf0/SWKq3XG2KvI/AAAAAAAAABM/PKWCctBDY6A/s72-c/04directories.gif' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7441051931482313977.post-3598511642391722105</id><published>2009-01-04T09:56:00.000-08:00</published><updated>2009-01-10T07:20:37.966-08:00</updated><title type='text'>Tutorial 3 part 2 - writing the HumanPilot class and making the ship rotate (finally!)</title><content type='html'>Ok, we now want to make a HumanPilot class, which will set the commands depending on the keyboard input from the user. Here's what we write:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;//HUMAN pilot CLASS - takes keyboard input and sets commands for ship controlled by pilot&lt;br /&gt;package pilots&lt;br /&gt;{&lt;br /&gt;   import flash.events.*;&lt;br /&gt;   import ships.*;&lt;br /&gt;&lt;br /&gt;   public class HumanPilot &lt;span style="font-weight: bold;"&gt;extends Pilot&lt;/span&gt;&lt;br /&gt;   {&lt;br /&gt;      private var _commandLeft:Boolean = false;&lt;br /&gt;      private var _commandRight:Boolean = false;&lt;br /&gt;&lt;br /&gt;      public function HumanPilot()&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="font-weight: bold;"&gt;super()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;         &lt;span style="font-weight: bold;"&gt;SpaceGame.instance.stage.&lt;/span&gt;addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);&lt;br /&gt;         &lt;span style="font-weight: bold;"&gt;SpaceGame.instance.stage.&lt;/span&gt;addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public function keyDownHandler(event:KeyboardEvent)&lt;br /&gt;      {&lt;br /&gt;         if(_ship != null) //ship could be null, in which case we want to avoid errors...&lt;br /&gt;         {&lt;br /&gt;            //Handle rotation:&lt;br /&gt;            if (event.&lt;span style="font-weight: bold;"&gt;keyCode&lt;/span&gt; == 65) _commandLeft = true; //A&lt;br /&gt;            if (event.&lt;span style="font-weight: bold;"&gt;keyCode&lt;/span&gt; == 68) _commandRight = true; //D&lt;br /&gt;&lt;br /&gt;            processCommands()&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public function keyUpHandler(event:KeyboardEvent)&lt;br /&gt;      {&lt;br /&gt;         if(_ship)&lt;br /&gt;         {&lt;br /&gt;            if (event.&lt;span style="font-weight: bold;"&gt;keyCode&lt;/span&gt; == 65) _commandLeft = false; //A&lt;br /&gt;            if (event.&lt;span style="font-weight: bold;"&gt;keyCode&lt;/span&gt; == 68) _commandRight = false; //D&lt;br /&gt;&lt;br /&gt;            processCommands()&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public function processCommands()&lt;br /&gt;      {&lt;br /&gt;         _commandRotation = 0;&lt;br /&gt;         if(_commandLeft) _commandRotation = -&lt;span style="font-weight: bold;"&gt;_ship.turnRate&lt;/span&gt;;&lt;br /&gt;         if(_commandRight) _commandRotation = &lt;span style="font-weight: bold;"&gt;_ship.turnRate&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The important thing here are the words “&lt;span style="font-weight: bold;"&gt;extends Pilot&lt;/span&gt;”. This means that the HumanPilot class is actually a Pilot class, but with a few things attached. So HumanPilot class already has the _commandRotation and _commandThrust variables, and we don't need to write them again.&lt;br /&gt;&lt;br /&gt;In the HumanPilot constructor, we have the function &lt;span style="font-weight: bold;"&gt;super()&lt;/span&gt; - this just calls the parent class's &lt;span style="font-weight: bold;"&gt;constructor&lt;/span&gt; (which in the case of Pilot doesn't do anything).&lt;br /&gt;&lt;br /&gt;But Why use inheritance?&lt;br /&gt;&lt;br /&gt;Well other Pilot types (namely the AI ones) will also be using Pilot functionality (so the command variables are shared, but so are certain functions, such as selectNearestEnemy() or reassignTarget() etc.). If I write a selectNearestEnemy() function in the Pilot class, I don't have to paste the same function into all the other classes that will be needing it.&lt;br /&gt;&lt;br /&gt;The problem with &lt;a href="http://www.developer.com/design/article.php/3525076"&gt;inheritance is that it breaks encapsulation&lt;/a&gt; – now HumanPilot is dependent on Pilot, so I have to take both classes into account when I'm working on them. So if one day I realise that Pilot should take an argument in its constructor, I will have to modify the super() function calls in all the classes that inherit from Pilot. This is the kind of extra work which well-designed OOP should help us avoid. But sometimes inheritance is the obvious solution – if you have many different classes that all share the same core of functionality, inheritance is probably the way to go. (The link I provided about inheritance and encapsulation is a really nice explanation of OOP for stupid people like me).&lt;br /&gt;&lt;br /&gt;In "the biz" (I just made that up, real programmers don't say that) referring to relationships between classes we talk about "is a" or "has a". A dog "is a" mammal, so the class Dog would extend the class Mammal. That's easy. But a car "has" wheels - there wouldn't be inheritance there. This is clear but there are murkier examples.&lt;br /&gt;&lt;br /&gt;For instance, what about a wheel? A wheel "is a" circle, right? I'd disagree. It has a circle shape. But it has a lot more functionality and uses than a circle. So the relationship between wheel and circle would be a "has a", I think (the circle would be the visual variable, or the collision detection variable within the wheel class). It hurts my head to think about it sometimes.&lt;br /&gt;&lt;br /&gt;So back to the HumanPilot class. I've added two more variables, &lt;a href="http://en.wikipedia.org/wiki/Boolean_datatype"&gt;&lt;span style="font-weight: bold;"&gt;Booleans&lt;/span&gt;&lt;/a&gt; this time: commandLeft and commandRight. This is because of the fact that we can't trust a human player (bloody stupid dolt that he/she probably is) only to press one of the buttons at time. This input is then processed in the "processInput()" function into something the ship class can read easily (in this case, an angle).&lt;br /&gt;&lt;br /&gt;So we have a function which is called whenever a key is pressed, then another function which is called whenever a key is released. It takes as its argument a &lt;span style="font-weight: bold;"&gt;KeyboardEvent&lt;/span&gt; - this is what is passed from the event listener on the stage to the function that deals with it. Inside the KeyboardEvent I can access the variable &lt;span style="font-weight: bold;"&gt;keycode&lt;/span&gt;, which is &lt;a href="http://www.asciitable.com/"&gt;ASCII code&lt;/a&gt; for the key pressed by the user. I've decided to use the codes for A and D to deal with rotating the ship.&lt;br /&gt;&lt;br /&gt;This will set the _commandRotation to the angle at which the ship is to be rotated.&lt;br /&gt;&lt;br /&gt;I've set the angle to the ship's turn rate, but where is that? In the ship class of course. Maybe I've broken encapsulation a little bit because the Pilot is accessing the Ship's turn rate (I just don't know anymore!). But seeing as I know all ships will have a turn rate, I don't think should lead to any problems (famous last words). The reason I've made the _commandRotation an angle, and not just a command (turn left, turn right) is that, especially for the AI player, there will be times that I'll need the ship to turn at less than its turn rate - it'll be clearer when we get there.&lt;br /&gt;&lt;br /&gt;Anyway, look what I did for the keyboard input:&lt;br /&gt;&lt;br /&gt;SpaceGame.instance.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);&lt;br /&gt;&lt;br /&gt;What is SpaceGame.instance? I hear you cry. Well, my SpaceGame.as file now looks like this:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;//THE DOCUMENT CLASS&lt;br /&gt;package&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;   import flash.display.*;&lt;br /&gt;   import ships.Ship;&lt;br /&gt;   &lt;span style="font-weight: bold;"&gt;import flash.events.*;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   public class SpaceGame extends MovieClip&lt;br /&gt;   {&lt;br /&gt;      /*this will allow other classes to access the instance&lt;br /&gt; of the document class created at the beginning of the game */&lt;br /&gt;      &lt;span style="font-weight: bold;"&gt;private static var _instance:SpaceGame;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;      &lt;span style="font-weight: bold;"&gt;public static function get instance():SpaceGame&lt;/span&gt;&lt;br /&gt;      {&lt;br /&gt;         return _instance;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public function SpaceGame()&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="font-weight: bold;"&gt;_instance = this;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;         var myShip:Ship = new Ship();&lt;br /&gt;         addChild(myShip);&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I've created a new variable called _instance which is simply a pointer to the single &lt;span style="font-weight: bold;"&gt;instance&lt;/span&gt; (remember the difference between classes and instances) of document class SpaceGame created when the game starts. The variable is &lt;span style="font-weight: bold;"&gt;static&lt;/span&gt;, as is its “getter” function. A &lt;a href="http://en.wikipedia.org/wiki/Static_variable"&gt;static variable&lt;/a&gt; is a variable which is accessed through the class definition, as opposed to an instance of the class. Wuh?&lt;br /&gt;&lt;br /&gt;Let's go back to Plato and his horse. In any specific instance of a horse, for instance my imaginary horse Buttercup, we have several variables specific to that instance. So Buttercup's variables of position, hair-colour, speed, strength, cuteness, affinity to kicking people in sensitive areas are all specific to her. But if I think of the ideal horse, the blue-print for all other horses (the class definition) then there are certain variables that are true to that class, and can be accessed through the ideal as opposed to a single instance. Variables such as class = mammal, diet = herbivore, inspirationForBadTeenageGirlArt = true. So instead of accessing Buttercup.diet I'd go straight to Horse.diet. I'm sure you didn't bother reading that paragraph. I wouldn't have.&lt;br /&gt;&lt;br /&gt;Anyway, this means I can access the “get” function for _instance directly through the class definition of SpaceGame. Access simply points to the instance of the game created in the SpaceGame constructor (that's what “this” refers to). I can do this because there will only ever be one instance of the class SpaceGame, but its a bit weird - I'm accessing the instance through the class definition. urgh...&lt;br /&gt;&lt;br /&gt;So from any other class, I can now type SpaceGame.instance and be accessing the document class SpaceGame. And remember what we did before? We accessed the stage through the document class. All this leads to the rather convoluted way of accessing the stage: Spacegame.access.stage. If there's a better way of doing this, please inform me!&lt;br /&gt;&lt;br /&gt;The nice thing about this is that the HumanPilot class has its event listeners assigned from within its constructor, and I don't need to apply them from anywhere else.&lt;br /&gt;&lt;br /&gt;Anyway, we saw in the HumanPilot class that I was setting _commandRotation to the ship's turn rate. So let's have a look inside our Ship class:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;//SHIP CLASS - controls ship attributes and movement&lt;br /&gt;package ships&lt;br /&gt;{&lt;br /&gt;   import flash.display.*;&lt;br /&gt;   import flash.events.*;&lt;br /&gt;   &lt;span style="font-weight: bold;"&gt;import pilots.*;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   public class Ship extends Sprite&lt;br /&gt;   {&lt;br /&gt;       //SHIP ATTRIBUTES&lt;br /&gt;      &lt;span style="font-weight: bold;"&gt;private var _turnRate:Number = 300.0/25.0;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;      private var _shipImage:MovieClip;&lt;br /&gt;&lt;br /&gt;      &lt;span style="font-weight: bold;"&gt;private var _controllingPilot:Pilot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;      &lt;span style="font-weight: bold;"&gt;public function get turnRate():Number&lt;/span&gt;&lt;br /&gt;      {&lt;br /&gt;         return _turnRate;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public function Ship()&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="font-weight: bold;"&gt;_controllingPilot = new HumanPilot();&lt;/span&gt;&lt;br /&gt;         &lt;span style="font-weight: bold;"&gt;_controllingPilot.ship = this;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;         _shipImage = new blueLightFighterImage();&lt;br /&gt;         addChild(_shipImage);&lt;br /&gt;&lt;br /&gt;         x = 275;&lt;br /&gt;         y = 200;&lt;br /&gt;&lt;br /&gt;         &lt;span style="font-weight: bold;"&gt;addEventListener(Event.ENTER_FRAME, updateShip)&lt;/span&gt;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public function updateShip(event:Event)&lt;br /&gt;      {&lt;br /&gt;         rotation += controllingPlayer.commandRotation;&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;In the ship class, I have a variable called &lt;span style="font-weight: bold;"&gt;currentPilot&lt;/span&gt;. Current because every ship will automatically have an AIPilot assigned to it (we'll be programming that in a later tutorial), but depending on what happens within the level, that AIPilot might be overridden by the player, or by a puppet master. For now, we're just going to create a HumanPilot and have it be the ship's pilot. Notice that we have to set the HumanPilot's _ship variable because it doesn't have one by default (the setter allows us to do this, even though the _ship variable is protected).&lt;br /&gt;&lt;br /&gt;We also have a private variable called _turnRate. This will be set when the ship is created, but not modified later (though who knows? We might find a need for that later). So it was a "getter" but no "setter". This is the value by which the ship turns in a single frame. I've written it as 300.0/25.0 because it's easier for me to understand – that means 300 degrees per second (25 frames per second – remember we set that frame rate earlier in this tutorial?). The .0 is because of the &lt;a href="http://opensource.adobe.com/wiki/display/flexsdk/Coding+Conventions#CodingConventions-LanguageUsage"&gt;convention&lt;/a&gt; for denoting Numbers literals.&lt;br /&gt;&lt;br /&gt;There are certain things the ship will do every frame, such as move or rotate, so we're going to have an updateShip function which is called every frame (done with an event listenener again - Event.ENTER_FRAME can be accessed anywhere, not just from the stage). We need to keep this function as simple as possible, because it will be called for every ship 25 times a second. No expensive equations here, please.&lt;br /&gt;&lt;br /&gt;So far, all we're doing in the update ship is rotating it depending on the command being sent by the currentPilot (in this case, the user). We simply add the value of shipPilot.commandRotation to the ship's rotation.&lt;br /&gt;&lt;br /&gt;When you test your movie, however, you might notice that the A button doesn't register. This is because it is a flash keyboard shortcut that selects some tool or another. You have to go to the control menu and select "Disable keyboard shortcuts". Then it should work, and you'll have something that hopefully looks like this:&lt;br /&gt;&lt;br /&gt;&lt;embed pluginspage=" http://www.macromedia.com/go/getflashplayer" src="http://sites.google.com/site/awoogamuffin/flashfiles/03rotate.swf" type="application/x-shockwave-flash" height="400" width="550"&gt;&lt;/embed&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:78%;"&gt;press A and D to rotate the ship&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Isn't that ridiculously exciting?&lt;br /&gt;&lt;br /&gt;What we really want is to have the ship flying around, but before we can do that we need to program a very useful, if slightly technical (read boring) tutorial. For most movement in this game we're going to use 2D vectors (remember those? Wish you had listened in Maths or Physics now?). Those will be the subject of our next tutorial…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7441051931482313977-3598511642391722105?l=flashgametutorials.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://flashgametutorials.blogspot.com/feeds/3598511642391722105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://flashgametutorials.blogspot.com/2009/01/tutorial-3-part-2-writing-humanpilot.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/3598511642391722105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/3598511642391722105'/><link rel='alternate' type='text/html' href='http://flashgametutorials.blogspot.com/2009/01/tutorial-3-part-2-writing-humanpilot.html' title='Tutorial 3 part 2 - writing the HumanPilot class and making the ship rotate (finally!)'/><author><name>Awoogamuffin</name><uri>http://www.blogger.com/profile/03868669228439003143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Z1AHsdfvZf0/SuMEF5uPYSI/AAAAAAAAADc/RGp1kyDoL9A/S220/dreg.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7441051931482313977.post-4021020395857676971</id><published>2009-01-04T03:57:00.000-08:00</published><updated>2009-01-04T10:01:07.466-08:00</updated><title type='text'>Tutorial 3: getting user input and making the ship rotate. Creating a pilot class, and having fun with inheritance!</title><content type='html'>So we have a ship on the screen, big whoop-di-doo. We want this thing to actually react to our input, right? By the end of this tutorial we should have this:&lt;br /&gt;&lt;br /&gt;&lt;a style="left: 0px ! important; top: 15px ! important;" title="Click here to block this object with Adblock Plus" class="abp-objtab-09430410872517584 visible ontop" href="http://sites.google.com/site/awoogamuffin/flashfiles/03rotate.swf"&gt;&lt;/a&gt;&lt;embed pluginspage=" http://www.macromedia.com/go/getflashplayer" src="http://sites.google.com/site/awoogamuffin/flashfiles/03rotate.swf" type="application/x-shockwave-flash" height="400" width="550"&gt;&lt;/embed&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:78%;"&gt;press A and D to rotate the ship. Oh and click on the flash file for it to become active&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So, here's how we're going to do it...&lt;br /&gt;&lt;br /&gt;First of all, if we're going to get things moving in this game, we need to decide how. I like things nice and smooth, so in the spaceGame.fla file I set the frames per second to 25. Also, I'm not going to bother having the game work in real time – so if the computer is slow, the game is slower too. This isn't very professional of me, but I'm doing it to allow me to have complete control over how things move, allowing for simpler collision detection and other such things later on.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Z1AHsdfvZf0/SWC0gYo5LYI/AAAAAAAAABE/qc5XwXeHft8/s1600-h/03framerate.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 83px;" src="http://1.bp.blogspot.com/_Z1AHsdfvZf0/SWC0gYo5LYI/AAAAAAAAABE/qc5XwXeHft8/s400/03framerate.gif" alt="" id="BLOGGER_PHOTO_ID_5287424430995746178" border="1" /&gt;&lt;/a&gt;&lt;br /&gt;In AS3, we get user input by adding special &lt;span style="font-weight: bold;"&gt;Event Listeners&lt;/span&gt; to the stage. In a later tutorial I'm going to go into great detail on event listeners and dispatchers (when we start to create our own ones, that is), but for now we'll just look at how they are used to get keyboard input.&lt;br /&gt;&lt;br /&gt;So the &lt;span style="font-weight: bold;"&gt;stage&lt;/span&gt;, as far as I can tell, is the main MovieClip which all the visual elements of the game reside in. It's here that we'll be “listening” for key-strokes. To do this we use the &lt;span style="font-weight: bold;"&gt;addEventListener&lt;/span&gt; function. We need to add the event listener to the stage, and it will happily sit there waiting for keyboard input. Once that input arrives, it will then call the keyDownHandler() function within ship, so within the Ship class we might have the line:&lt;br /&gt;&lt;br /&gt;stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);&lt;br /&gt;&lt;br /&gt;But unfortunately in AS3 you can only access the stage from an object which has been added to the display list. So, if we write this in the ship class:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;//THE SHIP CLASS&lt;br /&gt;package ships&lt;br /&gt;{&lt;br /&gt;  import flash.display.*;&lt;br /&gt;  &lt;span style="font-weight: bold;"&gt;import flash.events.*;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  public class Ship extends Sprite&lt;br /&gt;  {&lt;br /&gt;     private var _shipImage:MovieClip;&lt;br /&gt;&lt;br /&gt;     public function Ship()&lt;br /&gt;     {&lt;br /&gt;        //add event listener to stage&lt;br /&gt;        &lt;span style="font-weight: bold;"&gt;stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        _shipImage = new blueLightFighterImage();&lt;br /&gt;        addChild(_shipImage);&lt;br /&gt;&lt;br /&gt;        x = 275;&lt;br /&gt;        y = 200;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     //function to be called whenever event listener detects user input&lt;br /&gt;     &lt;span style="font-weight: bold;"&gt;public function keyDownHandler(event:Event)&lt;br /&gt;     {&lt;br /&gt;        trace("I have pressed a key!");&lt;br /&gt;     }&lt;/span&gt;&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;We get this error:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;TypeError: Error #1009: Cannot access a property or method of a null object reference.&lt;br /&gt;  at ships::Ship$iinit()&lt;br /&gt;  at spaceGame$iinit()&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This is because the Ship hasn't been added to the display list (as in, we haven't called &lt;span style="font-weight: bold;"&gt;addChild(myShip)&lt;/span&gt; yet), and it has no access to the stage. Also, notice that to be able to use addEventListener() I've imported &lt;span style="font-weight: bold;"&gt;flash.events.*&lt;/span&gt;. Again laziness with the wildcard...&lt;br /&gt;&lt;br /&gt;Also, I've started commenting my code. You really want to do this, even when you work on your own - I've often hated/loved my former self based on how much information I had decided to leave me about the weird stuff I'd programmed.&lt;br /&gt;&lt;br /&gt;So what do we do?&lt;br /&gt;&lt;br /&gt;Well, the document class (defined in SpaceGame.as) has access to the stage, so we could add keyboard event listeners from the document class to the Ship class...&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;//THE DOCUMENT CLASS&lt;br /&gt;package&lt;br /&gt;{&lt;br /&gt;  import flash.display.*;&lt;br /&gt;  import ships.Ship;&lt;br /&gt;  &lt;span style="font-weight: bold;"&gt;import flash.events.*;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  public class spaceGame extends MovieClip&lt;br /&gt;  {&lt;br /&gt;     public function spaceGame()&lt;br /&gt;     {&lt;br /&gt;        //create new ship&lt;br /&gt;        var myShip:Ship = new Ship();&lt;br /&gt;        &lt;span style="font-weight: bold;"&gt;//add event listener to stage which calls function within myShip&lt;br /&gt;        stage.addEventListener(KeyboardEvent.KEY_DOWN, myShip.keyDownHandler);&lt;/span&gt;&lt;br /&gt;        //add ship to display list&lt;br /&gt;        addChild(myShip);&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;And now it works! Whenever the eventListener detects a key-press on the stage, it calls the keydownHandler function in myShip. So far, all this does is trace an asinine message.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Z1AHsdfvZf0/SWC0gK1v5cI/AAAAAAAAAA0/say9ESueC7g/s1600-h/03asinine.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 232px;" src="http://2.bp.blogspot.com/_Z1AHsdfvZf0/SWC0gK1v5cI/AAAAAAAAAA0/say9ESueC7g/s400/03asinine.gif" alt="" id="BLOGGER_PHOTO_ID_5287424427291567554" border="1" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;yes, dear, very good&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;But this is really awkward, as it would oblige me to write three lines every time I create a ship:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt; &lt;br /&gt;  allShips[i]  = new Ship();&lt;br /&gt;  addChild(allShips[i]);&lt;br /&gt;  allShips[i].addEventListeners();&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Yuk. This is pretty much the way I did things Before the Tragedy (BT) but it's crap. The whole point of OOP is that I don't have to think about this nonsense...&lt;br /&gt;&lt;br /&gt;Anyway, this is not how I want to do things – the ship isn't going to be the entity which detects key-strokes from the user. This is why:&lt;br /&gt;&lt;br /&gt;We need to think about things in an object orientated way. The ship is just an automaton, a machine with certain attributes and behaviours, but it doesn't think for itself. Just like their real-life counterparts, these ships need a pilot to handle them. So that's what we're going to do: create a pilot class.&lt;br /&gt;&lt;br /&gt;Why is the Pilot class separate from the Ship Class? In this game there will obviously be the human player controlling a ship, but several other ships controlled by the computer. The point is that the ship doesn't care who is controlling it. Whether it's an AI pilot or a human telling it to turn left, the effect is the same. So by separating the entity giving the commands and the entity responding to the commands, we're keeping things simple.&lt;br /&gt;&lt;br /&gt;Similarly, the Pilot class will never directly modify the ship class. It will only give commands, which the ship can ignore or process.&lt;br /&gt;&lt;br /&gt;There are going to be several different pilot types. Obviously there is a person playing the game, but also the AI Pilots, of which there will be several types depending on what ship they're controlling (FighterAIPilot, CarrierAIPilot, ArtilleryAIPilot etc.). There might also be a PuppetMasterPilot used for cut scenes, or background ships…&lt;br /&gt;&lt;br /&gt;Each of these can pass commands to the ship they control – turn, thrust, fire, select next enemy and so on – but the way these commands are decided differs for each one. Here's a good situation in which to use&lt;span style="font-weight: bold;"&gt; inheritance&lt;/span&gt;. We'll have one base class Pilot which is the one core of functionality all Pilots share, then several classes that &lt;span style="font-weight: bold;"&gt;extend&lt;/span&gt; this class with their own specific attributes and methods. The end result will always be a simple list of commands to be sent to the ship.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Z1AHsdfvZf0/SWC0gNK__iI/AAAAAAAAAA8/HiH3ogVWhoI/s1600-h/03directories.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 136px;" src="http://2.bp.blogspot.com/_Z1AHsdfvZf0/SWC0gNK__iI/AAAAAAAAAA8/HiH3ogVWhoI/s400/03directories.gif" alt="" id="BLOGGER_PHOTO_ID_5287424427917573666" border="1" /&gt;&lt;/a&gt;&lt;br /&gt;First we need to create the Pilot class. Once again I'm going to start by making it a package, so I've got a new directory called pilots, and inside a new .as document called Pilot.as, and write the following code:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;//PILOT CLASS - sets commands for ship under pilot control&lt;br /&gt;package pilots&lt;br /&gt;{&lt;br /&gt;  import ships.*;&lt;br /&gt;&lt;br /&gt;  public class Pilot&lt;br /&gt;  {&lt;br /&gt;     //pilot can never modify attribute of Ship, only pass commands&lt;br /&gt;     //The available commands:&lt;br /&gt;     protected var _commandRotation:Number = 0.0;&lt;br /&gt;     protected var _commandThrust:Boolean = false;&lt;br /&gt;&lt;br /&gt;     //The ship being controlled&lt;br /&gt;     protected var _ship:Ship;&lt;br /&gt;&lt;br /&gt;     public function &lt;span style="font-weight: bold;"&gt;get&lt;/span&gt; commandRotation():Number&lt;br /&gt;     {&lt;br /&gt;        return _commandRotation;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     public function &lt;span style="font-weight: bold;"&gt;get&lt;/span&gt; commandThrust():Boolean&lt;br /&gt;     {&lt;br /&gt;        return _commandThrust;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     public function &lt;span style="font-weight: bold;"&gt;set&lt;/span&gt; ship(ship:Ship):void&lt;br /&gt;     {&lt;br /&gt;        _ship = ship;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     public function Pilot()&lt;br /&gt;     {&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;So we have a class that doesn't do much at the moment. All we have are two private variables that define commands given by the player: _commandRotate and _commandThrust. They are protected, which means only this class and its children can access them, but I do want the ship to be able to read these commands, so I make "&lt;span style="font-weight: bold;"&gt;getter&lt;/span&gt;" functions. This means that within the ship class I could write:&lt;br /&gt;&lt;br /&gt;Rotation += myPilot.commandRotate;&lt;br /&gt;&lt;br /&gt;And this will work, even though _commandRotate is protected. But because I haven't written a "&lt;span style="font-weight: bold;"&gt;setter&lt;/span&gt;" function, the following line from within the ship class would cause an error:&lt;br /&gt;&lt;br /&gt;myPilot.commandRotate = 5.0;&lt;br /&gt;&lt;br /&gt;I only want Pilot classes to be able to change the command variables. But notice I have written a "setter" for the _ship variable. This will be particularly useful for the HumanPilot and PupperMasterPilot classes because they will jump in and out of ships at will, but certain things need to be done to keep the game from breaking. At the moment the setter doesn't do much, but some extra functionality will be added later.&lt;br /&gt;&lt;br /&gt;If you're confused about the whole getter setter thing there're lots of &lt;a href="http://www.flepstudio.org/forum/object-oriented-programming-tutorials/694-tutorial-6-getter-setter.html"&gt;tutorials online&lt;/a&gt;. Unfortunately though, my inadequacies as a programmer come out once again as it turns out that &lt;a href="http://typicalprogrammer.com/?p=23"&gt;getters and setters break the all important encapsulation&lt;/a&gt; which I think one day I might begin to understand. Whatever. Let's make a game. But this is getting on a bit so I'll divide this tutorial into two parts...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://flashgametutorials.blogspot.com/2009/01/tutorial-3-part-2-writing-humanpilot.html"&gt;On to part 2!&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7441051931482313977-4021020395857676971?l=flashgametutorials.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://flashgametutorials.blogspot.com/feeds/4021020395857676971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://flashgametutorials.blogspot.com/2009/01/tutorial-3-getting-user-input-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/4021020395857676971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/4021020395857676971'/><link rel='alternate' type='text/html' href='http://flashgametutorials.blogspot.com/2009/01/tutorial-3-getting-user-input-and.html' title='Tutorial 3: getting user input and making the ship rotate. Creating a pilot class, and having fun with inheritance!'/><author><name>Awoogamuffin</name><uri>http://www.blogger.com/profile/03868669228439003143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Z1AHsdfvZf0/SuMEF5uPYSI/AAAAAAAAADc/RGp1kyDoL9A/S220/dreg.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Z1AHsdfvZf0/SWC0gYo5LYI/AAAAAAAAABE/qc5XwXeHft8/s72-c/03framerate.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7441051931482313977.post-1015773695343427434</id><published>2008-12-30T06:04:00.000-08:00</published><updated>2009-01-10T07:16:10.186-08:00</updated><title type='text'>Tutorial 2: making a ship appear on screen. Packages and classes revisited (yay!)</title><content type='html'>Ok, that first tutorial wasn’t so much a tutorial as lots of me talking. Let’s get something up on the screen.&lt;br /&gt;&lt;br /&gt;First of all, organisation. I want to make a ship, and I know that I’ll be making several different ships, so let’s create a new package. Again, my creativity abounds as I decide to call this package “ships”. So, how does this work?&lt;br /&gt;&lt;br /&gt;Well, in my spaceGame directory I create a new directory called “ships”. Therein I’ll create a new actionScript file called “Ship.as”.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Z1AHsdfvZf0/SVos_cuXTRI/AAAAAAAAAAc/lUT-q1gpZNE/s1600-h/02directories.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 141px;" src="http://1.bp.blogspot.com/_Z1AHsdfvZf0/SVos_cuXTRI/AAAAAAAAAAc/lUT-q1gpZNE/s400/02directories.gif" alt="" id="BLOGGER_PHOTO_ID_5285586581226736914" border="1" /&gt;&lt;/a&gt;&lt;br /&gt;Inside the actionScript file I’ll write the following:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;package ships&lt;br /&gt;{&lt;br /&gt;  import flash.display.Sprite&lt;br /&gt;&lt;br /&gt;  public class Ship extends Sprite&lt;br /&gt;  {&lt;br /&gt;     public function Ship()&lt;br /&gt;     {&lt;br /&gt;        trace("hello world!");&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Notice the capitalisation – it’s important. To keep things consistent, I’ll be starting class names with a capital letter, and instance names with a lower case one (I believe this is the &lt;a href="http://opensource.adobe.com/wiki/display/flexsdk/Coding+Conventions"&gt;convention&lt;/a&gt;). What’s an instance? Read on…&lt;br /&gt;&lt;br /&gt;So now I’ve written “package ships”. When it comes to compiling, Flash will look for a directory called “ships” whenever this class is imported from another file. How do we import from another file? Well, back in our SpaceGame.as file we’ll replace the code with this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;pre&gt;package&lt;br /&gt;{&lt;br /&gt;  import flash.display.MovieClip&lt;br /&gt;  &lt;span style="font-weight: bold;"&gt;import ships.Ship&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  public class SpaceGame extends MovieClip&lt;br /&gt;  {&lt;br /&gt;     public function SpaceGame()&lt;br /&gt;     {&lt;br /&gt;        &lt;span style="font-weight: bold;"&gt;var myShip:Ship = new Ship();&lt;/span&gt;&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So what has changed? Well, as well as importing the MovieClip class, we’re now importing our own new class called Ship, from the package “ships”. Then, within the SpaceGame &lt;a href="http://en.wikipedia.org/wiki/Constructor_%28computer_science%29"&gt;constructor&lt;/a&gt; we’re going to make a new variable.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;var myShip:Ship = new Ship()&lt;/span&gt;: &lt;a href="http://en.wikipedia.org/wiki/Variables#Computer_programming"&gt;variables&lt;/a&gt; can be all sorts of things – hopefully you should know what they are already… things like integers, Numbers, Arrays etc. Well, instances of a class are variables also, and here we’re declaring a new variable, called “myShip” (but it could be called anything: “myShip27”, “i”, “Jennifer”) and it is of type “Ship” (the class we’ve just written).&lt;br /&gt;&lt;br /&gt;The command &lt;span style="font-weight: bold;"&gt;new Ship()&lt;/span&gt; means that we create an &lt;span style="font-weight: bold;"&gt;instance&lt;/span&gt; (a specific individual as opposed to a general definition) of the class Ship, and this will run the &lt;span style="font-weight: bold;"&gt;constructor&lt;/span&gt; of class Ship – which in this case just means tracing “hello world” again. If we run it, hopefully nothing will have changed since the last version.&lt;br /&gt;&lt;br /&gt;Great Awoogamuffin, I hear you say, what was the point of that? Well, I just wanted to show how to organise the code using packages and whatnot. Let’s actually make a ship, yeah?&lt;br /&gt;&lt;br /&gt;The fun bit is next – design a ship. Here’s where flash comes into its own – you create a new symbol (movieClip) in the flash document and do whatever you want with it – you could make it animated or just a simple image. I’m going to keep things simple because in the end I want to have loads of these things flying around.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Z1AHsdfvZf0/SVotyG1nEaI/AAAAAAAAAAs/ujSQpg9O60g/s1600-h/02shipImage.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 209px; height: 400px;" src="http://4.bp.blogspot.com/_Z1AHsdfvZf0/SVotyG1nEaI/AAAAAAAAAAs/ujSQpg9O60g/s400/02shipImage.gif" alt="" id="BLOGGER_PHOTO_ID_5285587451524878754" border="1" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;notice that I've created a folder within the library for all my ship images. I'm &lt;span style="font-style: italic;"&gt;well&lt;/span&gt; organised.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;This is my little blue fighter ship, so I’m going to call it blueLightFighterImage. The “Image” part of the name is because this MovieClip is not the actual ship, just the visual representation of it.&lt;br /&gt;&lt;br /&gt;I won’t go into detail on the drawing and animation aspects of this game – there are plenty of resources online to help you with that – this blog is predominately about programming. But I am going to tell you that in the properties panel for your newly created ship MovieClip, you need to tick the box that says, “Export for ActionScript”. This means that now the ship Image symbol is a class you can use within your code.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Z1AHsdfvZf0/SVotxv_vHrI/AAAAAAAAAAk/p--wyKDpVz4/s1600-h/02properties.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 364px; height: 400px;" src="http://2.bp.blogspot.com/_Z1AHsdfvZf0/SVotxv_vHrI/AAAAAAAAAAk/p--wyKDpVz4/s400/02properties.gif" alt="" id="BLOGGER_PHOTO_ID_5285587445393333938" border="1" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;notice that you can select what the Base Class is... this is useful if you want to create something which doesn't need a timeline (such as a Sprite or Shape - these are easier on the memory). I'm keeping this image as a movieClip because I'll need the timeline for things like animating the ship exploding, or for more complex ships that change their state - like aggressive to defensive or something awesome like that&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;[note - as of &lt;a href="http://flashgametutorials.blogspot.com/2009/01/tutorial-6-writing-preloader-for-as3.html"&gt;tutorial 6&lt;/a&gt; some aspects have changed - the blueLightFighterImage is now a sprite, and we have to uncheck the "export on first frame" option. All is explained in tutorial 6. Things change, I guess]&lt;br /&gt;&lt;br /&gt;Now let’s go back to the Ship class. We’re going to make it more ship-like (as in, it’s functionality will not be limited to the admittedly unimpressive “hello world”). The ship class extends Sprite, which means it has a position, rotation, and can have other objects added to it. Ultimately, our ship will have all sorts of attributes, such as maximum speed, acceleration, turn rate, ammunition etc.&lt;br /&gt;&lt;br /&gt;But first of all we want to attach the image of a ship we made earlier. So now the ship class is going to look like this:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;br /&gt;&lt;pre&gt;package ships&lt;br /&gt;{&lt;br /&gt;  &lt;span style="font-weight: bold;"&gt;import flash.display.*;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  public class Ship extends Sprite&lt;br /&gt;  {&lt;br /&gt;     &lt;span style="font-weight: bold;"&gt;private var _shipImage:MovieClip;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;     public function Ship()&lt;br /&gt;     {&lt;br /&gt;        &lt;span style="font-weight: bold;"&gt;_shipImage = new blueLightFighterImage();&lt;br /&gt;        addChild(_shipImage);&lt;br /&gt;&lt;br /&gt;        x = 275;&lt;br /&gt;        y = 200;&lt;/span&gt;&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;A few small differences here – let’s have a look at what’s going one.&lt;br /&gt;&lt;br /&gt;First of all, I’ve been lazy, and written &lt;span style="font-weight: bold;"&gt;import flash.display.*&lt;/span&gt;. I believe they call the asterisk the wildcard or something (by “they” I mean real programmers), which is to say that it represents everything and anything. In this case it means importing every class in the flash.display package. Strictly speaking you should only import the specific classes you need to avoid confusion involving scary things like namespaces and other things I daren’t read about for fear of getting even more confused on the subject than I already am.&lt;br /&gt;&lt;br /&gt;Luckily, we’re just writing a game, and not an incredibly flexible, re-usable framework (they talk about this in the intimidating wikipedia entry on &lt;a href="http://en.wikipedia.org/wiki/Design_Patterns"&gt;design patterns&lt;/a&gt;). I feel guilty and pathetic, but I’m lazy so nyah!&lt;br /&gt;&lt;br /&gt;Anyway, we now declare a variable before the constructor.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;private var _shipImage:MovieClip:&lt;/span&gt; “private” is an &lt;a href="http://greenethumb.com/article/27/public-private-protected-internal-access-modifiers-in-as3"&gt;access modifier&lt;/a&gt; (this link has a nice metaphor involving beer), and it means that access to this variable is restricted to this particular class. The underscore before the name is a naming convention (as far as I can tell) for all variables that are not public. I’ve read a few confused accounts on the internet explaining why this convention exists, but nothing of the blinding clarity needed for me to understand. If anyone reading this wishes to educate me, please do!&lt;br /&gt;&lt;br /&gt;Anyway, this _shipImage variable is of the type MovieClip. We then call new blueLightFighterImage() which means we're making an &lt;span style="font-weight: bold;"&gt;instance &lt;/span&gt;of the symbol we created earlier within the spaceGame.fla file. Now, for this to actually appear within our Ship class we need to call &lt;span style="font-weight: bold;"&gt;addChild()&lt;/span&gt; which is a function within the flash.display.displayObject class (hence my importing everything out of sheer lethargy). All visible objects in Flash inherit from displayObject (I think). Now our blueLightFighterImage is visible in the Ship class.&lt;br /&gt;&lt;br /&gt;I also set the Ship x and y values (these are &lt;span style="font-weight: bold;"&gt;inherited&lt;/span&gt; from the Sprite class) to 275 and 200 so that the ship appears at the centre of the screen ([0,0] is the top left corner in Flash – I know, that's weird. In flash, y increases as you go down, unlike all those Cartesian maths you did at school. I think Adobe just wants to screw with our heads).&lt;br /&gt;&lt;br /&gt;But if we run the game now, we still don't see the ship! That's because we also need to add the myShip instance we created in SpaceGame.as to the display list. So now in the SpaceGame.as class we should add the following:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); margin: 0px; padding: 15px; overflow: auto; background-color: rgb(220, 220, 240); text-align: left;"&gt;&lt;br /&gt;&lt;pre&gt;package&lt;br /&gt;{&lt;br /&gt;  &lt;span style="font-weight: bold;"&gt;import flash.display.*;&lt;/span&gt;&lt;br /&gt;  import ships.Ship;&lt;br /&gt;&lt;br /&gt;  public class SpaceGame extends MovieClip&lt;br /&gt;  {&lt;br /&gt;     public function SpaceGame()&lt;br /&gt;     {&lt;br /&gt;        var myShip:Ship = new Ship();&lt;br /&gt;        &lt;span style="font-weight: bold;"&gt;addChild(myShip);&lt;/span&gt;&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Notice I've also been lazy and wild-carded the import statement; that's because the displayObject class is needed for the addChild function, so let's just import everything and hope something fits...&lt;br /&gt;&lt;br /&gt;Now run the game, and we should have a spaceGame.swf file that does this:&lt;br /&gt;&lt;br /&gt;&lt;embed pluginspage=" http://www.macromedia.com/go/getflashplayer" src="http://sites.google.com/site/awoogamuffin/flashfiles/02nothing.swf" type="application/x-shockwave-flash" height="400" width="550"&gt;&lt;/embed&gt;&lt;br /&gt;&lt;br /&gt;Yes, that's right. Absolutely nothing. On to tutorial 3!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7441051931482313977-1015773695343427434?l=flashgametutorials.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://flashgametutorials.blogspot.com/feeds/1015773695343427434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://flashgametutorials.blogspot.com/2008/12/tutorial-2-making-ship-appear-on-screen.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/1015773695343427434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/1015773695343427434'/><link rel='alternate' type='text/html' href='http://flashgametutorials.blogspot.com/2008/12/tutorial-2-making-ship-appear-on-screen.html' title='Tutorial 2: making a ship appear on screen. Packages and classes revisited (yay!)'/><author><name>Awoogamuffin</name><uri>http://www.blogger.com/profile/03868669228439003143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Z1AHsdfvZf0/SuMEF5uPYSI/AAAAAAAAADc/RGp1kyDoL9A/S220/dreg.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Z1AHsdfvZf0/SVos_cuXTRI/AAAAAAAAAAc/lUT-q1gpZNE/s72-c/02directories.gif' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7441051931482313977.post-6319432140240971904</id><published>2008-12-29T03:45:00.000-08:00</published><updated>2009-01-02T09:24:09.339-08:00</updated><title type='text'>Tutorial 1: Where do I start?</title><content type='html'>First of all, I highly recommend you discretely kill off a rich relative and leave yourself on the will so as to be able to afford Flash CS3 (or whatever the latest version is once you read this). It’s relatively expensive, but it’s cool, yeah?&lt;br /&gt;&lt;br /&gt;Now a lot of the tutorials online show you how to program a game by inputting AS3 code into the timeline of the main MovieClip. This is an excellent way of programming if you like getting horrifically confused and frantically clicking on different frames to figure out where the hell your code has gone. The big problem with this way of programming is that the bigger the game, the harder it is to expand it, so it’s only really useful for small games.&lt;br /&gt;&lt;br /&gt;No, in my game, no code will appear on the main timeline. There might be the odd bit of code within specific MovieClips, but the idea is that each entity within the game should be more or less self-contained. This way, we can add functionality to the game all we want without making it more difficult to manage. This is the whole point of &lt;a href="http://en.wikipedia.org/wiki/Object-oriented_programming"&gt;Object-Oriented programming&lt;/a&gt;, as far as I can tell. They like to use words like “encapsulation” but I’m going to avoid that type of jargon, mainly because I’m not entirely sure how to use it.&lt;br /&gt;&lt;br /&gt;Where do we put the code?&lt;br /&gt;&lt;br /&gt;The first thing we’re going to do is create a new Flash document. Now I’m making a game set in space, so I’m going to create a new folder called “spaceGame” (I’m creative like that). Then I create a flash document called, you’re never going to believe this, “spaceGame.fla”. Right, just to emphasize my point about not putting code within the timeline, I’m going to delete the one frame they put there for you.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Z1AHsdfvZf0/SVi-b72NBQI/AAAAAAAAAAM/I9AVT0MGrVw/s1600-h/01deleteFrame.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 189px;" src="http://3.bp.blogspot.com/_Z1AHsdfvZf0/SVi-b72NBQI/AAAAAAAAAAM/I9AVT0MGrVw/s320/01deleteFrame.gif" alt="" id="BLOGGER_PHOTO_ID_5285183549850060034" border="1" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So now what? How does the flash document know what code to run? Well, start off by creating a new actionScript file. Once again my creative genius will shine through in my naming abilities. I dub it “SpaceGame.as” and it shall be saved in the same folder as “spaceGame.fla”.&lt;br /&gt;&lt;br /&gt;Now back in the fla document, in the properties panel for the document see that down there at the bottom right? Document class. This is the class the document opens right at the beginning – so write “SpaceGame” in that space.&lt;br /&gt;&lt;br /&gt;As we go on in this exciting adventure, I’m going to talk an awful lot about classes, but for now let’s just write some code, and I’ll get into greater detail later…&lt;br /&gt;&lt;br /&gt;So within the “SpaceGame.as” document, we’re going to write the SpaceGame class. I want you to write the following:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(60, 60, 130); background-color: rgb(220, 220, 240);"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;   &lt;/pre&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;package&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;import flash.display.MovieClip&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public class SpaceGame extends MovieClip&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public function SpaceGame()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;trace("hello World!");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;What does all that mean?&lt;br /&gt;&lt;br /&gt;Sorry if you already know this stuff, but like I said my target audience is people who might know some programming stuff (if statements and whatnot) but not the way that flash AS3 is organised. These few lines are all important, so let’s look at them one by one…&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Package&lt;/span&gt;: Packages are sets of classes that work together. So in this game I will have a “ships” package, which contains all the different types of ship classes. I’ll have a “userInterface” package that contains all the… you get the picture. Packages are just the folders you save the classes in, and seeing as this class is in the main folder, it doesn’t actually belong to a specific package (otherwise it would read “package ships” for example). More on both packages and classes later.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Import flash.display.MovieClip&lt;/span&gt;: aha! Remember packages? We require a specific class (MovieClip - our game is a special kind of flash movie clip), which is found inside the package "display" which is in the package "flash". Obviously these packages come with flash, but we can make our own packages in the future, and we will &lt;span style="font-weight: bold;"&gt;import&lt;/span&gt; classes from these packages in the same way as we did the MovieClip. All clear?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;public:&lt;/span&gt; Now, if you were good and clicked on the wikipedia link for OOP (Object Orientated Programming) you probably got somewhat confused (unless you’re good at all this nonsense). Now the idea with this kind of programming is that we’re dealing with independent, self-contained objects, which then can communicate with each other. Public means that this class can be “contacted” by any other class from any other part of the program. More on this when I feel like it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Class:&lt;/span&gt; aha! Hopefully, while you were reading the above you developed a strong urge to learn what on Earth a class is – it’s impossible for me to talk about packages etc. without talking about classes. So here goes. Take a deep breath.&lt;br /&gt;&lt;br /&gt;Think about how we talk about the animal world – it’s divided into different classes (or kingdoms, branches, I don’t know). If we talk about a class of animals, we’re talking about a group of animals that share common attributes, as well as behaviour patterns.&lt;br /&gt;&lt;br /&gt;The attributes, such as how many legs this class of animal has, or whether or not is has feathers, would be variables in AS3, and its behaviour would be defined by functions (behaviour such as fly(), attackOldPersonInPark(), throwUpOnCarpet() ). They have a nice example involving dogs in the &lt;a href="http://en.wikipedia.org/wiki/Object-oriented_programming"&gt;wikipedia article on OOP&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So we define all these things in a class document, then from the class document we can create instances of the class, which is to say a specific individual, as opposed to a general definition. To clarify this idea further I’m going to use another animal metaphor. A very old animal metaphor. And I’ll stick in some Greek philosophy. It all applies to programming.&lt;br /&gt;&lt;br /&gt;Remember when you studied &lt;a href="http://en.wikipedia.org/wiki/Plato"&gt;Plato&lt;/a&gt; at school? If not, go to wikipedia NOW, because I’d like to think of my readers (if I ever have any) as a cultivated lot. Anyway, he wrote down lots of what Socrates said, including his idea that physical objects and events are mere reflections of a pure ideal. This is often illustrated with horses.&lt;br /&gt;&lt;br /&gt;If you think of horses, there is in your mind the fleeting perception of the perfect horse. The horses we see around us are all linked, but also unique – different colour, size, behaviour and whatnot, but they’re definitely all horses, which is to say reflections of the ideal horse, that exists beyond the physical (metaphysics).&lt;br /&gt;&lt;br /&gt;Now I think this is a misinterpretation of Socrates’ thinking – he wasn’t actually trying to describe reality – he had merely developed Object Orientated Programming 2500 years in advance. In his example, the ideal horse is actually the class Horse, whereas all the physical horses are instances of the class, as in “myHorse:Horse = new Horse(brown, short, fast, bad-tempered)”.&lt;br /&gt;&lt;br /&gt;I hope that cleared all that up.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;SpaceGame extends MovieClip&lt;/span&gt;: so the class is called “SpaceGame”, fine, that’s all good. Then “&lt;span style="font-weight: bold;"&gt;extends&lt;/span&gt;” means that the SpaceGame class has all the functionality of MovieClip, and we’re just going to add some more. So with a MovieClip we can jump between frames, we can add other MovieClips, we can apply transformations to it, and the same is true of SpaceGame. We say that SpaceGame &lt;span style="font-weight: bold;"&gt;inherits&lt;/span&gt; from MovieClip.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Public function SpaceGame()&lt;/span&gt;: so this function is public (as in, it can be accessed from anywhere) and the function has the same name as the class. This means that SpaceGame() is the &lt;a href="http://en.wikipedia.org/wiki/Constructor_%28computer_science%29"&gt;&lt;span style="font-weight: bold;"&gt;constructor&lt;/span&gt; &lt;/a&gt;of the class; it is called automatically whenever a new SpaceGame class is created.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;trace("hello World!")&lt;/span&gt;: the trace function is something we’ll be using from time to time – it will not be part of the final product, but will help us with debugging, or as a quick fix just to see if something has worked. As for “Hello World”, this seems to be a traditional programming opening line, and I like it because it makes me think that the application has just been born and wants to greet the world. Obviously you could replace “hello World” with “go eat your grandmother” but I’m not sure that would be the most auspicious start…&lt;br /&gt;&lt;br /&gt;So now run your flash application (cmd + enter for macs) and hopefully you should have something that looks like this:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Z1AHsdfvZf0/SVjAq-dsaqI/AAAAAAAAAAU/b-dUvqEuOCw/s1600-h/02helloWorld.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 262px;" src="http://2.bp.blogspot.com/_Z1AHsdfvZf0/SVjAq-dsaqI/AAAAAAAAAAU/b-dUvqEuOCw/s400/02helloWorld.gif" alt="" id="BLOGGER_PHOTO_ID_5285186007273859746" border="1" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now in your SpaceGame folder there should be a new document: “spaceGame.swf”. This is the final product- the thing you can send to your friends be email, or upload to your site. If you open it in flash player now you won’t get anything but a white square, but within the flash application you’ll get an output window saying “hello World”.&lt;br /&gt;&lt;br /&gt;It’s alive!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7441051931482313977-6319432140240971904?l=flashgametutorials.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://flashgametutorials.blogspot.com/feeds/6319432140240971904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://flashgametutorials.blogspot.com/2008/12/first-of-all-i-highly-recommend-you.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/6319432140240971904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/6319432140240971904'/><link rel='alternate' type='text/html' href='http://flashgametutorials.blogspot.com/2008/12/first-of-all-i-highly-recommend-you.html' title='Tutorial 1: Where do I start?'/><author><name>Awoogamuffin</name><uri>http://www.blogger.com/profile/03868669228439003143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Z1AHsdfvZf0/SuMEF5uPYSI/AAAAAAAAADc/RGp1kyDoL9A/S220/dreg.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_Z1AHsdfvZf0/SVi-b72NBQI/AAAAAAAAAAM/I9AVT0MGrVw/s72-c/01deleteFrame.gif' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7441051931482313977.post-7421466888242728423</id><published>2008-12-29T03:37:00.000-08:00</published><updated>2008-12-29T03:42:29.140-08:00</updated><title type='text'>Introduction - back up!</title><content type='html'>Computer games are obviously lots of fun – but how often have you wanted to improve on one, or create an entirely new one? Have you tried? It’s bloody difficult…&lt;br /&gt;&lt;br /&gt;This series of tutorials is intended for people with at least an inkling of how to program, but initially I’ll try to explain in great detail what’s going on – this is not so much a programming tutorial as an explanation of how to think about structuring a complex game in flash (or any object orientated language). There’ll be lots of code on display, though, which hopefully should help you discover the syntax of ActionScript 3 as well...&lt;br /&gt;&lt;br /&gt;The internet is rife with information on AS3, so if ever you find yourself confused by something I’m doing, don’t panic – there’s the documentation within Flash, and a huge resource of information at your finger tips. Also, feel free to leave comments if you want something explained in greater detail.&lt;br /&gt;&lt;br /&gt;“So why are you making these tutorials?” I hear you ask. Well, I’ve been thinking of sharing the fruits of my slow and painful journey of discovery for a while now, and recent events have forced my hand…&lt;br /&gt;&lt;br /&gt;For a while I’ve been trying to make a sort of 2D space shooter game, but with a relatively flexible engine and therefore several different game-play variations. So with this as my template, I set out a year ago to figure out the complexities of flash. Bit by bit, my knowledge grew, and so did the game, until recently I found it excitingly close to completion. Then the tragedy occurred.&lt;br /&gt;&lt;br /&gt;Firstly, here’s some context, so as to allow you to fully appreciate the extent of my idiocy. I have in my possession three 1 GB USB sticks. I have an external hard drive. Also, the entire game project was only a couple of megabytes big – enough to send myself as an email attachment without breaking a sweat. Have you guessed the tragedy yet?&lt;br /&gt;&lt;br /&gt;Fuelled by sheer spite, my hard disk died on me. I think it just wanted to teach me a lesson for my procrastination. You understand, I always planned to back up my game, but my laziness always got the better of me. Some things are best learned the hard way. And this was &lt;span style="font-style: italic;"&gt;hard&lt;/span&gt;!&lt;br /&gt;&lt;br /&gt;So please, please, please back up. Programming is a lot of work, and the work you produce is so small it really isn’t difficult to back up your work. Then again, if you’re the sort of person who only really learns things the hard way, I definitely recommend you work on something for a year then pour water onto your hard drive or something. That’ll learn ya.&lt;br /&gt;&lt;br /&gt;Also, I’m not a professional programmer – I’m a keen amateur, who received some training at university (I studied 3D animation) but I’m far from an expert. I will surely make mistakes, and I can only hope some people reading this can point them out, or inform me of a better way of doing things. These tutorials won’t teach you the perfect way of programming a game, but they should certainly help you get started on making a decent game – my target audience is me a year ago, basically.&lt;br /&gt;&lt;br /&gt;Anyway, time to move on to actually writing a game. Time for tutorial number 1.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7441051931482313977-7421466888242728423?l=flashgametutorials.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://flashgametutorials.blogspot.com/feeds/7421466888242728423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://flashgametutorials.blogspot.com/2008/12/introduction-back-up.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/7421466888242728423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7441051931482313977/posts/default/7421466888242728423'/><link rel='alternate' type='text/html' href='http://flashgametutorials.blogspot.com/2008/12/introduction-back-up.html' title='Introduction - back up!'/><author><name>Awoogamuffin</name><uri>http://www.blogger.com/profile/03868669228439003143</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Z1AHsdfvZf0/SuMEF5uPYSI/AAAAAAAAADc/RGp1kyDoL9A/S220/dreg.png'/></author><thr:total>0</thr:total></entry></feed>
