Box2DWeb_02之MouseControl

上一次我们创建了World和body并且看到了!之后的效果!现在我们来添加鼠标交互!

在box2d中没有直接提供对鼠标操作的事件的监听!

在box2d中为我们提供了一个mouseJoint来和其他body进行鼠标交互,我们都知道Joint是用来连接body与body的所以在我们的交互中还会出现另外一个body一个是我们点击的body而另一个则是我们系统给我们默认提供的一个body,world.GetGroundBody();就可以得到!

鼠标交互主要函数必须在什么mousedown啊mouseup之类的方法里面!

那既然要叫互,当我们点下的时候我么就必须得拿到点的是谁!

所以我们先从mouseDown看,当然记得给canvas注册监听 

    

function mouseDown(e){ 
//必须设置,才能在getBodyAtMouse中获取 

    mouseX = e.offsetX / drawScale;//把屏幕坐标转换为物理坐标
    mouseY = e.offsetY / drawScale;
    isMouseDown = true;
    document.addEventListener("mousemove", mouseMove, true);
    
    if(isMouseDown && (!mouseJoint)) {
        var body = getBodyAtMouse();//看看我们点的谁..并返回!
        if(body) {
           var md = new b2MouseJointDef();//创建主角——MouseJoint
           md.bodyA = world.GetGroundBody();
           md.bodyB = body;
           md.target.Set(mouseX, mouseY);
           md.collideConnected = true;
           md.maxForce = 300.0 * body.GetMass();
           mouseJoint = world.CreateJoint(md);
           body.SetAwake(true);
        };
     };
};

 所以当我们点下的时候我们做了两件事!

1.我们点的哪!根据那个哪找出点的谁也就是getBodyAtMouse方法的工作!找到了的话!确定我们不是什么都没点着! 然后呵呵!

2.创建mouseJoint并为其设置连接的两个body,bodyA和bodyB

现在我们看看 getBodyAtMouse

 function getBodyAtMouse() { 

    mousePVec = new b2Vec2(mouseX, mouseY);
    var aabb = new b2AABB();
    aabb.lowerBound.Set(mouseX - 0.001, mouseY - 0.001);
    aabb.upperBound.Set(mouseX + 0.001, mouseY + 0.001);
    
    // Query the world for overlapping shapes.

    selectedBody = null;
    world.QueryAABB(getBodyCallBack, aabb);
    return selectedBody;
 };

 根据点击的的位置确定一个范围Query;

这时候我们点到了,也知道点的谁!那就可以处理了!在move函数我们让这body跟随鼠标吧 

function mouseMove(e){
     mouseX = e.offsetX / drawScale;
     mouseY = e.offsetY / drawScale;
     
     if(mouseJoint) {
         if(isMouseDown) {
            mouseJoint.SetTarget(new b2Vec2(mouseX, mouseY));
      }     }}; 

 up的时候清场!

function mouseUp(e){
    document.removeEventListener("mousemove", mouseMove, true);
    isMouseDown = false;
    mouseX = 0;
    mouseY = 0;
    if(mouseJoint){
        world.DestroyJoint(mouseJoint);
        mouseJoint = null;
    }};  

So........

Your browser does not support the canvas element.

所有代码:

window.onload = init;
var world = new b2World(new b2Vec2(0,9.8), true),
bodyDef = new b2BodyDef(),
fixDef = new b2FixtureDef();
const drawScale =30,canvasHeight = canvasWidth = 500;
function init(){
var canvas = document.getElementById("stage");
canvas.addEventListener("mousedown",mouseDown,true);
canvas.addEventListener("mouseup",mouseUp,true);
createWorld();
createWall();
createBall(20,canvasWidth/2,canvasHeight/2);
};
function createWorld(){
var debug = new b2DebugDraw();
debug.SetSprite(document.getElementById("stage").getContext("2d"));//必须先设置context,后面才能设置ctx的线条宽度以及其他属性
debug.SetDrawScale(drawScale);
debug.SetFillAlpha(0.5);
debug.SetLineThickness(1.0);
debug.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
world.SetDebugDraw(debug);
setInterval(update, 1000/30);
};
function update(){
var timeStep = 1/60;
world.Step(timeStep,10,10);
world.ClearForces();
world.DrawDebugData();
};
function createWall(){
bodyDef.type = b2Body.b2_staticBody;
fixDef.density = 1.0;
    fixDef.friction = 0.5;
    fixDef.restitution = 0.6;
    fixDef.shape = new b2PolygonShape();
    //top
    bodyDef.position.Set(canvasWidth/2/drawScale,3/drawScale);
    fixDef.shape.SetAsBox(canvasWidth/2/drawScale, 3/drawScale);
world.CreateBody(bodyDef).CreateFixture(fixDef);
//bottom
bodyDef.position.Set(canvasWidth/2/drawScale,(canvasHeight-3)/drawScale);
world.CreateBody(bodyDef).CreateFixture(fixDef);
//left
bodyDef.position.Set(3/drawScale,canvasHeight/2/drawScale);
fixDef.shape.SetAsBox(3/drawScale,canvasHeight/2/drawScale);
world.CreateBody(bodyDef).CreateFixture(fixDef);
//right
bodyDef.position.Set((canvasWidth-3)/drawScale,canvasHeight/2/drawScale);
world.CreateBody(bodyDef).CreateFixture(fixDef);
};
function createBall(radius,x,y){
bodyDef.type = b2Body.b2_dynamicBody;
bodyDef.position.Set(x/drawScale,y/drawScale);
fixDef.shape = new b2CircleShape(radius/drawScale);
var ball = world.CreateBody(bodyDef);
ball.CreateFixture(fixDef);
return ball;
};
function getBodyAtMouse() {
    mousePVec = new b2Vec2(mouseX, mouseY);
    var aabb = new b2AABB();
    aabb.lowerBound.Set(mouseX - 0.001, mouseY - 0.001);
    aabb.upperBound.Set(mouseX + 0.001, mouseY + 0.001);
    
    // Query the world for overlapping shapes.
    selectedBody = null;
    world.QueryAABB(getBodyCallBack, aabb);
    return selectedBody;
 };
 function getBodyCallBack(fixture) {
    if(fixture.GetBody().GetType() != b2Body.b2_staticBody) {
       if(fixture.GetShape().TestPoint(fixture.GetBody().GetTransform(), mousePVec)) {
          selectedBody = fixture.GetBody();
          return false;
       }
    }
    return true;
 };
 
var mouseX,mouseY,isMouseDown,mouseJoint,mousePVec,selectedBody;
function mouseDown(e){
mouseX = e.offsetX / drawScale;
    mouseY = e.offsetY / drawScale;
isMouseDown = true;
    document.addEventListener("mousemove", mouseMove, true);
    
    if(isMouseDown && (!mouseJoint)) {
        var body = getBodyAtMouse();
        if(body) {
           var md = new b2MouseJointDef();
           md.bodyA = world.GetGroundBody();
           md.bodyB = body;
           md.target.Set(mouseX, mouseY);
           md.collideConnected = true;
           md.maxForce = 300.0 * body.GetMass();
           mouseJoint = world.CreateJoint(md);
           body.SetAwake(true);
        };
     };
};
function mouseMove(e){
mouseX = e.offsetX / drawScale;
     mouseY = e.offsetY / drawScale;
     
     if(mouseJoint) {
         if(isMouseDown) {
            mouseJoint.SetTarget(new b2Vec2(mouseX, mouseY));
      }
     }
};
function mouseUp(e){
document.removeEventListener("mousemove", mouseMove, true);
    isMouseDown = false;
    mouseX = 0;
    mouseY = 0;
    if(mouseJoint){
    world.DestroyJoint(mouseJoint);
    mouseJoint = null;
    }
};
posted @ 2012-03-12 18:23  _公孓℡  阅读(1068)  评论(0编辑  收藏  举报