我刚开始玩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();
}