Platform engine using Box2D – Step 2
After publishing Platform engine using Box2D, my attempt to replicate the Rick Triqui‘s main character continues.
Now you can move the guy with left and right arrows, aim the bazooka with the mouse and shoot a bullet clicking on the mouse.
The bazooka isn’t a Box2D object because I didn’t need to include it into the physics world, so it’s just a sprite, like the pills in Mazeroll game.
This is the source code, still uncommented (I’ll made the tutorial when I’ll have the character jumping and textured)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | package { import flash.display.Sprite; import flash.events.Event; import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.Math.*; import General.Input; import flash.events.MouseEvent; public class HelloWorld extends Sprite { public var m_world:b2World; public var pixels_in_a_meter:int=30; public var bodyDef:b2BodyDef; public var boxDef:b2PolygonDef; public var m_input:Input; public var xspeed:int=0; public var bazooka:zooka=new zooka(); public var bazooka_angle:Number; var body:b2Body; public function HelloWorld() { addEventListener(Event.ENTER_FRAME, Update, false, 0, true); var worldAABB:b2AABB = new b2AABB(); worldAABB.lowerBound.Set(-100.0, -100.0); worldAABB.upperBound.Set(100.0, 100.0); var gravity:b2Vec2=new b2Vec2(0.0,10.0); var doSleep:Boolean=true; m_world=new b2World(worldAABB,gravity,doSleep); var m_sprite:Sprite; m_sprite = new Sprite(); addChild(m_sprite); var dbgDraw:b2DebugDraw = new b2DebugDraw(); var dbgSprite:Sprite = new Sprite(); m_sprite.addChild(dbgSprite); dbgDraw.m_sprite=m_sprite; dbgDraw.m_drawScale=30; dbgDraw.m_alpha=1; dbgDraw.m_fillAlpha=0.5; dbgDraw.m_lineThickness=1; dbgDraw.m_drawFlags=b2DebugDraw.e_shapeBit; m_world.SetDebugDraw(dbgDraw); var bodyDef:b2BodyDef; var boxDef:b2PolygonDef; var circleDef:b2CircleDef; square_tile(250,395,500,10); hero(100,370,20,40); // Box2D input class - why should I bother making my one? m_sprite = new Sprite(); addChild(m_sprite); // input m_input=new Input(m_sprite); addChild(bazooka); stage.addEventListener(MouseEvent.CLICK, shoot); } public function shoot(event:Event) { bodyDef = new b2BodyDef(); bodyDef.position.Set((bazooka.x+(bazooka.width+3)*Math.cos(bazooka_angle))/pixels_in_a_meter, (bazooka.y+(bazooka.width+3)*Math.sin(bazooka_angle))/pixels_in_a_meter); boxDef = new b2PolygonDef(); boxDef.SetAsBox(0.1,0.1); boxDef.friction=0.3; boxDef.density=0.1; body=m_world.CreateBody(bodyDef); body.CreateShape(boxDef); body.SetMassFromShapes(); body.ApplyImpulse(new b2Vec2(Math.cos(bazooka_angle)/pixels_in_a_meter, Math.sin(bazooka_angle)/pixels_in_a_meter),body.GetWorldCenter()); } public function square_tile(px:int,py:int,w:int,h:int) { bodyDef = new b2BodyDef(); bodyDef.position.Set(px/pixels_in_a_meter, py/pixels_in_a_meter); boxDef = new b2PolygonDef(); boxDef.SetAsBox(real_pixels(w), real_pixels(h)); boxDef.friction=0.3; boxDef.density=0; body=m_world.CreateBody(bodyDef); body.CreateShape(boxDef); body.SetMassFromShapes(); } public function hero(px:int, py:int, w:int, h:int) { bodyDef = new b2BodyDef(); bodyDef.position.Set(px/pixels_in_a_meter, py/pixels_in_a_meter); boxDef = new b2PolygonDef(); boxDef.SetAsBox(real_pixels(w), real_pixels(h)); boxDef.density=1.0; boxDef.friction=0.3; boxDef.restitution=0.2; bodyDef.userData = new Sprite(); bodyDef.userData.name="Player"; body=m_world.CreateBody(bodyDef); body.SetBullet(true); body.CreateShape(boxDef); body.SetMassFromShapes(); } public function real_pixels(n:int) { return (n/pixels_in_a_meter/2); } public function Update(e:Event):void { m_world.Step(1/30, 10); xspeed=0; for (var bb:b2Body = m_world.m_bodyList; bb; bb = bb.m_next) { if (bb.GetUserData()!=null) { if (Input.isKeyDown(39)) { xspeed=3; } else if (Input.isKeyDown(37)) { xspeed=-3; } if (xspeed) { bb.WakeUp(); bb.m_linearVelocity.x=xspeed; } bb.m_sweep.a=0; bazooka.x=bb.m_userData.x=bb.GetPosition().x*30; bazooka.y=bb.m_userData.y=bb.GetPosition().y*30; var dist_x=bazooka.x-mouseX; var dist_y=bazooka.y-mouseY; bazooka_angle=Math.atan2(- dist_y,- dist_x); bazooka.rotation=bazooka_angle*57.2957795; } } Input.update(); } } } |
And this is the result:
Left/Right to move, mouse to aim and shoot.
Download the source code and enjoy.
They can be easily customized to meet the unique requirements of your project.















(25 votes, average: 4.64 out of 5)









This post has 7 comments
New
Oh that’s awesome.
Thomas Francis
Hey I’m working on a platform engine as well in Box2D. Well, a cleaner version of Box2D called QuickBox2D, and I kinda need some help.
When my character (a circle) is on a slope, how do I get the ball to stop sliding down the hill (it’s not rolling, i set fixed rotation). Setting the friction to 1 on the ball and the ground slows the ball’s speed going up the slope, but it does stop the sliding. And changing the ball’s Y linearvelocity to 0 when to the ball is on the ground also slows it’s movement on the slope…
What do I do?
Bass
there’s no source code attached :)
aseneo
where is the download link? :)
Thomas Francis
You’re supposed to paste the code in the timeline…
Agadoijo
Really looking forward for all tutorials related to making a platform engine with Box2D.
Do you think it would be possible to make a simpler version of a game like LittleBigPlanet? It would require lots of stuff… but it would be really fun!
Hopefully your tutorial will have scrolling, moving platforms and “ropes”! :D
Keep up the awesome work!
A Freelancer’s Flash Bash [4] | Freelance Flash Games News
[...] Feronato has been working on Box2d tutorials for a basic Filler engine and a platform engine. They’re quite [...]