Real world catapult prototype using Box2D
Talking about Crush the Castle game, Actionscript 3, Box2D and Flash.
Learn cross platform HTML5 game development
Check my Gumroad page for commented source code, games and books.
This is an early attempt to simulate a real world catapult using Box2D.
Raw and uncommented code, but a lot of useful information about compound objects, revolute joints and motors.
This is what you’ll get:
Click with the mouse to shoot the ball.
And this is the source code:
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.*;
import Box2D.Dynamics.Joints.*;
public class main extends Sprite {
public var world:b2World=new b2World(new b2Vec2(0,10.0),true);
public var world_scale:int=30;
var arm_joint:b2RevoluteJointDef = new b2RevoluteJointDef();
var the_joint_itself:b2RevoluteJoint;
public function main():void {
debug_draw();
draw_box(250,400,500,30,false,"ground");
var catapult_body:b2BodyDef = new b2BodyDef();
catapult_body.position.Set(350/world_scale,200/world_scale);
catapult_body.type=b2Body.b2_dynamicBody;
var main_part:b2PolygonShape = new b2PolygonShape();
main_part.SetAsOrientedBox(125/world_scale, 20/world_scale, new b2Vec2(0,0),0);
var fixed_arm:b2PolygonShape = new b2PolygonShape();
fixed_arm.SetAsOrientedBox(20/world_scale, 60/world_scale, new b2Vec2(-80/world_scale,-40/world_scale),0);
var catapult_itself:b2Body=world.CreateBody(catapult_body);
catapult_itself.CreateFixture2(main_part,200);
catapult_itself.CreateFixture2(fixed_arm,200);
var catapult_arm:b2BodyDef = new b2BodyDef();
catapult_arm.allowSleep = false;
catapult_arm.position.Set(210/world_scale,110/world_scale);
catapult_arm.type=b2Body.b2_dynamicBody;
var arm_part:b2PolygonShape = new b2PolygonShape();
arm_part.SetAsOrientedBox(150/world_scale, 10/world_scale, new b2Vec2(0,0),0);
var stopper:b2PolygonShape = new b2PolygonShape();
stopper.SetAsOrientedBox(10/world_scale, 20/world_scale, new b2Vec2(-140/world_scale,-30/world_scale),0);
var catapult_arm_itself:b2Body=world.CreateBody(catapult_arm);
catapult_arm_itself.CreateFixture2(arm_part,1);
catapult_arm_itself.CreateFixture2(stopper,1);
arm_joint.enableMotor = true;
arm_joint.enableLimit = true;
arm_joint.Initialize(catapult_itself, catapult_arm_itself,new b2Vec2(0,0));
arm_joint.localAnchorA=new b2Vec2(-80/world_scale,-90/world_scale);
arm_joint.localAnchorB=new b2Vec2(60/world_scale,0);
the_joint_itself=world.CreateJoint(arm_joint) as b2RevoluteJoint;
the_joint_itself.SetMotorSpeed(1000);
the_joint_itself.SetLimits(-Math.PI,Math.PI/3);
the_joint_itself.SetMaxMotorTorque(1)
var cannonball:b2BodyDef= new b2BodyDef();
cannonball.position.Set(90/world_scale, 90/world_scale);
cannonball.type=b2Body.b2_dynamicBody;
var ball:b2CircleShape=new b2CircleShape(10/world_scale);
var the_cannonball_itself:b2Body=world.CreateBody(cannonball);
the_cannonball_itself.CreateFixture2(ball,20);
addEventListener(Event.ENTER_FRAME, update);
stage.addEventListener(MouseEvent.CLICK,fire);
}
public function fire(e:MouseEvent):void {
the_joint_itself.SetMaxMotorTorque(10000)
}
public function draw_box(px,py,w,h,d,ud):void {
var ground:b2BodyDef= new b2BodyDef();
ground.position.Set(px/world_scale, py/world_scale);
if (d) {
ground.type=b2Body.b2_dynamicBody;
}
var my_box:b2PolygonShape = new b2PolygonShape();
my_box.SetAsBox(w/2/world_scale, h/2/world_scale);
var my_fixture:b2FixtureDef = new b2FixtureDef();
my_fixture.shape=my_box;
var the_ground_itself:b2Body=world.CreateBody(ground);
the_ground_itself.SetUserData(ud);
the_ground_itself.CreateFixture(my_fixture);
}
public function debug_draw():void {
var debug_draw:b2DebugDraw = new b2DebugDraw();
var debug_sprite:Sprite = new Sprite();
addChild(debug_sprite);
debug_draw.SetSprite(debug_sprite);
debug_draw.SetDrawScale(world_scale);
debug_draw.SetFlags(b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit);
debug_draw.SetFillAlpha(0.5);
world.SetDebugDraw(debug_draw);
}
public function update(e:Event):void {
world.Step(1/30,10,10);
world.ClearForces();
world.DrawDebugData();
}
}
}
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.