box2dweb初学者:无法通过单击画布来模拟添加的夹具

时间:2012-07-20 02:32:11

标签: javascript box2d

我刚开始玩box2dweb,现在遇到一个让我感到难过的问题。

我有一个带有“地面”静态夹具的基本模拟和一些代码,允许我在我点击它的位置向画布添加形状(现在只是圆圈)。

我的代码正在工作,因为我可以根据需要在画布中添加尽可能多的圆圈,并将它们绘制在画布上。

然后我有一个按钮,通过进入步循环开始模拟。我希望当我点击按钮时,圆圈会落到“地面”并最终停下来,从而结束模拟。

问题在于,一旦我开始模拟,下一帧就会完全删除场景中的所有灯具。但是,如果我开始在场景中使用圆圈(不是通过点击添加,而是通过创建世界和地面的初始化函数添加),并且我开始模拟,它会按预期运行:圆圈以某种速率下降并且停在“地面”上。

我正在使用相同的函数addCircle()在场景初始化时或者当我点击画布时添加圆圈,所以看起来代码很好。

// this function is called by the canvas onclick
function addShape(e) {
    var shape = $('input:radio[name=shape]:checked').val();
    var offset = $("#c").offset();

    if (shape == "circle") {
        addCircle((e.pageX - offset.left) / SCALE,
                  (e.pageY - offset.top) / SCALE,
                  $("#dimen").val());
    }
    gWorld.DrawDebugData();
}

// same function is used by the above handler and also to set up a circle
// in the initial scene, however when added via click, the simulation
// breaks (all objects disappear in the next frame)
function addCircle(x, y, r) {
    var fixDef = new b2FixtureDef;
    fixDef.density = 1.0;
    fixDef.friction = 0.5;
    fixDef.restitution = 0.2;

    var bodyDef = new b2BodyDef;
    bodyDef.type = b2Body.b2_dynamicBody;
    bodyDef.position.x = x;
    bodyDef.position.y = y;

    fixDef.shape = new b2CircleShape(r);
    gWorld.CreateBody(bodyDef).CreateFixture(fixDef);
}

// called when a button to start the simulation is clicked
function startSimulation() {
    gWorld.SetGravity(new b2Vec2(0, parseInt($("#gravity").val())));
    gStopped = false;
    requestAnimFrame(update);
}

// this is the main step loop
function update() {
    if (!gStopped) {

    gWorld.Step(
           1 / 60   //frame-rate
        ,  10       //velocity iterations
        ,  10       //position iterations
    );

    gWorld.DrawDebugData();
    gWorld.ClearForces();

    var keepGoing = true;
    for (var b = gWorld.GetBodyList(); keepGoing && b; b = b.m_next) {
        if (! b.IsAwake()) {
            keepGoing = false;
        }
    }
    if (keepGoing) {
        requestAnimFrame(update);
    }
}

function init() {
    gWorld = new b2World(
        new b2Vec2(0, parseInt($("#gravity").val())),
        true);

    var fixDef = new b2FixtureDef;
    fixDef.density = 1.0;
    fixDef.friction = 0.5;
    fixDef.restitution = 0.2;

    //create ground
    var bodyDef = new b2BodyDef;
    bodyDef.type = b2Body.b2_staticBody;
    bodyDef.position.x = $("#c").width() / 2 / SCALE;
    bodyDef.position.y = $("#c").height() / SCALE;

    fixDef.shape = new b2PolygonShape;
    fixDef.shape.SetAsBox((600 / SCALE) / 2, (10/SCALE) / 2);
    gWorld.CreateBody(bodyDef).CreateFixture(fixDef);

    //setup debug draw
    var debugDraw = new b2DebugDraw();
    debugDraw.SetSprite(document.getElementById("c").getContext("2d"));
    debugDraw.SetDrawScale(SCALE);
    debugDraw.SetFillAlpha(0.3);
    debugDraw.SetLineThickness(1.0);
    debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
    gWorld.SetDebugDraw(debugDraw);

    // this circle is simulated correctly
    addCircle(1,1,1);

    gWorld.DrawDebugData();
}

2 个答案:

答案 0 :(得分:2)

我发现问题出现在以下几行:

$("#dimen").val()

当我将其更改为以下内容时,模拟开始正常运行:

parseFloat($("#dimen").val())

答案 1 :(得分:1)

Box2DWeb严重缺乏文档,一直在打破它。想出了一些基本的工作流程,在这里发表了关于它的博客http://box2dinabox.blogspot.in/。希望你会发现它有用:)