package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
import Box2D.Dynamics.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
import Box2D.Dynamics.Joints.*;
public class Main extends Sprite {
private var world:b2World=new b2World(new b2Vec2(0,10),true);
private var worldScale:Number=30;
private var hero:b2Body;
private var distanceJoint:b2DistanceJoint;
private var isHooked:Boolean=false;
public function Main() {
// this is the ground
addBox(320,480,640,20,b2Body.b2_staticBody);
// let's add some random stuff
for (var i:Number=1; i<=12; i++) {
addBox(Math.random()*600+20,Math.random()*300,Math.random()*30+15,Math.random()*30+15,b2Body.b2_staticBody);
}
// and finally the hero
hero=addBox(320,460,20,20,b2Body.b2_dynamicBody);
addEventListener(Event.ENTER_FRAME,update);
stage.addEventListener(MouseEvent.MOUSE_DOWN,fireHook);
stage.addEventListener(MouseEvent.MOUSE_UP,releaseHook);
debugDraw();
}
private function fireHook(e:MouseEvent):void {
// when firing the hook, let's remove old joints, if any
if (distanceJoint) {
world.DestroyJoint(distanceJoint);
}
// checking the body under the mouse
world.QueryPoint(queryCallback,new b2Vec2(mouseX/worldScale,mouseY/worldScale));
}
private function queryCallback(fixture:b2Fixture):Boolean {
var touchedBody:b2Body=fixture.GetBody();
if (touchedBody.GetType()==b2Body.b2_staticBody) {
// if I have a body under the mouse, I create a distance joint between the hero and mouse position
var distanceJointDef:b2DistanceJointDef=new b2DistanceJointDef();
distanceJointDef.Initialize(hero,touchedBody,hero.GetWorldCenter(),new b2Vec2(mouseX/worldScale,mouseY/worldScale));
distanceJointDef.collideConnected=true;
distanceJoint=world.CreateJoint(distanceJointDef) as b2DistanceJoint;
isHooked=true;
}
return false;
}
private function releaseHook(e:MouseEvent):void {
// if I release the mouse, I destroy the distance joint
if (distanceJoint) {
world.DestroyJoint(distanceJoint);
}
}
private function manageHook():void{
// as long as the hook is active, I shorten a bit joint distance
if (isHooked) {
// BODY MUST BE AWAKE!!!!!!
hero.SetAwake(true)
distanceJoint.SetLength(distanceJoint.GetLength()*0.99);
}
}
private function addBox(pX:Number,pY:Number,w:Number,h:Number,bodyType:Number):b2Body {
var bodyDef:b2BodyDef=new b2BodyDef();
bodyDef.position.Set(pX/worldScale,pY/worldScale);
bodyDef.type=bodyType;
var polygonShape:b2PolygonShape=new b2PolygonShape();
polygonShape.SetAsBox(w/2/worldScale,h/2/worldScale);
var fixtureDef:b2FixtureDef=new b2FixtureDef();
fixtureDef.shape=polygonShape;
fixtureDef.density=1;
fixtureDef.restitution=0.4;
fixtureDef.friction=0.5;
var body:b2Body=world.CreateBody(bodyDef);
body.CreateFixture(fixtureDef);
return body;
}
private function debugDraw():void {
var debugDraw:b2DebugDraw=new b2DebugDraw();
var debugSprite:Sprite=new Sprite();
addChild(debugSprite);
debugDraw.SetSprite(debugSprite);
debugDraw.SetDrawScale(worldScale);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit);
debugDraw.SetFillAlpha(0.5);
world.SetDebugDraw(debugDraw);
}
private function update(e:Event):void {
world.Step(1/30, 10, 10);
manageHook();
world.ClearForces();
world.DrawDebugData();
}
}
}
0 comentários:
Postar um comentário