For Part one Click here
For Part two Click here
That's what we have done till now
If you have seen the demo in the first part of this series you can see that we can't shoot the player unless it's on the ground, also we added some more walls in the scene and so in this tutorial we will be creating more walls and limit the shooting to only on the ground.
You can see how easy and fast it's to create walls using our createWall method.
For Part two Click here
That's what we have done till now
If you have seen the demo in the first part of this series you can see that we can't shoot the player unless it's on the ground, also we added some more walls in the scene and so in this tutorial we will be creating more walls and limit the shooting to only on the ground.
Creating more walls
We would need also to create one more thing and that is to set the returned b2Body for the creation of the wall that represents the ground to a ground object, so let's define that ground first
In the init method
private var ground:b2Body;
In the init method
public function init(e:Event = null):void { createWorld(); player = createPlayer(40, 50, 50, 10); addEventListener(Event.ENTER_FRAME, update); stage.addEventListener(MouseEvent.CLICK, stageClicked); var th:uint = 10; // Vertical walls createWall(0, 0 , th, stage.stageHeight); createWall(stage.stageWidth - th, 0, th, stage.stageHeight); // Horizontal walls createWall(0, 0 , stage.stageWidth, th); ground = createWall(0, stage.stageHeight - th, stage.stageWidth, th); createWall(200, 300 , th, 100); createWall(350, 300 , th, 100); createWall(250, th , th, 200); }
You can see how easy and fast it's to create walls using our createWall method.
Shooting player when only on the ground
What we would like to do here is when the mouse is clicked we need to check if the player is colliding with the ground or not to allow shooting.
Each b2Body has a list of bodies that it's in contact with, we will loop through them and check if one of them is the ground to execute the shooting algorithm.
That loop looks like the one in the second part of this series, GetContactList() method gets the first contactEdge in the list and saves the next contactEdge in the "next" variable.
We have checked if the ground is the same as the b2body object saved in the "other" variable, "other" means the other body that is in contact with the player.
for (var contact:b2ContactEdge = player.GetContactList(); contact; contact = contact.next) { if (contact.other == ground) { var force_x:Number = (mouseX / PM - player.GetPosition().x); var force_y:Number = (mouseY / PM - player.GetPosition().y); var force:b2Vec2 = new b2Vec2(force_x, force_y); force.Multiply( 2 / 3 ); player.ApplyImpulse(force, player.GetPosition()); } }
That loop looks like the one in the second part of this series, GetContactList() method gets the first contactEdge in the list and saves the next contactEdge in the "next" variable.
We have checked if the ground is the same as the b2body object saved in the "other" variable, "other" means the other body that is in contact with the player.
Part 3 All come together
The final code
public class Main extends MovieClip { public static var world:b2World; public static const PM:uint = 30; private var player:b2Body; private var ground:b2Body; public function Main() { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } public function init(e:Event = null):void { createWorld(); player = createPlayer(40, 50, 50, 10); addEventListener(Event.ENTER_FRAME, update); stage.addEventListener(MouseEvent.CLICK, stageClicked); var th:uint = 10; // Vertical walls createWall(0, 0 , th, stage.stageHeight); createWall(stage.stageWidth - th, 0, th, stage.stageHeight); // Horizontal walls createWall(0, 0 , stage.stageWidth, th); ground = createWall(0, stage.stageHeight - th, stage.stageWidth, th); createWall(200, 300 , th, 100); createWall(350, 300 , th, 100); createWall(250, th , th, 200); } public function stageClicked(e:MouseEvent):void { for (var contact:b2ContactEdge = player.GetContactList(); contact; contact = contact.next) { if (contact.other == ground) { var impulse_x:Number = (mouseX / PM - player.GetPosition().x); var impulse_y:Number = (mouseY / PM - player.GetPosition().y); var impulse:b2Vec2 = new b2Vec2(impulse_x, impulse_y); impulse.Multiply( 2 / 3 ); player.ApplyImpulse(impulse, player.GetPosition()); } } } public function update(e:Event):void { world.Step(1 / 30, 10, 10); var temp:Sprite; for (var body:b2Body = world.GetBodyList(); body != null; body = body.GetNext()) { if (body.GetUserData()) { temp = body.GetUserData() as Sprite; temp.x = body.GetPosition().x * PM; temp.y = body.GetPosition().y * PM; temp.rotation = body.GetAngle() * (180 / Math.PI); // radians to degrees } } } public function createWorld():void { var gravity:b2Vec2 = new b2Vec2(0, 9.8); var sleep:Boolean = true; world = new b2World(gravity, sleep); } public function createWall(_x:Number, _y:Number, _width:Number, _height:Number):b2Body { _x = _x + _width / 2; _y = _y + _height / 2; // Create Wall Sprite Using code var wallSprite:Sprite = new Sprite(); wallSprite.graphics.beginFill(0xe7d7c0, 1); wallSprite.graphics.drawRect( -_width / 2, -_height / 2 , _width, _height); wallSprite.graphics.endFill(); wallSprite.x = _x; wallSprite.y = _y; addChild(wallSprite); // Create body definition var bodyDef:b2BodyDef = new b2BodyDef(); bodyDef.userData = wallSprite; bodyDef.type = b2Body.b2_staticBody; bodyDef.position.Set( _x / PM, _y / PM); // Create body from world using bodyDef var body:b2Body = world.CreateBody(bodyDef); // Create shape var shape:b2PolygonShape = new b2PolygonShape(); shape.SetAsBox((_width / 2) / PM, (_height / 2) / PM); // Create fixtureDef giving shape var fixtureDef:b2FixtureDef = new b2FixtureDef(); fixtureDef.shape = shape; fixtureDef.restitution = 0.2; fixtureDef.friction = 1; fixtureDef.density = 0.5; // Pass the fixtureDef to the createFixture method in the body object body.CreateFixture(fixtureDef); return body; } public function createPlayer(_x:Number , _y:Number, _width:Number, _height:Number):b2Body { // Create car sprite var carSprite:Sprite = new Sprite(); carSprite.graphics.beginFill(0xafafaf, 1); carSprite.graphics.drawRect( -_width / 2, -_height / 2 , _width, _height); carSprite.graphics.endFill(); carSprite.x = _x; carSprite.y = _y; addChild(carSprite); // Create body definition var bodyDef:b2BodyDef = new b2BodyDef(); bodyDef.userData = carSprite; bodyDef.type = b2Body.b2_dynamicBody; bodyDef.position.Set(_x / PM, _y / PM); // Create body from world using bodyDef var body:b2Body = world.CreateBody(bodyDef); // Create shape var shape:b2PolygonShape = new b2PolygonShape(); shape.SetAsBox(_width / 2 / PM, _height / 2 / PM); // Create fixtureDef giving shape var fixtureDef:b2FixtureDef = new b2FixtureDef(); fixtureDef.shape = shape; fixtureDef.restitution = 0.2; fixtureDef.friction = 1; fixtureDef.density = 0.5; // Pass the fixtureDef to the createFixture method in the body object body.CreateFixture(fixtureDef); return body; } }