Creation of a Flash artillery game using Box2D – part 2: removing bullets
This is the second part of Creation of a Flash artillery game using Box2D… one reader asked for a function to make blocks (bullets) disappear after 10 seconds or any given time.
I found the question interesting, and here I am writing something about removing bullets.
To introduce timed bullets, I only need another class to keep track of passed time and pass a flag to the main class when the bullet “gets old”.
This is the new class called bullet.as
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 | package { import flash.display.Sprite; import flash.utils.Timer; import flash.events.TimerEvent; public class bullet extends Sprite { // setting the time to 10,000 milliseconds = 10 seconds public var time_count:Timer=new Timer(10000); // flag to determine if I have to remove the bullet public var remove_the_bullet=false; public function bullet() { // simple time listener time_count.addEventListener(TimerEvent.TIMER, bullet_is_old); time_count.start(); } public function bullet_is_old(event:TimerEvent) { // removing the time listener time_count.removeEventListener(TimerEvent.TIMER, bullet_is_old); // setting the flag to true remove_the_bullet=true; } public function has_to_be_removed():Boolean { // returning the flag, this is the method I'll call from the main class return (remove_the_bullet); } } } |
Next step is assign the class to every new bullet and periodically check for bullet age and eventually remove it.
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 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | 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; public var m_contactListener=new b2ContactListener(); // defining the power of the bazooka public var power:int=1; // flag to determine if I am charging the bazooka // 0 = not charging // 1 = positive charge // -1 = negative charge public var charging:int=0; 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); // // adding the contact listener m_world.SetContactListener(m_contactListener); // // 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); bazooka.gotoAndStop(1); // now we don't shoot when the player clicks the mouse // but we charge bazooka's power while the mouse is pressed // and release the bullet when it's released stage.addEventListener(MouseEvent.MOUSE_UP, shoot); stage.addEventListener(MouseEvent.MOUSE_DOWN,charge); } public function charge(event:Event) { // I always start with positive charging charging=1; } public function shoot(event:Event) { // reset charging charging=0; 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(10/pixels_in_a_meter,10/pixels_in_a_meter); boxDef.friction=0.3; boxDef.density=1; // the bullet now has its own class bodyDef.userData = new bullet(); // giving the bullet a name... let's say "bullet"... bodyDef.userData.name="bullet"; body=m_world.CreateBody(bodyDef); body.CreateShape(boxDef); body.SetMassFromShapes(); // apply the impulse according to the power // that "/4" is just a setting to have decent gameplay body.ApplyImpulse(new b2Vec2(Math.cos(bazooka_angle)*power/4, Math.sin(bazooka_angle)*power/4),body.GetWorldCenter()); // resetting the power power=1; // updating bazooka clip bazooka.gotoAndStop(1); } 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); // var ground_sensor:b2PolygonDef = new b2PolygonDef(); ground_sensor.isSensor=true; ground_sensor.userData="groundsensor"; ground_sensor.SetAsOrientedBox(10/pixels_in_a_meter,5/pixels_in_a_meter,new b2Vec2(0,27/pixels_in_a_meter), 0); body.CreateShape(ground_sensor); // 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) { // I know my body is "something", now I have to perform // different actions according to body's name... "Player" or "bullet" switch (bb.m_userData.name) { // same as before case "Player" : if (Input.isKeyDown(39)) {// right arrow xspeed=3; } else if (Input.isKeyDown(37)) {// left arrow xspeed=-3; } if (Input.isKeyDown(38)) {// up arrow if (m_contactListener.can_jump()) {// checking if the hero can jump bb.ApplyImpulse(new b2Vec2(0.0, -1.0), bb.GetWorldCenter()); } } 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; break; case "bullet" : // checking if I have to remove the bullet if (bb.m_userData.has_to_be_removed()) { // removing the bullet bb.m_userData=null; m_world.DestroyBody(bb); } break; } } } // If I am charging the bazooka (I am holding the mouse) if (charging!=0) { // update the power power+=charging; // if the power ran out of range... // (I assume max power is 30 because there are 30 frames in the bazooka animation if (power>30||power<1) { // invert the power charging*=-1; // update the power again power+=charging; } // show the correct bazooka frame bazooka.gotoAndStop(power); } Input.update(); } } } |
And this is the result… same as Creation of a Flash artillery game using Box2D but boxes disappear after 10 seconds.
They can be easily customized to meet the unique requirements of your project.















(25 votes, average: 4.48 out of 5)









This post has 15 comments
MSFX
surely dispatching an event from the bullet and listening for it from the main class and then removing once received would be a better approach?
Astro75
You can fly by holding UP and rapidly clicking bottom of the flash screen
Platon Skedow
The best way to fix rotation of a hero – set
bodyDef.fixedRotation = true;
instead of calling each time bb.m_sweep.a=0;
Monkios
@ Astro75 :
Let’s call that the “Jetpack effect“.
Guest
Thanks for the post!
Guest
Can you make a little Box2d tutorial like: “Skinning a body in box2d for dummies”?
^_^’
skinning-> “applying textures or assigning a movieclip to a rigid body in box2d” mini-tutorial
not only to boxes (sprites) but to a main character (movieclip)
Thomas Francis
If you shoot down really fast, you can fly!
SO69
Great tutorial, thanks!
Can you show other basic elements in a box2d platform game, like: trampolines, bumps, ladders moving platforms and basic enemies? that would be great!
Guest
Emanuele, do you think it’s possible to use this to create a “hook”? i mean, like batman, or spiderman,… you throw a rope/whip to the roof, then you can swing using it… do you think its possible with box2D?
Connor
I am creating a 2-player shooter game using this engine and I was stuck at how to assign different keys (I was able to get another person to show up) but this showed me how I can do this, by creating another class, thanks! But how would I get the turret part onto the second player? I was also having trouble assigning the mouse event shoot and charge to keys, any help? :D
Connor
Part 3 should include reloading times and a way to control two different heroes with different keybindings. Also, how would one change the bazooka angle from being controlled by the mouse to a standard platform shooter where is either facing left or right and you control that with your mouse keys? I also couldn’t find a way to shoot with a certain key on the keyboard -.-
Jodi Houareau
Thanks awesome tutorial! Having some trouble with skinning it tho if you looking for more tutorial ideas!
unity3D gamer
Man, you are the best :P , these tutorials are just so perfect.
I tried to watch the video tutorials from kerp.net – and didn’t got anything from what he tried to explain :D , and these are the real thing! Thanks a lot.
shinboiz
Hi, i’m beginner using box2d. And i wonder how to replace BoxShape bullet by CircleShape bullet. Can you help me about this. Thanks…
P/s: and a small trouble : Did you use old version of box2D, cause when i use box2D new version for this project so it’s not working.
T_N_D
Hello, great tutorial!!
Why the player have some easeout when i stop moving? How i can remove it?
Thanks