Hello and welcome back to my blog!
This time I’m going to try something new. There are many tutorials for various techniques and tricks on the web, but what you don’t often see is one that takes you through the development of a game, step by step from start to finish.
This is what I’m going to attempt here. I hope that it will provide some missing insight into the components that actually make up a working game and how to go about developing them.
I’m going to assume the reader is familiar with the basics of game development and I’m going to concentrate on the art and programming. At the end of this tutorial you will be able create a demo similar to this:
Angry Birds
So, the game I’m going to be making is to be based on the extremely popular Angry Birds by Rovio, a AAA title which cost some $140k USD to make.
Obviously, since its just me making this I will have to take a few short-cuts and will be concentrating on the core part of the game.
Cloning
Before I start I should mention that I do not condone the cloning of games in any way; what I’m doing in these tutorials is purely for educational purposes and I have no plans to release the game at the end of this.
Analysis
Ok, lets have a look at the requirements for a bare-bones version of the game:
Graphics
- Background, mid-ground and foreground layers
- Bird characters,
- Pig characters,
- Slingshot,
- Rigid body pieces – materials: wood, stone, glass in rectangle, square and triangle shapes
Code
Camera
- Panning
- Parallax
- Zoom
- Object tracking
Collision detection
- Possible requirement for advanced broad-phase
- Various static and dynamic shapes – rectangles, triangles, circles
- Object colliding call-back system
Physics
- Very stable physics engine
- Integrated object sleeping system
Editor
- Some kind of editor to allow layout of levels and creation of graphics. I’m using Flash CS4 for all this.
The Beginning
The first thing I’m going to tackle from that list is to get the world set up so that there is a nice looking environment and to root the project in something solid looking.
I started with the podium that the birds gets launched from; its going to be a static object in the physics system and to keep things simple I’m going to compose all objects from primitive parts, so collision wise at least the podium will be made from some squares and triangles.
As you can see, it’s covered with a repeating earth texture, so the first thing is to make this. Its actually quite easy to do:
The first part is easy, just pick two vaguely earthy colours and paint one half of the texture in each colour, with a nice rough overlap in the midddle.
Then, offset the image by half the width and height (I used photoshop’s offset filter) to get the image in the middle. Then you can rough up the middle edge as you did in the first image. Once you’re done you’ll have a nice infinitely repeatable texture.
In order to actually apply this texture to an arbitrary object in Flash, you import the image onto the stage, then right click and and choose ‘Break apart’. Then you can use the eye-dropper tool to pick that texture as a fill texture which you can then apply to any shape with the paint bucket.
Because we’re making all collision objects from primitive shapes, we need to decide what basic shapes we’re going to be using. I chose these for the podium:
These can be rotated, duplicated and placed to form the podium shape:
So, when actually creating the shape for the visible part of the podium, its important to follow the exact same shape that you could compose only using the primitive collision shapes in various different configurations.
This will start to become very useful later when we try to integrate the physics system with the graphics.
Foreground
The foreground consists of another tiling shape; the soil. This was made from a rectangle, and lots of ovals in Flash, just repeated and placed. Its important to make sure it tiles so pay attention at the edges and use grid snap.
Mid-ground
Yet another tiling shape, this time rolling hills with a few far off plants; nothing out of the ordinary here, just make sure it tiles. You’ll want to make this one wider than the screen – I made mine roughly twice as wide:
Background
Yes, you guessed it, tiling shapes again – this one is roughly one screen in size:
Exporting
All these layers have been set to export for action-script in the Flash IDE; I’ve appended every name with Fla so that I can tell in code which classes are from Flash and which are my own.
Everything should now be exported as a .swc which you can enable in File->Publish Settings->Flash->Export SWC.
Then you can import this SWC into your project in your favourite flash code compiler; I’m using Amythyst because I cannot live without Visual Studio.
Putting it together
Of course, the idea with all these separate layers is that the code will place and animate them separately to give a parallax effect as the camera pans/zooms around the world.
Dimensions
I picked a screen size of 640×360 (wide-screen), and a world size of 2560×720 (four screens wide by two screens high). And I’ve centred the world at 0,0.
The Camera
Having a good camera class is fundamental to any game, particularly this one which requires lots of smooth pans and zooms.
At the very least it should provide functions for converting coordinates between world space and screen space and visa versa.
Because there are three layers of parallax at work, the camera needs to be able to position each one as it pans around the scene, so its constructor takes them as parameters:
public function Camera(background:MovieClip, midground:MovieClip, foreground:MovieClip, bird:Bird) { ... }
The bird parameter is just a dummy at the moment which represents the focal point for the camera – it contains accessors for position so the camera can know where in the world it is.
In order to get the camera to centre on the bird no matter where the bird is on screen we need to do a little bit of maths; forming what is known as the world to screen matrix, so called because it transforms points in world space into screen space.
public function Update( dt:Number ) : void { m_worldToScreen = new Matrix(); m_worldToScreen.translate( -m_bird.m_Pos.x, -m_bird.m_Pos.m_y ); m_worldToScreen.scale( m_scale.m_x, m_scale.m_y ); m_worldToScreen.translate( Constants.kScreenDimensions.m_x/2, Constants.kScreenDimensions.m_y/2 ); m_foreground.transform.matrix = m_worldToScreen; // for screen->world matrix m_screenToWorld = m_worldToScreen.clone(); m_screenToWorld.invert(); }
What’s going on in the above function is: first the camera is centred on the bird, then any zoom is applied and finally we add on the centre of the screen to make sure the bird is in the centre (remember, 0,0 is the top left of the screen, not the centre).
We then take this matrix and apply it as the transform for the foreground geometry, so in actual fact the geometry moves around the camera, not the other way around – which is a bit difficult to get your head around at first.
The first translate in the above snippet is easier to understand with this in mind – 0,0 is the destination for the world geometry, coming from the position of the bird and 0-m_bird.m_Pos is the vector which achieves that.
Then I take a copy of this matrix and invert it so that I can do the opposite transform whenever I need to convert a point in screen-space to world-space.
To get the parallax effect on the back and mid-ground layers, I do a similar piece of maths for each layer (each layer getting its own world->screen matrix), the only change is that I divide the x translation by the layer’s z-depth, which causes them to move at different speeds.
All this will work fine, but it won’t prevent the camera from leaving the bounds of the world. In order to do that we need to understand the camera’s relationship with the world.
So, lets take a look at the world, the camera and their relationship:
Figure 1 shows the entire extents of the world and also one possible location for the camera. Note that the camera has the dimensions of the screen.
In this configuration, the camera is actually showing a view which is partially outside the world, which should not be allowed to happen. In order to fix this problem we need to know exactly how far outside the camera is.
Figure 2 shows the measurements we need to correct this problem (the red arrows) and also shows in green, the camera’s position after it has been corrected.
public function Update( dt:Number ) : void { // // clamp camera to only show map // var translate:Vector2 = m_bird.m_Pos.m_Neg; var screenHalfExtents:Vector2 = new Vector2(Constants.kScreenDimensions.m_x/2, Constants.kScreenDimensions.m_y/2).Div(new Vector2(m_scale.m_x, m_scale.m_y)); var mapExtents:Vector2 = Constants.kWorldAabb.m_HalfExtents.MulScalar( 2 ); var topLeft:Vector2 = m_bird.m_Pos.Sub(screenHalfExtents); var bottomRight:Vector2 = m_bird.m_Pos.Add(screenHalfExtents); var correctLeft:Number = Math.min(topLeft.m_x+Constants.kWorldAabb.m_HalfExtents.m_x, 0); var correctTop:Number = Math.min(topLeft.m_y+Constants.kWorldAabb.m_HalfExtents.m_y, 0); var correctRight:Number = Math.min(Constants.kWorldAabb.m_HalfExtents.m_x-bottomRight.m_x, 0); var correctBottom:Number = Math.min(Constants.kWorldAabb.m_HalfExtents.m_y-bottomRight.m_y, 0); translate.m_x += correctLeft - correctRight; translate.m_y += correctTop - correctBottom; ... }
The above is the code which calculates the red arrowed regions shown in Figure 2, and applies any corrections needed to the initial translation of the camera.
There is one caveat to watch out for: the foreground layer is a child of the main MovieClip which makes up the game – this is essential because otherwise the camera would only be translating the foreground shape and not everything in the world, which would be all bad. However, because the camera is translating the main MovieClip, the mid and background layers cannot be children of it. Instead, they must be children of the stage; this allows them to be translated independently to give the correct effect.
Create a tile strip
This is relatively simple, you just divide the width of the world by the width of a tile to get the number of repetitions, set the starting point and then just instance the correct MovieClip:
private function CreateTileStrip( start:Vector2, type:Class ):MovieClip { var obj:* = new type(); var mc:MovieClip = MovieClip( obj ); var tileRoot:MovieClip = new MovieClip( ); var worldWidth:Number = Constants.kWorldAabb.m_HalfExtents.m_x*2; var numTiles:int = (worldWidth/mc.width) + 1; for ( var i:int = 0; i<numTiles; i++) { var x:Number = i*(mc.width-1); mc.x = x + start.m_x; mc.y = start.m_y-mc.height; tileRoot.addChild( mc ); obj = new type(); mc = MovieClip( obj ); } return tileRoot; }
And you call it like this:
m_backgroundLayer = CreateTileStrip( bottomLeft, BackgroundTileFla ); m_midgroundLayer = CreateTileStrip( bottomLeft, MidgroundTileFla ); m_foregroundLayer = CreateTileStrip( bottomLeft, ForegroundTileFla );
I was actually pleasantly surprised how easy it was to pass a class as a type in actionscript, much easier than in c# or c++ and it really makes it simple to tile any shape that you export from the Flash IDE.
The demo
Ok, so here is the demo so far:
It demonstrates a continuous loop of zooming and panning, three layers of parallax and will not allow the camera to move outside of the world.
The source
As ever, please if you like this article buy the source code (and in this case assets as well) so that I can produce more of this series; your contribution makes a real difference!
It will include all the code which produced the demo above and in addition, all the artwork as well, which you will need Flash CS4 to edit. You are free to use this however you like, even in commercial applications – the only thing I ask is that you don’t give it wholesale to anyone else.
After purchasing, you will be redirected to a page where you can download the source immediately.
USD 4.99
Subscribers can access the source here
Have fun,
Cheers, Paul.















Twitter
Facebook
RSS
This is awesome!
Thanks!!!!!!!
Peruvian Represent!
Hello,
It is really nice to see the computer graphics matrix theory applied in action! The parallax is a nice, effect, thanks for showing how easy it is to achieve with some basic Matrix arithmetic.
I have a nit pick regarding the last function:
var numTiles:int = (worldWidth/mc.width) + 1;
If by chance mc.width evenly divides worldWidth you will end up creating an extra tile. That’s not a real problem here, but it’s not the best way to go about dividing. I would go with:
if(worldWidth % mc.width==0)
numTiles = worldWidth/mc.width;
else
numTiles = worldWidth/mc.width +1;
Greetings from fellow AS programmer,
Caroline
Ah, yes! Good spot Caroline, thanks
Excellent article, and /articles/
Off topic question but where is that 140k cost from? How did it cost that much to make that game when they’re using Box2D and that game is basically the Box2d demo?
Thanks!
I have literally no idea – I’m betting a lot of that is marketing spend, and maybe there were a lot of failed prototypes?
I didn’t realise they were using box2d, that’s interesting!
Cheers, Paul.
“Basically the Box2d demo”?
Last time I checked the Box2D demos looked like this:
http://box2d.org/screenshots.html
Not exactly salable material.
And it’s just the physics engine. You need all the other handling code too. And you need graphics. And you need to pay your graphic designer and your coders to finish it and debug it and polish it.
I haven’t had a chance to read through this in its entirety but this is an awesome idea and it looks like a great tutorial. Keep up the good work!
Thanks Mike!
would there be part two? I just downloaded your files. Cool tutorial.
Hi Dave,
Yes, part two is on the way
Cheers, Paul.
that’s awesome. ive been looking for this kind of tutorial over the internet. when will be the next tutorial. im willing to pay
Hopefully the end of this week/beginning of next
Hey. It’s almost a month. Is the part 2 coming soon? I’m so excited.
Sorry Dave – I had some bugs and features to work out
I’m literally writing the pt2 article as we speak
cool! is this it? or there’s more?
Depends if enough people buy it
This one took a long time to make, so it needs to pay for itself!
Have you thought of using Box2d Flash for the Physics?
Hi Doug,
That would be the totally logical choice in the real world – but then again, physics is what I do (or did do anyway) so I think I can probably cover some of the things you don’t often see talked about by writing it myself in the hope it will help others… Lets see how it turns out!
Cheers, Paul.
– Quote –
I was actually pleasantly surprised how easy it was to pass a class as a type in actionscript, much easier than in c# or c++ and it really makes it simple to tile any shape that you export from the Flash IDE.
– End Quote –
This is not true at all, in c++ you can use templates and in c# you can use both generics and Type parameter passing.
Having used either templates or generics () you have gained precious compiler time error checking. You can’t do this in flash.
Its perfectly true – flash handles the actual passing of a type much more cleanly than c# and certainly c++ doesn’t have anything like that.
If you use Type in c# you start dealing with the pain of reflection, flash is more elegant.
You lose the type checking, this is true, but flash isn’t a strongly typed language anyway for better or worse (worse in my opinion)
private function CreateTileStrip( start:Vector2, type:Class ):MovieClip
{
var obj:* = new type();
var mc:MovieClip = MovieClip( obj );
...
}
C# equivalent:
1.
private MovieClip CreateTileStrip(Vector2 start) where T : MovieClip, new(){
T mc = new T();
...
}
This is the cleanest way possible, with compile time error checking.
2.
private MovieClip CreateTileStrip(Vector2 start, Type type){
MovieClip mc = (MovieClip)Activator.CreateInstance(type);
...
}
This is equivalent of the flash code, runtime error checking only.
In C++ you can write something similiar to #1 using templates.
Hmm is this HTML formatted, because it didn’t display the “less than” and “greater than” after CreateTileStrip.
CreateTileStrip<T>
Yes, you’re right; its certainly true as you’ve demonstrated there – the c# version is equivalent to the AS3 version.
There is one thing you can’t do, though in c#, which is to store the class type as a variable and then pass it to CreateTileStrip(). Now, I know i’m not doing that in this example, but I have used that pattern before – and its this which is neater in AS3, IMO
Of course you can do it:)
Type useMeLater = typeof(MovieClip);
…
CreateTileStrip(vector, useMeLater);
Ah yes, but you can’t write:
Type useMeLater = typeof(MovieClip);
CreateTileStrip<useMeLater>(vector);
which is whats required isn’t it?
Cheers, Paul.
That is true, but it makes sense that you can’t do it.
Compiler just can’t guess whether useMeLater in CreateTileStrip<useMeLater>(vector) is of type MovieClip at compile time.
For example this is used a lot in functional programming:
Function1<T, S>(…){
Function2<T>(…);
Function3<S>(…);
}
As my friend says you can code without worries of making a mistake, because it would not compile.
Though in my opinion not using it makes the code sometimes more readable.
The trouble is, if you need to use that pattern in c# you’re forced to use reflection which is a pain IMO… Don’t get me wrong, I much prefer the type safety of c# over actionscript, but I do find the fact that AS3 has a Class variable type to be a more elegant way of dealing with dynamic types than reflection in c#
However, if I’m able to use generics I always try to do that in c#.
Cheers, Paul.
Reflection can be really slow at times, especially when you parse through class properties/members.
I’ve learned to accept it for you can do nice things with it, like Attribute tags:
public class Document{
[NameBinding("name")]
public string Name { get; set; }
[NameBinding("address")]
public string Address { get; set; }
...
}
Now when you reflect the class you can match the property with the correct field in document(e.g. word).
Makes things really pretty.
Pingback: How to make Angry Birds – part 2 | Paul's blog@Wildbunny
Pingback: Semana de E3 | ~/jose152
What language are you using to make this?
Hi there,
I’m coding in flash
Cheers, Paul.
This is so cool. Thanks for doing this, the flash community is suffering so bad right now, especially because of Evil Apple, that this effort is greatly appreciated. It reminds me of why i decided to learn Actionscript in the first place, simply because of great developers like you sharing their knowledge with everyone. You sir, are the Man
Hey no problem
Glad you enjoyed it!
Pingback: How to make Angry Birds tutorials | Marco Olivo
Pingback: links for 2011-06-08 « Donghai Ma
Pingback: Cómo hacer un Angry Birds, primera parte | CyberHades
Pingback: Unity 3D Code Snippet – Flight Script « Keith M. Programming
hi,
I purchased part 1 of this and I am trying to convert your code to use with the Corona SDK, would you ever consider converting this to Corona?
Hi Marq,
I’ve no idea what Corona is! … Ok , just googled it!
Ok, as it stands the answer is no because I simply don’t have the time to get into mobile development right now… All my time is taken up with my flash work
Cheers, Paul.
Pingback: ??????? » [Web] ????
Pingback: Game Development: Links, News, Resources (1) « Angel “Java” Lopez on Blog
Paul,
Great tutorial. I’m new to all of this, so I’m trying to really understand all the methods you used to create such a demo? My question is other tutorials I’ve come across use box2d, looking over your tutorial I’ve been trying to see what version you are using but do not see you mention anything? Either that or I must be missing it? Also, part two you are selling the code for 49.99 and here it’s 4.99? Does part two include the code from here as well?
Sorry, I would really love to learn how to do this kind of coding and have one to many questions since my teacher has no clue on what or how to do this sort of stuff.
George =)
Hi George,
I’m not using box2d – I made my own custom physics engine just for this demo, to show programmers what it takes to write your own solution
Cheers, Paul.
Hi,
Thanks for sharing valuable blog article post and it provides fantastic online game for everyone on PC.
Angry Birds Flash
Do you have any idea on how to make a level selection screen? If so can you help us?
I would make a template for the level icon in the flash ide and then programatically display and array of them on screen with the appropriate level name and just stick an onClick handler on each one so you can tell which one was chosen
I do not know much English, but i want to make this game!!
thanks for the tutorial !
Pingback: angry birds tutorial - Fires of Heaven Guild Message Board
Pingback: TechFan.org » Before Angry Birds, There Was Castle Clout: Hit Game Arrives For iPhone® And iPad®
Pingback: How to make a 2d Platform Game – part 1 | Paul's blog@Wildbunny
Hey can you make a video for this ?
Pleeeasee..
Pingback: How to make games | Paul's blog@Wildbunny
Pingback: Development by sarajin - Pearltrees
Pingback: ??????????????????1? | GamerBoom.com ???
Pingback: ??????????????????1? | ????
Hi Paul,
bought your source code, looks great! However, experiencing some troubles with compiling from Flash Develop (I use Flash CS4). Do you think you could post some short tutorial/instructions how to compile properly your source code in Flash Develop? Appreciate it! Get no errors, but compiled swf does not work – static, guessing something wrong with paths/references..
Hi Alexis,
Things to check: are the class-paths set correctly in CS4 when you exported the .swc?
Did you get any warnings when compiling in FlashDevelop?
Very strange to have no errors at all, and then a blank window…
Cheers, Paul.
Ok, thanks. Checked all paths. When build/compiled från FD get 4 errors (playing with pt1): src\Code\AngryBirds.as:17: 1046: Type was not found or was not a compile-time constant: PodiumFla, 1180: Call to a possibly undefined method PodiumFla, etc
Project structure as:
AngryBirds/bin + lib + scr,
scr/Assets.fla,
src/Code/…as files,
lib/Assets.swc as library asset
in Flash CS4: classpath as Code.AngryBirds
What I am doing wrong?
Hi Alexis,
Have you tried to compile the project as it came without first exporting from CS4? That will tell us if the problem is CS4 or with the actual FlashDevelop project…
Cheers, Paul.
Hi Paul,
Why? Strange, I’m going to keep debugging, but it works at least..
yes, of course – the same error in pt1.. but, I got pt2 working- cool! However, for some reason, the last level (nr3) is always in the stage after compiling, so I have double of everything
Ok, so the project pt1 fails to compile as it first came?
Hmmm, I’ve never seen a problem with double of everything before – is this fresh out of the box, as it were, or has it been modified and exported from CS4?
Cheers, Paul.
Ok, got it working completely! Even made some new levels to test – amazing work Paul! Thank you once again. The problem was a MovieClip on a stage in the ‘out of the box’ .fla file, removed it and everyhting works smoothly, even without FD. I just exported directly from CS4 and all changes visible right away..
Great, glad you got it working
Sorry you were having problems!
Pingback: Startups | Pearltrees
hey im trying to make a game in gamemaker, sort of an angry birds game. but with pokemons in stead of birds could you tell me how to start?
Hi there,
Sorry, gamemaker is not something I’m familiar with – I suggest a quick google for some related tutorials?
Cheers, Paul.
Hi Paul,
working with your scripts for some time now – amazing work men!
Question: is it possible to make dynamic triangles as well (may be even octagons)? Seems like it narrowed to 2-3 files where it has to be specified or is it more complex task? Thanks for any tips on that!
Hello Paul…nice tutorial…do u have email or Skype? Thanks.
Hi, click ‘Contact me’ on the menu bar
hi paul!
how are u?!
plzzz help me…!!!!!i need to the angry birds source code in java or c++ completely!plz send me very very….. soon.
thanks so much!
Hi Soheila,
Unfortunately I do not have the source code in java or c++, its only available in AS3, sorry!
Cheers, Paul.
Hello.. Good works.. And i have a question.. If we want to make this game for android, what must we do? Can we make it in Flash, too?
Hi,
Yes, you can use flash via adobe air on andriod
Cheers, Paul.
Hello Paul, I have a problem trying to implement zooming at the game..please could you give me some ideas how to implement that?….
Nice Work!
If you have the source code accompanying this article simply change the value of m_scale inside Camera.as
Cheers, Paul.
I would like to buy the source, so I tried to register for your site (thank you very much for this tutorial). But I haven’t received a confirmation e-mail and it won’t let me login.
Is there something on your site you need to occasionally give a kick?
Thanks again!
Paul Firth Hello, my name is William and I am your big fan, I really want to buy that source more I’m Brazilian, I do not have the U.S. currency.
Please, pass me the source code, I beg you, Please!
please!
please!
please!
please!
please!
please!
Hi there,
PayPal converts automatically from your native currency into USD – you don’t need a paypal account you just need a credit card
Cheers, Paul.
What should I buy, to $ 49.99 or $ 4.99 for?
I await response …
Sorry, I don’t understand the question?
Which code should I buy, the first costing $ 4.99 or the second source code, which costs $ 49.99
Depends what you’re after – the 2nd code contains all of the 1st, so no need to buy pt1 if you buy pt2