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.

Download the source code.

Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (25 votes, average: 4.48 out of 5)
Loading ... Loading ...
Flash Templates provided by Template Monster are pre-made web design products developed using Flash technology.
They can be easily customized to meet the unique requirements of your project.
Be my fan on Facebook and follow me on Twitter! Exclusive content for my Facebook fans and Twitter followers

This post has 15 comments

  1. MSFX

    on September 7, 2009 at 8:04 pm

    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?

  2. Astro75

    on September 7, 2009 at 8:39 pm

    You can fly by holding UP and rapidly clicking bottom of the flash screen

  3. Platon Skedow

    on September 8, 2009 at 8:32 am

    The best way to fix rotation of a hero – set
    bodyDef.fixedRotation = true;
    instead of calling each time bb.m_sweep.a=0;

  4. Monkios

    on September 8, 2009 at 8:21 pm

    @ Astro75 :

    Let’s call that the “Jetpack effect“.

  5. Guest

    on September 10, 2009 at 2:58 pm

    Thanks for the post!

  6. Guest

    on September 11, 2009 at 9:32 am

    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)

  7. Thomas Francis

    on September 14, 2009 at 5:48 pm

    If you shoot down really fast, you can fly!

  8. SO69

    on September 15, 2009 at 8:46 pm

    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!

  9. Guest

    on September 24, 2009 at 10:25 pm

    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?

  10. Connor

    on December 20, 2009 at 6:00 am

    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

  11. Connor

    on December 21, 2009 at 8:19 pm

    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 -.-

  12. Jodi Houareau

    on April 1, 2010 at 8:43 am

    Thanks awesome tutorial! Having some trouble with skinning it tho if you looking for more tutorial ideas!

  13. unity3D gamer

    on May 4, 2011 at 1:39 pm

    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.

  14. shinboiz

    on August 29, 2011 at 7:54 am

    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.

  15. T_N_D

    on December 5, 2011 at 6:49 pm

    Hello, great tutorial!!

    Why the player have some easeout when i stop moving? How i can remove it?

    Thanks