Way of an Idea Box2D prototype

Read all posts about "" game

Did you enjoy Way of an Idea?

Nice physics game… besides the joints and motors used in level design, the most interesting part is the chalk drawing.

Way of an Idea.

We are going to do it in three steps

Step 1 – Freehand drawing

Let’s start with a simple script with some mouse listeners to let the player draw when he presses and moves the mouse:

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	public class draw extends Sprite {
		public var drawing:Boolean=false;
		public var canvas:Sprite = new Sprite();
		public function draw():void {
			addChild(canvas);
			canvas.graphics.lineStyle(5)
			stage.addEventListener(MouseEvent.MOUSE_DOWN,mouse_pressed);
			stage.addEventListener(MouseEvent.MOUSE_MOVE,mouse_moved);
			stage.addEventListener(MouseEvent.MOUSE_UP,mouse_released);
		}
		public function mouse_pressed(e:MouseEvent):void {
			drawing=true;
			canvas.graphics.moveTo(mouseX,mouseY);
		}
		public function mouse_moved(e:MouseEvent):void {
			if (drawing) {
				canvas.graphics.lineTo(mouseX,mouseY);
			}
		}
		public function mouse_released(e:MouseEvent):void {
			drawing=false;
		}
	}
}

And this is the result:

Draw with the mouse

Step 2 – Segment drawing

Since the idea is converting a freehand drawing into a set of Box2D primitives, we can’t allow the player to draw as free as he wants.

So we must constrain him to draw with segments of at least n pixels. The smaller n, the more realistic the freehand feeling, the more primitives needed to convert drawing into objects.

In this example I am using a 20 minimum length, but you are free to set your own by changing pixel_dist value at line 8

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	public class draw extends Sprite {
		public var drawing:Boolean=false;
		public var canvas:Sprite = new Sprite();
		public var pixel_dist:int=20;
		public var saved_x:int;
		public var saved_y:int;
		public function draw():void {
			addChild(canvas);
			canvas.graphics.lineStyle(5);
			stage.addEventListener(MouseEvent.MOUSE_DOWN,mouse_pressed);
			stage.addEventListener(MouseEvent.MOUSE_MOVE,mouse_moved);
			stage.addEventListener(MouseEvent.MOUSE_UP,mouse_released);
		}
		public function mouse_pressed(e:MouseEvent):void {
			drawing=true;
			canvas.graphics.moveTo(mouseX,mouseY);
			saved_x=mouseX;
			saved_y=mouseY;
		}
		public function mouse_moved(e:MouseEvent):void {
			if (drawing) {
				var dist_x:int=mouseX-saved_x;
				var dist_y:int=mouseY-saved_y;
				if (dist_x*dist_x+dist_y*dist_y>pixel_dist*pixel_dist) {
					canvas.graphics.lineTo(mouseX,mouseY);
					saved_x=mouseX;
					saved_y=mouseY;
				}
			}
		}
		public function mouse_released(e:MouseEvent):void {
			drawing=false;
		}
	}
}

This is the result:

You can draw with the mouse with almost the same freedom as before

Step 3: Box2D conversion

In the final step we render the segments with Box2D rectangles. We just need to save all vertices in an array, determine segments length and angle with some trigonometry and create static rectangles once the player releases the mouse

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.*;
	public class draw extends Sprite {
		public var drawing:Boolean=false;
		public var canvas:Sprite = new Sprite();
		public var points_array:Array;
		public var pixel_dist:int=20;
		public var saved_x:int;
		public var saved_y:int;
		public var m_world:b2World;
		public function draw():void {
			// world creation
			var worldAABB:b2AABB = new b2AABB();
			worldAABB.lowerBound.Set(-100.0, -100.0);
			worldAABB.upperBound.Set(100.0, 100.0);
			m_world=new b2World(worldAABB,new b2Vec2(0,10),true);
			// end world creation
			// debug draw
			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);
			// debug draw end
			addChild(canvas);
			canvas.graphics.lineStyle(5);
			stage.addEventListener(MouseEvent.MOUSE_DOWN,mouse_pressed);
			stage.addEventListener(MouseEvent.MOUSE_MOVE,mouse_moved);
			stage.addEventListener(MouseEvent.MOUSE_UP,mouse_released);
			addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
		}
		public function mouse_pressed(e:MouseEvent):void {
			drawing=true;
			canvas.graphics.moveTo(mouseX,mouseY);
			points_array=new Array();
			saved_x=mouseX;
			saved_y=mouseY;
			points_array.push(saved_x);
			points_array.push(saved_y);
		}
		public function mouse_moved(e:MouseEvent):void {
			if (drawing) {
				var dist_x:int=mouseX-saved_x;
				var dist_y:int=mouseY-saved_y;
				if (dist_x*dist_x+dist_y*dist_y>pixel_dist*pixel_dist) {
					canvas.graphics.lineTo(mouseX,mouseY);
					saved_x=mouseX;
					saved_y=mouseY;
					points_array.push(saved_x);
					points_array.push(saved_y);
				}
			}
		}
		public function mouse_released(e:MouseEvent):void {
			drawing=false;
			var sx:int;
			var ex:int;
			var sy:int;
			var ey:int;
			var dist_x:int;
			var dist_y:int;
			var dist:Number;
			var angle:Number;
			var segments:int=points_array.length/2-1;
			for (var i:int=0; i

and this is the final result:

Now you can draw with the mouse and create solid objects along your path.

Download the source code.

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

215 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
// Stairs
// 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