Do you like my tutorials?

Then consider supporting me on Ko-fi

Talking about Angry Birds game, Actionscript 3, Box2D, Flash and Game development.

Here we are with one of the most famous games running on your iPhone/iPad… Rovio‘s Angry Birds!

A lot of developers criticize this title, saying it’s just a clone of “shoot something to destroy something using physics”, but what can I say? It’s fun.

So don’t be envy and let’s start understanding how does the sling work.

I wrote a quick and quite messy code just as a pre-release, I will probably adjust something and explain the code tomorrow, but for all you “gimme the code now, I can read it”, here it is the sling:

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import Box2D.Dynamics.*;
	import Box2D.Collision.*;
	import Box2D.Collision.Shapes.*;
	import Box2D.Common.Math.*;
	import Box2D.Dynamics.Joints.*;
	public class Main extends Sprite {
		private var world:b2World=new b2World(new b2Vec2(0,10),true);
		private var worldScale:int=30;
		private var bird:birdMc=new birdMc();
		private var birdSphere:b2Body;
		public function Main() {
			var bg:backgroundMc=new backgroundMc();
			addChild(bg);
			addChild(bird);
			bird.x=170;
			bird.y=270;
			bird.buttonMode=true;
			addWall(320,10,320,395);
			addWall(320,10,320,-5);
			addWall(10,320,-5,240);
			addWall(10,320,645,240);
			addEventListener(Event.ENTER_FRAME,updateWorld);
			bird.addEventListener(MouseEvent.MOUSE_DOWN,birdClicked);
		}
		private function addWall(w,h,px,py):void {
			var floorShape:b2PolygonShape = new b2PolygonShape();
			floorShape.SetAsBox(w/worldScale,h/worldScale);
			var floorFixture:b2FixtureDef = new b2FixtureDef();
			floorFixture.density=0;
			floorFixture.friction=10;
			floorFixture.restitution=0.5;
			floorFixture.shape=floorShape;
			var floorBodyDef:b2BodyDef = new b2BodyDef();
			floorBodyDef.position.Set(px/worldScale,py/worldScale);
			var floor:b2Body=world.CreateBody(floorBodyDef);
			floor.CreateFixture(floorFixture);
		}
		private function birdClicked(e:MouseEvent):void {
			addEventListener(MouseEvent.MOUSE_MOVE,birdMoved);
			addEventListener(MouseEvent.MOUSE_UP,birdReleased);
			bird.removeEventListener(MouseEvent.MOUSE_DOWN,birdClicked);
		}
		private function birdMoved(e:MouseEvent):void {
			bird.x=mouseX;
			bird.y=mouseY;
			var distanceX:Number=bird.x-170;
			var distanceY:Number=bird.y-270;
			if (distanceX*distanceX+distanceY*distanceY>10000) {
				var birdAngle:Number=Math.atan2(distanceY,distanceX);
				bird.x=170+100*Math.cos(birdAngle);
				bird.y=270+100*Math.sin(birdAngle);
			}
		}
		private function birdReleased(e:MouseEvent):void {
			bird.buttonMode=false;
			removeEventListener(MouseEvent.MOUSE_MOVE,birdMoved);
			removeEventListener(MouseEvent.MOUSE_UP,birdReleased);
			var sphereShape:b2CircleShape=new b2CircleShape(15/worldScale);
			var sphereFixture:b2FixtureDef = new b2FixtureDef();
			sphereFixture.density=1;
			sphereFixture.friction=3;
			sphereFixture.restitution=0.1;
			sphereFixture.shape=sphereShape;
			var sphereBodyDef:b2BodyDef = new b2BodyDef();
			sphereBodyDef.type=b2Body.b2_dynamicBody;
			sphereBodyDef.userData=bird;
			sphereBodyDef.position.Set(bird.x/worldScale,bird.y/worldScale);
			birdSphere=world.CreateBody(sphereBodyDef);
			birdSphere.CreateFixture(sphereFixture);
			var distanceX:Number=bird.x-170;
			var distanceY:Number=bird.y-270;
			var distance:Number=Math.sqrt(distanceX*distanceX+distanceY*distanceY);
			var birdAngle:Number=Math.atan2(distanceY,distanceX);
			birdSphere.SetLinearVelocity(new b2Vec2(-distance*Math.cos(birdAngle)/4,-distance*Math.sin(birdAngle)/4));
		}
		private function updateWorld(e:Event):void {
			world.Step(1/30,10,10);
			for (var currentBody:b2Body=world.GetBodyList(); currentBody; currentBody=currentBody.GetNext()) {
				if (currentBody.GetUserData()) {
					currentBody.GetUserData().x=currentBody.GetPosition().x*worldScale;
					currentBody.GetUserData().y=currentBody.GetPosition().y*worldScale;
					currentBody.GetUserData().rotation=currentBody.GetAngle()*(180/Math.PI);
				}
			}
			world.ClearForces();
			world.DrawDebugData();
		}
	}
}

And this is the result:

… you should know how to play… drag the bird to fire it with the sling.

Download the source code.

Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.