Bookmark and Share

PushButton game engine which arrived to the open source world at March 2009, has earned much community supports since then. It also has Box2D physics engine built-in but unfortunately its example was done using XML templates which some people may not like… so here is a basic Box2D setup in the code (You will need PBE 1.0):

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package {
 
	import com.pblabs.engine.PBE;
 
	[SWF(width="800", height="600", frameRate="30")]
	public class Game extends Sprite {
 
		public function Game() {
			PBE.startup(this);
 
			createScene();
			createBox2DManager();
			createBall();
			createBrick();
		}
 
		private function createScene():void {}
		private function createBox2DManager():void {}
		private function createBall():void {}
		private function createBrick():void {}
 
}

What we need to do first is to create scene then box2D manager (debugger if needed) and setup ball and brick entities. Since PushButton is component based, you will see the full code below that adds a few components into each entity (the code should be self-explainable with comments):

?View Code ACTIONSCRIPT
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
package {
 
	import com.pblabs.box2D.Box2DDebugComponent;
	import com.pblabs.box2D.Box2DManagerComponent;
	import com.pblabs.box2D.Box2DSpatialComponent;
	import com.pblabs.box2D.CircleCollisionShape;
	import com.pblabs.box2D.PolygonCollisionShape;
	import com.pblabs.engine.PBE;
	import com.pblabs.engine.core.InputMap;
	import com.pblabs.engine.core.ObjectType;
	import com.pblabs.engine.entity.IEntity;
	import com.pblabs.engine.entity.PropertyReference;
	import com.pblabs.rendering2D.SimpleShapeRenderer;
	import com.pblabs.rendering2D.SpriteRenderer;
	import com.pblabs.rendering2D.SpriteSheetRenderer;
	import com.pblabs.rendering2D.spritesheet.SpriteSheetComponent;
	import com.pblabs.rendering2D.ui.SceneView;
 
	import flash.display.Sprite;
	import flash.geom.Point;
	import flash.geom.Rectangle;
 
	[SWF(width="800", height="600", frameRate="30")]
	public class Game extends Sprite {
 
		public function Game() {
			PBE.startup(this);
 
			createScene();
			createBox2DManager();
			createBall();
			createBrick();
		}
 
		private function createScene():void {
			var sceneView:SceneView = new SceneView();
			sceneView.width = 800;
			sceneView.height = 600;
			PBE.initializeScene(sceneView);
		}
 
		private function createBox2DManager():void {
			// Create manager component.
			var comp:Box2DManagerComponent = new Box2DManagerComponent();
 
			// Allocate new entity and add components.
			var myEntity:IEntity = PBE.allocateEntity();
			myEntity.addComponent(comp, "Manager");
			myEntity.initialize("SpatialManager");
		}
 
		private function createBall():void {
			// Create spatial component.
			var spatialComp:Box2DSpatialComponent = new Box2DSpatialComponent();
			spatialComp.spatialManager = PBE.lookupEntity("SpatialManager").lookupComponentByName("Manager") as Box2DManagerComponent;
			spatialComp.canMove = true;
			spatialComp.canRotate = true;
			spatialComp.canSleep = false;
			spatialComp.position = new Point(0, -300);
			spatialComp.size = new Point(60, 60);
			spatialComp.collisionType = new ObjectType("Ball");
			spatialComp.collidesWithTypes = new ObjectType("Brick");
 
			// Collision shape.
			var shape:CircleCollisionShape = new CircleCollisionShape();
			shape.radius = 1.0;
			shape.density = 1;
 
			// Add the shape to spatial component.
			spatialComp.collisionShapes = new Array();
			spatialComp.collisionShapes.push(shape);
 
			// Create input component.
			var gameInput:GameInput = new GameInput();
			gameInput.input = new InputMap();
			gameInput.velocityReference = new PropertyReference("@Spatial.linearVelocity");
 
			// Create renderer component.
			var renderer:SimpleShapeRenderer = new SimpleShapeRenderer();
			renderer.fillColor = 0xdddddd;
			renderer.isCircle = true;
			renderer.lineColor = 0x000000;
			renderer.scene = PBE.scene;
			renderer.positionProperty = new PropertyReference("@Spatial.position");
			renderer.rotationProperty = new PropertyReference("@Spatial.rotation");
			renderer.sizeProperty = new PropertyReference("@Spatial.size");
 
			// Allocate new entity and add components.
			var myEntity:IEntity = PBE.allocateEntity();
			myEntity.addComponent(spatialComp, "Spatial");
			myEntity.addComponent(gameInput, "Input");
			myEntity.addComponent(renderer, "Render");
			myEntity.initialize("Ball");
 
		}
 
		private function createBrick():void {
			// Create spatial component.
			var spatialComp:Box2DSpatialComponent = new Box2DSpatialComponent();
			spatialComp.spatialManager = PBE.lookupEntity("SpatialManager").lookupComponentByName("Manager") as Box2DManagerComponent;
			spatialComp.position = new Point(0, 0);
			spatialComp.size = new Point(250, 60);
			spatialComp.canMove = false;
			spatialComp.canRotate = false;
			spatialComp.collisionType = new ObjectType("Brick");
			spatialComp.collidesWithTypes = new ObjectType("Ball");
 
			// Collision shape.
			var shape:PolygonCollisionShape = new PolygonCollisionShape();
			shape.vertices = [new Point(-1, -1), new Point(1, -1), new Point(1, 1), new Point(-1, 1)];
			shape.density = 1;
 
			// Add the shape to spatial component.
			spatialComp.collisionShapes = new Array();
			spatialComp.collisionShapes.push(shape);
 
			// Create renderer component.
			var renderer:SimpleShapeRenderer = new SimpleShapeRenderer();
			renderer.fillColor = 0xdddd00;
			renderer.isCircle = false;
			renderer.isSquare = true;
			renderer.lineColor = 0x000000;
			renderer.scene = PBE.scene;
			renderer.positionProperty = new PropertyReference("@Spatial.position");
			renderer.rotationProperty = new PropertyReference("@Spatial.rotation");
			renderer.sizeProperty = new PropertyReference("@Spatial.size");
 
			// Allocate new entity and add components.
			var myEntity:IEntity = PBE.allocateEntity();
			myEntity.addComponent(spatialComp, "Spatial");
			myEntity.addComponent(renderer, "Renderer");
			myEntity.initialize("Brick");
		}
	}
}

You will also need GameInput class for input component to control the ball:

?View Code ACTIONSCRIPT
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
package {
 
	import com.pblabs.box2D.CollisionEvent;
	import com.pblabs.engine.PBE;
	import com.pblabs.engine.components.TickedComponent;
	import com.pblabs.engine.core.InputKey;
	import com.pblabs.engine.core.InputMap;
	import com.pblabs.engine.entity.EntityComponent;
	import com.pblabs.engine.entity.PropertyReference;
 
	import flash.geom.Point;
 
	public class GameInput extends TickedComponent {
 
		[TypeHint(type="flash.geom.Point")]
		public var velocityReference:PropertyReference;
 
		private var _inputMap:InputMap;
		private var _left:Number = 0;
		private var _right:Number = 0;
		private var _jump:Number = 0;
		private var _onGround:int = 0;
 
		public function get input():InputMap {
			return _inputMap;
		}
 
		public function set input(value:InputMap):void {
			_inputMap = value;
			if (_inputMap != null) {
				_inputMap.mapKeyToHandler(InputKey.LEFT, onLeft);
				_inputMap.mapKeyToHandler(InputKey.RIGHT, onRight);
				_inputMap.mapKeyToHandler(InputKey.SPACE, onJump);
			}
		}
 
		override public function onTick(tickRate:Number):void {
			var move:Number = _right - _left;
			var velocity:Point = owner.getProperty(velocityReference);
			velocity.x = move * 100;
 
			if (_jump > 0) {
				velocity.y -= 200;
				_jump = 0;
			}
 
			owner.setProperty(velocityReference, velocity);
		}
 
		override protected function onAdd():void {
			super.onAdd();
			owner.eventDispatcher.addEventListener(CollisionEvent.COLLISION_EVENT, onCollision);
			owner.eventDispatcher.addEventListener(CollisionEvent.COLLISION_STOPPED_EVENT, onCollisionEnd);
		}
 
		override protected function onRemove():void {
			super.onRemove();
			owner.eventDispatcher.removeEventListener(CollisionEvent.COLLISION_EVENT, onCollision);
			owner.eventDispatcher.removeEventListener(CollisionEvent.COLLISION_STOPPED_EVENT, onCollisionEnd);
		}
 
		private function onCollision(event:CollisionEvent):void {
			if (PBE.objectTypeManager.doesTypeOverlap(event.collidee.collisionType, "Brick")) {
				if (event.normal.y > 0.7)
					_onGround++;
			}
 
			if (PBE.objectTypeManager.doesTypeOverlap(event.collider.collisionType, "Brick")) {
				if (event.normal.y < -0.7)
					_onGround++;
			}
		}
 
		private function onCollisionEnd(event:CollisionEvent):void {
			if (PBE.objectTypeManager.doesTypeOverlap(event.collidee.collisionType, "Brick")) {
				if (event.normal.y > 0.7)
					_onGround--;
			}
 
			if (PBE.objectTypeManager.doesTypeOverlap(event.collider.collisionType, "Brick")) {
				if (event.normal.y < -0.7)
					_onGround--;
			}
		}
 
		private function onLeft(value:Number):void {
			_left = value;
		}
 
		private function onRight(value:Number):void {
			_right = value;
		}
 
		private function onJump(value:Number):void {
			if (_onGround > 0)
				_jump = value;
		}
 
	}
}

And if you need to debug box2D then add the code below:

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
private function createBox2DDebugger():void {
	// Create debugger component.
	var comp:Box2DDebugComponent = new Box2DDebugComponent();
	comp.spatialManager = PBE.lookupEntity("SpatialManager").lookupComponentByName("Manager") as Box2DManagerComponent;
	comp.scene = PBE.scene;
 
	// Allocate new entity and add components.
	var myEntity:IEntity = PBE.allocateEntity();
	myEntity.addComponent(comp, "Debug");
	myEntity.initialize("SpatialDebugger");
}

This should get you start!!