How to make a 2d Platform Game – part 1

giantStar
Submit to StumbleUpon

Hello, and welcome back to my blog!

Its been a long time coming, but finally I’ve managed to get some time to work on the blog again…

In this first instalment of a series blog articles, I’m going to be explaining step by step how you make this 2d platform game:


Click the game to give it focus… Apologies for the programmer art, and my level design (not my best qualities!)

The language is actionscript 3.0, but the techniques are applicable to all languages.

Inspiration

As a kid I always used to love playing The Newzealand Story and Rainbow Islands by Taito

The NewZealand Story

Rainbow Islands

And of late my love of platformers was rekindled by this awesome work in progress Generic:

So I decided to write about the process of making one – you’ll see influences from all three of these games in my bad graphics!

The background

Ok, one of the first things you will notice is that the game has a couple of layers of parallax in the background; this was relatively easy to achieve with the aid of a couple of tiles.

Background Tile

Mid-ground tile

Notice how the tiles are different sizes? This is important to stop the seams lining up too much as the camera moves about.

The most difficult thing was actually getting these designs to tile seamlessly when stacked next to each other, but that’s because I’m a programmer not an artist! Anyway, I’ll cover how I did that later when I talk about creating the tile set for the game.

Tiles follow camera

In order to get a seemingly infinite tiling background, the tiles are laid down by the renderer as they are needed, Wallace and Gromit style, as the camera moves around the level.

Gromit lays down the track just in time

In the picture above Gromit is laying down the track as the train moves him along; if you replace Gromit with the renderer and the train with the camera you should be able to see what I mean. The difference is that at the other end of the train, we would need another Gromit facing in the opposite direction picking up the track as the train passes over it, and then handing it back to the Gromit at the front!

I found that I needed a cache of N=Screen Width/Tile width + 2 in the X and N=Screen Height/Tile height + 2 in Y number of tiles in order to keep the screen full constantly.

Figure 1

Figure 1 shows the screen in blue moving around a grid of tiles; green tiles are added at the front of the motion and red tiles are removed (or rather recycled) at the rear. Here is the code used:

package Code.Graphics
{
	import flash.display.*;
	import Code.Geometry.*;
	import Code.Maths.*;
	import Code.Constants;
	import Code.Platformer;
 
	public class TileRenderer
	{
		private var m_tiles:Vector.<MovieClip>;
		private var m_numX:int;
		private var m_numY:int;
		private var m_tileWidth:int;
		private var m_tileHeight:int;
		private var m_camera:Camera;
		private var m_zDepth:Number;
 
		private var m_tempAabb:AABB;
 
		/// <summary>
		/// Constructor
		/// </summary>	
		public function TileRenderer( tileType:Class, width:int, height:int, camera:Camera, stage:Platformer, zDepth:Number )
		{
			m_tileWidth = width;
			m_tileHeight = height;
			m_camera = camera;
			m_zDepth = zDepth;
 
			m_tempAabb = new AABB( );
 
			m_numX = Constants.kScreenDimensions.m_x/width+2;
			m_numY = Constants.kScreenDimensions.m_y/height+2;
 
			m_tiles = new Vector.<MovieClip>( m_numX*m_numY );
 
			// run though and create all the tiles we need, this fuction takes
			// a closeure which actually does the work
			PositionLogic( function( index:int, xCoord:int, yCoord:int ):void
			{
				m_tiles[index] = new tileType( );
				m_tiles[index].x = xCoord;
				m_tiles[index].y = yCoord;
				m_tiles[index].cacheAsBitmap = true;
 
				// add the tile and send it to the back
				stage.addChild( m_tiles[index] );
				stage.setChildIndex( m_tiles[index], 0 );
			});
		}
 
		/// <summary>
		/// This function runs through and computes the position of each tile - it takes a closeure 
		/// so you can insert your own inner logic to run at each location
		/// </summary>
		private function PositionLogic( action:Function ):void
		{
			m_camera.GetWorldSpaceOnScreenAABB( m_tempAabb );
 
			var screenTopLeft:Vector2 = m_tempAabb.m_TopLeft;
 
			// stop the background from crawling around due to pixel trucation
			screenTopLeft.RoundTo( );
 
			// calculate the top left of the screen, scaled for z depth
			var scaledTopLeft:Vector2 = screenTopLeft.MulScalar( 1/m_zDepth );
			var tileX:int = Math.floor(scaledTopLeft.m_x / m_tileWidth);
			var tileY:int = Math.floor(scaledTopLeft.m_y / m_tileHeight);
 
			// this offset corrects for translation caused by the divide by z
			var offset:Vector2 = scaledTopLeft.Sub( screenTopLeft );
 
			// get the starting tile coords
			var startX:int = tileX*m_tileWidth - offset.m_x;
			var startY:int = tileY*m_tileHeight - offset.m_y;
			var xCoord:int = startX;
			var yCoord:int = startY;
 
			// run though and call the closure for each tile position
			for ( var j:int = 0; j<m_numY; j++ )
			{
				xCoord = startX;
				for ( var i:int = 0; i<m_numX; i++ )
				{
					var index:int = j*m_numX+i;
 
					action(index, xCoord, yCoord);
 
					xCoord += m_tileWidth;
				}
				yCoord += m_tileHeight;
			}
		}
 
		/// <summary>
		/// Update all the tiles to the new coordinates based on the camera's new position
		/// </summary>	
		public function Update( ):void
		{
			PositionLogic( function( index:int, xCoord:int, yCoord:int ):void
			{
				m_tiles[index].x = xCoord;
				m_tiles[index].y = yCoord;
			});
		}
	}
}

A couple of important caveats with this technique:

In order to stop the tiles crawling around the screen very slightly due to coordinate trucation it was important to make sure the reference point for the top left of the screen was correctly rounded to an integer pixel boundary:

// stop the background from crawling around due to pixel trucation
screenTopLeft.RoundTo( );

My function RoundTo() just rounds to the nearest integer.

Also, the parallax was achieved simply by dividing by the z value of the tile, and then correcting the position of the tiles so they started in the correct place on screen:

var scaledTopLeft:Vector2 = screenTopLeft.MulScalar( 1/m_zDepth );
var tileX:int = Math.floor(scaledTopLeft.m_x / m_tileWidth);
var tileY:int = Math.floor(scaledTopLeft.m_y / m_tileHeight);
var offset:Vector2 = scaledTopLeft.Sub( screenTopLeft );

So what’s going on in the above code? What we’re actually doing is taking the world-space position of the top left of the screen, dividing by the resolution of the tile to get the number of tiles required in each axis and then ‘integerising’ the result. Going back to the Gromit analogy, this stops Grommit from putting one piece of train track over the top of the last, or in front of it – he is forced to place them exactly one after the other, which means they tile without visual gaps. The last part is correcting for the offset which happens when we divide by the z depth of the tile layer – this forces the tiles to start at the top left of the screen.

Figure 2

Figure 2 shows a grab of the game where you can see how the tiles are being placed outside the area normally visible to the camera.

The Tiles

Central to any old-school platform game are the tiles which make up the static part of the world. All the tiles in the game are a fixed size; 64×64 pixels, but you can obviously choose whatever tile size is most appropriate.

Tiles are multi-purpose in that they not only provide the building blocks from which every level is constructed, but that they also make up the collision geometry which the player interacts with as they play the level. They are also used to place down enemies and other special non-visible markers which affect certain AI behaviours.

Figure 3

Figure 3 shows the complete tile-set from the game.

Each of the tiles above is assigned a unique integer which represents it, in this case starting from 0 and increasing left to right, top to bottom. The set of all of these integers for a particular level is called the Map. Maps must always be rectangular.

They are represented in code like this:

// map for the level
private var m_map:Vector.<uint> = Vector.<uint>
( 
	[
		04,04,04,04,04,04,04,04,04,04,04,04,04,04,04,04,04,04,
		04,52,19,51,00,00,00,52,19,51,00,52,19,51,00,19,51,04,
		04,17,15,18,00,00,00,17,15,18,35,17,15,49,51,15,18,04,
		04,17,15,49,51,15,00,50,15,18,34,17,15,15,49,15,18,04,
		04,00,48,15,49,15,50,15,47,29,34,17,15,48,15,15,18,04,
		04,00,00,48,15,15,15,47,29,00,34,17,15,00,48,15,18,04,
		04,00,00,00,16,16,16,29,00,00,00,00,16,00,31,16,29,04,
		04,00,42,42,42,42,42,42,42,42,42,42,42,42,42,42,00,04,
		04,00,13,00,00,00,00,00,00,00,00,00,00,00,00,00,00,04,
		04,02,02,02,02,02,02,02,02,02,02,02,02,02,02,02,02,04
	]
);

There is a big enum which allows me to identify which integer corresponds to which tile:

public class eTileTypes
{
	// foreground
	static public const kEmpty:uint = 0;
	static public const kEarthGrassLeft:uint = 1;
	static public const kEarthGrass:uint = 2;
	static public const kEarthGrassRight:uint = 3;
	static public const kEarthMid:uint = 4;
	static public const kEarthTop:uint = 5;
	static public const kEarthRight:uint = 6;
	static public const kEarthLeft:uint = 7;
	static public const kEarthBottom:uint = 8;
        ...
}

At level construction time, I run through the Map picking out each integer and constructing the relevant tile which represents it. The position of each tile in the world relates exactly to its position in the Map.

Tile coordinate system

The total extent of the world is defined as 64 x Nx, 64 x Ny, where Nx and Ny are the number of tiles in X and Y axis in the Map. I’ve also added an offset to locate 0,0 in pixel coordinates to the middle of the Map, in tile coordinates.

Tile coordinates are simply the tile indices into the map, and world coordinates are in pixels (in this case, since I’m using flash and that’s most convenient). Its quite common to want to be able to convert from tile coordinates into world coordinates and vice versa, I do so like this:

/// <summary>
/// calculate the position of a tile: 0,0 maps to Constants.kWorldHalfExtents
/// </summary>
static public function TileCoordsToWorldX( i:int ):Number
{
	return i*Constants.kTileSize - Constants.kWorldHalfExtents.m_x;
}
 
/// <summary>
/// go from world coordinates to tile coordinates
/// </summary>
static public function WorldCoordsToTileX( worldX:Number ):int
{
	return ( worldX+Constants.kWorldHalfExtents.m_x )/Constants.kTileSize;
}

There are corresponding versions for the other axis.

Tile psychology

How you actually design your tiles can have a massive effect on the number of them required to represent your game levels. Getting the tiles to seamlessly repeat is a quite irksome process if your not familiar with it.

Cheese

Consider this cheese tile for example (which was actually designed to look like stone, but ended up like cheese due to my fantastic design skill). Looks nice enough by itself, but when you try tiling it a few times, obvious empty spaces emerge:

Tiling cheese

This is due to the spaces in the original design which were too small to fit a decent sized hole into. The solution is to design holes which are cut away on one side and continue on the other, like this:

Side bits which tile

When combined with the original image we get this:

The final cheese

Which tiles much more pleasingly:

Final cheese tiling

But there is one important side effect which comes when designing the end pieces for each side of the tile – end pieces are tiles which represent the end of a piece of cheese, or earth and are there to make the design look less square and rigid.

Cheese plus 4 end pieces

As you can see the end pieces help break up the squareness of the tile, but there is a problem. Due to the choice I made to tile the holes in the corners of the cheese, it means I not only need end pieces but also corner pieces to fill in the holes you can see above in each corner!

This is not only a lot more work when designing the tiles, its also more work when it comes to mapping them, because you need to map many more actual tiles to tidy up the design.

Mapping

In order to actually map down the tiles for each level you don’t want to have to manually enter all the integers for each tile type, so I used Mappy instead, which is freely available and even has a script to output an AS3 array of data.

A level in Mappy looks like this:

A level in mappy

You can see a selection of the tiles on the right and how they look once you’ve mapped them on the left.

Layers

If you look carefully at the game, you’ll notice that there isn’t just one single layer of tiles for each level. There are actually three!

  • The main foreground tiles, which consist of things the player collides with
  • The mid-ground tiles which represent characters and special controls
  • The background tiles, which are purely visual

Background tiles only

I purposefully made all the background tiles much darker than the foreground so they don’t look confusing to the player.

Mid-ground tiles only

The arrow markers you can see either side of the ladybirds actually control their motion – I’ll talk more about this in a coming article.

Foreground tiles only

The foreground also acts as the collision layer – everything you see in this layer is collidable.

All layers together

Putting all there together, we get the above.

The reason to have three layers is that is gives you much greater flexibility when creating the levels; if you just used one, you wouldn’t be able to map the player on a ladder, for example, because there would be only one tile slot in which to map both player and ladder.

It also adds a predefined depth sorting order – background tiles are always behind everything else, mid-ground tiles come after (although, most are not actually visible), and then the foreground tiles are top-most of all.

Having multiple layers doesn’t add much complexity to the system and it gives a lot of flexibility.

Camera

The camera system I used here is much the same as the one I’ve described previously in this article, so I won’t repeat myself.

I will just point out one improvement I made since last time: because we are using tiles, its of the utmost importance that there not be any visual cracking between the tiles as the player moves around the level. Such cracking would destroy the illusion of a continuous world. In order to prevent this, its very important that the camera only ever be positioned on whole pixel boundaries.

In order to achieve this I’ve added the following bit of code to the camera system:

// this is essential to stop cracks appearing between tiles as we scroll around - because cacheToBitmap means
// sprites can only be positioned on whole pixel boundaries, sub-pixel camera movements cause gaps to appear.
m_worldToScreen.tx = Math.floor( m_worldToScreen.tx+0.5 );
m_worldToScreen.ty = Math.floor( m_worldToScreen.ty+0.5 );

m_worldToScreen is the matrix which ultimately gets attached to the main Sprite for the game, causing the world to be translated around as the player moves, giving the illusion that the player is moving around the world.

End of part 1

That’s it for this instalment! Next time I’m going to starting talking about the collision detection of the player against the world, and also how the AI works.

As ever, if you want, you can buy the source-code for the entire game (or try a version for free), including all the assets and levels you see above. It will require Adobe Flash CS4+, the Adobe Flex Compiler 4.0+ and either Amethyst, or Flash Develop to get it to build. And you’ll want Mappy or some alternative in order to create your own levels!

Following on from feedback from the Angry Birds article, I’ve included a Flash Develop project as well as an Amethyst project inside the .zip file, to help you get started more quickly, no matter which development environment you have.

You are free to use it for whatever purposes you see fit, even for commercial games or in multiple projects, the only thing I ask is that you don’t spread/redistribute the source-code around. Please note that you will need some programming and design skills in order to make the best use of this!

Go to the source-code option page to choose the version you’d like – from completely free to the full version!

Subscribers can access the source here

Until next time, Have fun!

Cheers, Paul.

Continue reading in part 2

Submit to StumbleUpon

About Paul Firth

A games industry veteran of ten years, seven of which spent at Sony Computer Entertainment Europe, he has had key technical roles on triple-A titles like the Bafta Award Winning Little Big Planet (PSP), 24: The Game (PS2), special effects work on Heavenly Sword (PS3), some in-show graphics on the BBC’s version of Robot Wars, the TV show, as well as a few more obscure projects.   Now joint CEO of Wildbunny, he is able to give himself hiccups simply by coughing.   1NobNQ88UoYePFi5QbibuRJP3TtLhh65Jp
This entry was posted in AS3, Parallax and Tiles, Platform game, Technical and tagged , , , , . Bookmark the permalink.

72 Responses to How to make a 2d Platform Game – part 1

  1. Pingback: How to make a 2d platform game – part 2 collision detection | Paul's blog@Wildbunny

  2. DatapawWolf says:

    I have been looking for a nice ActionScript Plaformer tutorial for a while now. Actually followed a link to here from a C#-based MMO engine. Heh.
    I’ll be trying this out hopefully the next time I have an hour or two to spare. Thank!

  3. Pingback: How to make games | Paul's blog@Wildbunny

  4. Diego Rodrigues says:

    You gave to me a reason to put my head on a new personal project. Thank you very much for that :D

  5. nikhi k says:

    I have purchased platform game recently and I am new to flash. As said in tutorials i installed Adobe flash professional cs5.5 ,flash develop and adobe flex compiler 4.1.
    But project is not building,it says HudLifeFla method not found.
    Please help me to run this project.

    • Paul Firth says:

      Hi there,

      Which program are you attempting to build the project from?

      Are you able to build a simple ‘hello world’ test program, to confirm your set-up is functioning correctly.

      Cheers, Paul.

      • nikhi k says:

        yes hello world program is functioning properly. I have purchased your 2D platform game of 19.99$. I was attempting to build project “Platformer” and it is giving error as HudLifeFla method not found,whereas i checked HudLifeFla class is present in assets.swc but not in platformer.swf when i build the project.
        Then i made changes in class Hud.as by replacing HudLifeFla word with PlayerFla and project got builded succesfully but as i started playing game it gives error as follow:

        Error: Assertion failed: AnimationController.PlayLooping(): unable to find label idleAnim
        at global/Code.System::Assert()
        at Code.Graphics::AnimationController/PlayLooping()
        at Code.Graphics::AnimationController/PlayOnce()
        at Code.Characters::Player/WalkOrStop()
        at Code.Characters::Player/KeyboardControl()
        at Code.Characters::Player/Update()
        at Code::Platformer/Update()
        at Code.System::GameLoop/UpdateInternal()

        • Paul Firth says:

          Ok,I’m just out in town right now with my parents; I will look into this properly asap but might not be until Sunday evening hope that’s ok? :)

          • nikhi k says:

            ok … :)

          • Paul Firth says:

            Hi there,

            Ok, found the problem – the assets.swc in the root of the project was slightly out of date compared to the one inside the assets directory.

            To fix the problem, simply copy the /assets/assets.swc over the one in the root – or you can re-export the .fla over the top of the file in the root :)

            Hope that helps!

            Cheers, Paul.

  6. nikhil K says:

    Hey it worked….Thanks alot!.
    Your the BEST… :)

  7. john says:

    paul,I have recently purchased your platform game.I m trying on one aspect that is when i collect 3 diamonds i should get one extra life.Can u please tell me how to do it?.
    I was able to add lifeicons on stage when i collect 3 diamonds ,but i could get only 3 attempts to play and not 4.

    • Paul Firth says:

      Ok, couple of new functions and some replacements:

      Gui/Hud.as

      ///
      ///
      ///
      public function Hud( defaultLives:int, stage:Stage )
      {
      m_stage = stage;
      m_lifeIcons = new ReferenceArray( HudLifeFla );

      for ( var i:int = 0; i<defaultLives; i++ )
      {
      AddLife( i );
      }
      }

      ///
      ///
      ///
      private function AddLife( i:int ):void
      {
      var icon:HudLifeFla = new HudLifeFla( );

      icon.x = i*( icon.width+5 )+Constants.kScreenDimensions.m_x/2;
      icon.y = 5;

      m_lifeIcons.Add( icon );

      m_stage.addChild( icon );
      }

      ///
      ///
      ///
      public function ExtraLife( ):void
      {
      AddLife( m_lifeIcons.m_Num );
      }

      Code/Characters/Player.as

      ///
      ///
      ///
      public function ExtraLife( ):void
      {
      m_lives++;
      m_platformer.ExtraLife( );
      }

      Code/Platformer.as

      ///
      ///
      ///
      public function ExtraLife( ):void
      {
      m_hud.ExtraLife( );
      }

      Then, whenever the player should get an extra life call: m_player.ExtraLife()

      Hope that helps!

      • john says:

        hey it worked!!Can u please tell me how to add timer on stage.I have added a timer but it doesn’t stops also i haven’t given it command of start() or stop().It goes on running…till i close flash player

  8. Mitchel says:

    hello buddy,how do i add a movie clip containing a start button in assets.fla.I created a movieclip but it is not publishing in flash develop proj (asset.swc).Which on click should start my platformer game.

  9. nikhil says:

    hello paul. I have this code of button.
    package Code {
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.events.*;
    import flash.utils.getDefinitionByName;
    import Code.Graphics.*;
    public class ButtonInteractivity extends Sprite {

    private var button:Sprite = new Sprite();

    public function ButtonInteractivity() {
    drawButton()
    button.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
    addChild(button);

    }

    private function drawButton():void {
    var textLabel:TextField = new TextField()
    button.graphics.clear();
    button.graphics.beginFill(0xD4D4D4); // grey color
    button.graphics.drawRoundRect(0, 0, 80, 25, 10, 10); // x, y, width, height, ellipseW, ellipseH
    button.graphics.endFill();
    textLabel.text = “Click Me!”;
    textLabel.x = 10;
    textLabel.y = 5;
    textLabel.selectable = false;
    button.addChild(textLabel)
    }

    private function mouseDownHandler(event:MouseEvent):void {
    button.x += 20
    if (button.x > 400) { button.x = 0;
    }
    }
    }
    }
    what i want to do is when i click on button our Platformer.as should run…Can you tell me ?

  10. Pingback: Serious Flash | Pearltrees

  11. karen says:

    hello Paul Firth,

    I Recently purchased your platformer game and i have two questions to ask.Hope you would solve my querries… :)

    1. When i make any changes in assets.fla like, i drawn a line on midground tile.The change is shown in assests.swf but when i run the game no change is shown there!!
    could you please tell.

    2. how do i remove all moveable objects from stage when my player dies completely?

    hope you will tell :)

    • Paul Firth says:

      Hi Karen,

      1) Have you re-built the game in FlashDevelop / Amethyst? FD needs assets.swc exporting to the root of the project.
      2) Add this function to Code/Platformer.as

      /// <summary>
      /// Remove all moveable objects
      /// </summary>
      public function RemoveAllMos():void
      {
      	for ( var i:int = 0; i
      

      And you can call it from Code.Characters.Player.Died() if you want them to disappear before the start of the next level, or from Code.Platformer.DiedCompletely() if you want them to disappear at the start of next level.

      Cheers, Paul.

      • karen says:

        May be this will be stupid question but can you tell me how to do (
        FD needs assets.swc exporting to the root of the project.)?

        • Paul Firth says:

          FD = FlashDevelop
          It requires assets.swc to be exported from Flash CS4 into the same directory as the file platformer.amproj.

          Then you need to rebuild the project in FD and the changes should show up :)

          • karen says:

            Nothing is happening Paul!! I tried it lot of times but no change in graphics.May be you could please tell me in detail.And I have adobe flash cs5.5

  12. karen says:

    hey paul!!.I tried to publish in various formats like swf,windows projector,png,gif.They all got published but only swc file is not publishing .What may be the problem?

    • Paul Firth says:

      Are you getting any errors from CS4? Have you set the class-paths correctly?

      • karen says:

        Yes Paul, Adobe flash cs5.5 is giving compile errors i.e.
        Line 1 5000: The class ‘Code.Characters.Player’ must subclass ‘flash.display.MovieClip’ since it is linked to a library symbol of that type.
        Same for brain,ladybird,ladyspikes and skeleton

        • Paul Firth says:

          Ok, I think that means the class-paths are not set up correctly…

          File->Publish Settings->Flash->Actionscript 3.0: Settings

          Make sure ‘source path’ points to the correct location, which is the directory where you have unzipped project containing – Code, bin, assets etc :)

          Cheers, Paul.

  13. kartik says:

    hello paul, want to know that AI coding of characters is based on which AI category? or is it newly made by you?

  14. Abbas says:

    Greetings Paul,
    i consider my self an intermediate programmer, i’v built a tile-based game similar to the platform you demonstrated. I dealt with the “infrastructure” (collisions and so on…)
    but i’m having hard time choosing and making characters (using paint), what do you recommend to use.
    The really hard part is how to manage several maps if i’m going to use different tiles.
    (i was thinking of generating maps using Mappy, then hard code each map & tile’s properties, and finally fill all maps in an array…seems kind of primitive :\ )
    plus i thought of spicing things up, like playing from top view. Any suggestions for an easy approach would be appreciated :)
    Thank you for the tutorial;very helpful.

  15. Fuhans says:

    Sir Paul Firth, i want to ask.. is that possible to make 2d platform game without using flash professional (just using coding in Flash Develop)? because i make a some game without using flash professional (only using Flash Develop and create the environment into coding)

    sorry for my bad english

    thanks

  16. Ganesh says:

    Hey,
    I have learnt C and C++ in school and done some private courses, but the program codes above look out of scope for me, is that because its too advance???
    If yes, then to understand them and write a code what exactly do i need to learn???
    I mean is there any specific course/subject for that??

    Unless i understand them i cant say “I know programming”

    Thanks :D

  17. Chris says:

    Hey I recently purchased your source code for a small project of mine. I’ve been trying to edit the tile set to change the current tiles for my own art. However every time i try to change the background tiles (CheeseCornerTopRightBackground) there seems to be no collision detection. How would I go about creating collision for these tiles ?
    Thanks :)

    • Paul Firth says:

      Hi there,

      As long as you maintain the same actionscript names the tiles it should be ok – CheeseTileFla, CheeseTopFla, CheeseRightFla, etc etc…

      However, the background tiles don’t collide with anything anyway? Its only the foreground tiles which do IIRC.

      Cheers, Paul.

  18. Kristian says:

    Hi and thanks for your tutorials!

    I tried following along with this one (the first part, about background layers and a parallax effect) and got it to work in my own little test project (converting it to C++ and SFML), but I don’t understand exactly what the calculations in the code accomplish.

    I think I can follow the calculations: in PositionLogic you take the top left coordinate of the screen and scale this vector by the z depth. You then store a vector, offset, which could be described as reaching from the top left corner of the screen to the “tip” of the scaled vector. Finally, you figure out how many tiles fit in the scaled vector, store the position these tiles would reach, subtract the offset vector and start covering the screen with tiles from that position. I understand the parallax concept and I got the code to work, I just don’t get why it is done the way I described above (if my understanding is correct, that is). I’m quite new at this so it may well be a simple misunderstanding or something really obvious :).

    • Paul Firth says:

      Hi Kristian,

      I think you’ve nearly got it right.

      What I do is calculate the top left of the screen, scale by the z depth (this moves it away from the top left), then I need to offset this scaled position back to the top left again, which is the offset vector. Then I work out how many tiles fit on screen and away we go :)

      Cheers, Paul.

  19. Michél says:

    Awesome tutorial! :) It helped me alot! once I get my own game up and running . then I’ll send a link :D

  20. Reuben says:

    what program did you use to make the images and blocks for the game?

  21. Tristyn Gordon says:

    Okay, so I’m supposed to do the artwork for a platformer game. This is my first time and it’s just confusing the hell out of me since I am not a programmer. I have to document what each tile represents and how it’s supposed to be applied. And I don’t really know where to start at all, can you please explain what that means and how I’m supposed to do it? I would seriously appreciate it, because I’m a literal beginner at this.

    • Paul Firth says:

      Well, not knowing exactly what your programmer wants its a bit difficult to tell, but from your description I presume they want to know whether each tile is an edge piece or a middle piece, background, foreground, what material type it is, ice, grass, stone whatever.

      Obviously you’ll have to make sure all your middle tiles actually tile correctly, as well :)

  22. ooper says:

    very good!!

  23. SgtPineapple says:

    I was making a game where you have a plane and the other planes fly down from the top and you shoot at them. I got to the point where i made the character plane follow my cursor and i have the sprites for the enemy planes but i dont know what to do from here.
    Can you help me?

  24. Ian says:

    thank you for the tutorial
    about GeneRic, how do you draw the sprites?
    do you draw them in hand first then scan or draw in a software from scratch, if you do which one you use
    thanks in advance

  25. Md Rubel says:

    Hello,
    I bought the source code from you and trying to compile and run it.
    I compiles perfectly and runs ok. But when beetles throw bullet, i get the following error

    ArgumentError: Error #2109: Frame label 1.5 not found in scene 1.5.
    at flash.display::MovieClip/gotoAndStop()
    at Code.Graphics::AnimationController/GoToAndStop()
    at Code.Graphics::AnimationController/Update()
    at Code.Characters::Character/Update()
    at Code.Characters::Enemy/Update()
    at Code.Characters::LadySpikes/Update()
    at Platformer/Update()
    at Code.System::GameLoop/UpdateInternal()
    ArgumentError: Error #2109: Frame label 1.5 not found in scene 1.5.
    at flash.display::MovieClip/gotoAndStop()
    at Code.Graphics::AnimationController/GoToAndStop()
    at Code.Graphics::AnimationController/Update()
    at Code.Characters::Character/Update()
    at Code.Characters::Enemy/Update()
    at Code.Characters::LadySpikes/Update()
    at Platformer/Update()
    at Code.System::GameLoop/UpdateInternal()
    ArgumentError: Error #2109: Frame label 1.5 not found in scene 1.5.
    at flash.display::MovieClip/gotoAndStop()
    at Code.Graphics::AnimationController/GoToAndStop()
    at Code.Graphics::AnimationController/Update()
    at Code.Characters::Character/Update()
    at Code.Characters::Enemy/Update()
    at Code.Characters::LadySpikes/Update()
    at Platformer/Update()

  26. Mr M says:

    Great tutorial!

    I am using Unity myself these days. Check out this tool to develop platformers: https://www.assetstore.unity3d.com/#/content/10411

  27. Alex Sims says:

    Hi Paul,

    Thanks for this tutorial, I’m a software engineer by trade and I have never attempted a game before, this tutorial has been great in providing me the foundations in being able to create my first platformer.

    I appreciate your efforts bringing this too us! :)

  28. myk says:

    cheers paul! i planning to purchase your game. but can you pls help me to put a menu and a score board on it? im a beginner in as4. thanks from the philippines

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

WP-SpamFree by Pole Position Marketing