Creation of a Flash artillery game using Box2D

Read all posts about "" game

Small intro: having a plugin that allows readers to vote posts can help you understanding what do readers like.

I saw readers liked a lot Create a flash artillery game – step 1 so I decided to create something similar with modern techniques (that post is dated 2007!!! Ages ago!!).

Let’s start from Platform engine using Box2D – Step 3 and turn the way player fires into an artillery mode.

In an artillery game, the more you press the fire button, the stronger the force you’ll apply to the projectile.

To make things more interesting, pressin the button for an hour won’t fire a lightspeed bullet, but once the force reached its maximum it will decrease, just to start increasing again once it reaches its minimum and so on, until the player releases the fire button

In the following example, holding the mouse will determine bazooka’s force, and releasing it will make the player fire.

The animation of the bazooka turning red has been made on the timeline, with a 30 frames tween. This means the maximum force should be 30 :)

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;
			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) {
					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;
				}
			}
			// 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: press and hold the mouse button and see what happens.

Download the source code and tell me if you are ready for a Box2D Bloons :)

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

214 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers