Creating a Asteroids Flash Game Part 3: Creating and rendering the ship

In the last section we setup our main game class, created our main game loop, and created the background we will be rendering all of our game objects on to.

In this section, we’ll make a base class for all our game objects, create our ship, and use the arrow keys to move it around on screen.

Chris Moeller Web Flash Asteroid Game Part 3: Creating the ship

Creating the GameSprite Base Class

The first thing we need to do is create our GameSprite class.
Right click on the folder on your ‘src’ folder on the right, and add a new folder called ‘Entities’. Next right click on that folder, and create a new class called ‘GameSprite’.

This object will include the basic things that all of our game objects will need, including our ship, bullets and asteroids.

package Entities
{
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.geom.Point;

    public class GameSprite
    {

   	 public var x:Number;
   	 public var y:Number;
   	 public var width:int;
   	 public var height:int;
   	 public var angle:Number;

   	 protected var image:BitmapData;
   	 protected var image_sprite:Sprite;

   	 public function GameSprite(x:int, y:int, width:int, height:int, angle:int=0)
   	 {
   		 this.x = x;
   		 this.y = y;
   		 this.width = width;
   		 this.height = height;
   		 this.angle = angle;
   	 }
   	 public function Render():void
   	 {
   	 }
   	 public function Update():void
   	 {
   	 }
    }
}

All of our objects will need an x, y, width and height to be rendered on screen. Additionally, all of our objects should have the ability to be rotated by some angle.

Note:

Make sure you don’t set up the x and y and ‘int’ type. It can cause some major rounding errors later for calculations that use the position.

For rendering, each object will need at least a bitmapdata, and if being drawn using vectors, we will need to first use a sprite, since it has built in functions for drawing, which the bitmapdata class lacks.

Next in the constructor function, we set it up so that it needs to be passed its x and y position, as well as width and height, and have it assume the angle is ‘0’ if none is passed in.

Inside, we assign all of the passed in variables to the objects variables, so the object now has these properties set.

Finally, we setup a prototype ‘Render’ and ‘Update’ function, since all of our objects will need the ability to be rendered and updated, and this gives us the flexibility of being able to do them independently of each other.

Creating the Ship Class

Now that we have a base GameSprite class, we will create the ship class. Right click on the “Entities’ folder again, and click ‘Add->New Class’. We will name this one ‘Ship.as’, but this time we will click on the ‘browse’ button next to ‘Base Class’. Start typing in “GameSprite”, and select the one found below and click ok. Next, click the checkbox for ‘generate constructor matching base class’ and click ‘ok’ to create your new ship class.

Doing this will allow the ship class to inherit all the functions and variables from the base class ‘GameSprite’.

Since we will be drawing this ship instead of using a pre-created image right now, we will need to initialize the sprite, and override the ‘GameSprite’s Render function to draw the ship.

package Entities
{
	import flash.display.Sprite;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	public class Ship extends GameSprite
	{
		public function Ship(x:int, y:int, width:int, height:int)
		{
			super(x, y, width, height);
			image_sprite = new Sprite();
			image_sprite.graphics.lineStyle(.1, 0xFFFFFF);

			//create the ship drawing
			image_sprite.graphics.moveTo(0, height);
			image_sprite.graphics.lineTo(width / 2, 0);
			image_sprite.graphics.lineTo(width, height);

			//draw the line across
			image_sprite.graphics.moveTo((7*height/8 -height)/(-height/(width/2)), 7*height/8 );
			image_sprite.graphics.lineTo((7*height/8 -height)/(height/(width/2))+width, 7*height/8);
		}
		override public function Render():void
		{
			var matrix:Matrix = new Matrix();
			matrix.translate(x, y);

			Game.Renderer.draw(image_sprite, matrix);
		}
	}
}

In the ships constructor, we first call the ‘super’ constructor, which calls the GameSprite’s constructor.
Next we initialize the image_sprite, and setup the linestyle for drawing the ship.

We then need to override the gameSprite’s  ‘Render’ function to draw the ship.

The first thing is to move the starting point of our line drawing to the top-center of our sprite (the top of a triangle), draw to the bottom right, draw to the bottom left, and finally draw back to the top-center to complete our triangle/ship.

Creating the Ship in the Game

Now that we have the ship class created, we need to actually create our ship from our game object.

package chrismweb.ex1.vector_based.Game
{
    import Entities.Ship;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.KeyboardEvent;
    import flash.geom.Rectangle;
    import flash.utils.getTimer;

    public class Game
    {
   	 public var bitmap:Bitmap;
   	 public static var Renderer:BitmapData;
    	 private var ship:Ship;

    	public function Game(stageWidth:int, stageHeight:int)
   	 {
   		 trace("Game created");
   		 Renderer = new BitmapData(stageWidth, stageHeight, false, 0x000000);
   		 bitmap = new Bitmap(Renderer);

//ship positioned at center of the screen
   		 ship = new Ship(Renderer.width/2-5, Renderer.height/2-10, 10, 20);
   	 }
    	public function Render():void
   	 {
   		 Renderer.lock();
   		 Renderer.fillRect(new Rectangle(0, 0, Renderer.width, Renderer.height), 0x000000);

   		 ship.Render();

   		 Renderer.unlock();
   	 }
    	public function Update():void
   	 {
    	}
    }
}

We first create the ship as a variable in our game class, initialize it in our constructor at x= x center of screen minus half the ship width, y=y center of screen minus half the height, and a width of 10, height of 20.

Now that the ship is created, all we have to do is render it by adding a few things to our game’s render function.

We first lock the bitmapdata surface, since it is supposed to increase speed, and limit access to it, next we fill it with black to remove anything previously drawn every frame, we call the ship’s render function to draw the ship on our freshly black canvas, and finally unlock the surface again at the end of the function.

If you compile and run the game now (ctrl+enter) you’ll see your space ship rendered in space!

Tutorial Demo

In the next section we’ll add keyboard controls so that you can move around your ship on screen.

Download the source Code and please leave me any comments or feedback you have.

Other Articles in this Series

Bookmark the permalink.

19 Comments

  1. I am having trouble with the GameSprite base class. FD keeps complaining that the file name does not match. I’ve changed the name to a few logical things, and it isn’t satisfied. Because of this, I get an error in my Ship class at lines 8 and 25. I read your other tutorial and this is by far the most helpful info I’ve been able to come across. Please investigate the issue. Thanks!

  2. Wow I cant tell you how informative this tutorial has been. It seems like Ive looked far and wide for someone to explain it the way you did. Thank you so much! Looking forward to more!

  3. Hi chris,
    I was wondering where you put the code snipplet in this section

  4. Why did you remove the angle:int arguments in the ship class? Just wondering.

    • Good question – I think I setup the base class so that I could set the angle when creating an object (which might add more variability to how the asteroids are created).

      But the ship is always setup with angle = 0, so I just simplified the constructor (although it probably would have made more sense to leave it in, since now it doesn’t have a default constructor matching its base class).

  5. Where do you put the last strip of code? This is my 1st tutorial so complete newbie to this – It looks like the 2 last codes go under ship.as but when that happens it does not show a space ship. All other logical attempts at putting the code somewhere haven’t worked to make a spaceship either for me.

    • Hi Nick- each Class is put into it’s own .AS file with the same name as the class.

      So the last one is just modifying Game.as to add the code to create the ship.

      You can also download the code zip file to see how it ends up for this section of the tutorial.
      Hope that helps!

  6. Hi, this tutorial is excellent and clear. One thing I was curious about is how you calculated the third line for the ship (the one going across). The x value expressions simplify to 1/16 of the width and 15/16 of the width. Just wondering how you came to the longer expression. Thanks again for the great tutorial.

    • That is a good question, and looking back at it, it’s actually pretty confusing, and took me a while to remember 😉

      I wanted the line to be almost at the bottom, but not quite, and the closest spot to that was about 7/8th of the height.

      From there, you have the y value you want, so you need to plug it in the equation for a line for each side of the ship (y=mx+b), and solve for x (m being slope, being y intercept- http://en.wikipedia.org/wiki/Linear_equation).

      So for the left side:
      y=mx+b
      7/8*h= m*x+b
      You need the slope (m) first, and since we have two points, it’s “rise over run”, or the diff of the 2 y-values over 2 x values:
      (y1-y2)/(x1-x2) = (10-0)/(0-2.5)= -4.
      (it is only 2.5 instead of 5, because the left side of the ship only goes to 1/2 the total width)
      The y intercept/b is easy, because it is when x=0 (intersects y axis): 10.

      so now we can solve for x:
      (7/8*h-b)/m=x
      (7/8*10-10)/-4= x
      =-.3125

      Now we can solve for the other line on the right side, which should have the same slope, but negative, but we also want to have it add the width of the ship to it.

      Hope that helps! I remember testing it at the time with .5*height for the starting y value, to make sure my equations worked right 😉

  7. dude! thanks for this wonderful tutorial i have just one problem. i follow all your instructions, i even copy word for word the code. i even downloaded your code (only this part 3) but whenever i run it, it only shows a black screen. unlike your code which i downloaded it shows the ship. can you tell me what might be the problem? there’s no error but it doesn’t show the ship unlike yours. i hope you can help me. thanks

    • You could send me what you have and I can look at it, but it would be best to first try to “debug” the code some.

      Make sure you are creating the ship, in the render portion make sure you are calling the ship’s “ship.Render()” function. In the “ship.Render()” function add ‘trace(“Rendering ship”);’ and make sure that is outputting when you run it. Then, try seeing if you can draw a line or something directly on the Renderer object after it is filled with the black rectangle.

      • i don’t think thats the problem because i even copy your code that i downloaded word for word still it only shows black screen. but whenever i use your file (the one i downloaded) it runs perfectly. btw, how do i send my file to you? i can’t find your yahoo mail or gmail. and thanks for the fast reply.

        • Send it to chris at chrismweb dot com – maybe something in the project properties are different? Or set differently by default with newer versions of FlashDevelop?

          I can check it out though and see though-

  8. I don’t get how to initialize the sprite and override Gamesprites render function. Please help with telling what to click on. Thank You.

  9. Great tutorials – this series was my sensei when I first began dabbling in AS3. I can’t thank you enough.

    However, now that I’ve gone a bit beyond the content here, I have a related question: Wouldn’t establishing the GameSprite class (and all objects on screen) as purely sprite sheets and/or bitmapDatas, and then having the Game’s Renderer bitmapData call .copyPixels() on those bitmapDatas, have been significantly more efficient than using actual sprites and bitmaps to represent the various game objects? Especially when it comes to later embedding image assets (.png) in place of vector images?

    I understand that this game in this tutorial has few visual components, so performance overheads are of no real difference. But branching beyond, it becomes an issue.

    But thanks again!

    • Yes, that would be more efficient!
      I’m not sure how much more, I (or you 😉 ) would have to setup a benchmark to test it out.

      I’ve been using more OpenGL ES lately, and the old version couldn’t use non power of 2 textures (so yet another reason to pack it into a sprite sheet), but the newer (2.0) can, but I have heard you still will lose quite a bit of performance.

      Ideally, you’d probably want to still have your images saved as individuals, but whenever you modify them/ add new ones, you’d want to re-pack them into your texture atlas, and only load that in at runtime.

      But yeah, one of the strengths of using flash was pretty quick performance, even with using vector objects to draw everything on the fly, for simpler stuff, and testing, it’s much faster to work with.

Leave a Reply

Your email address will not be published. Required fields are marked *