small JavaScript Box2D program without gravity has things moving anyway... why?

I have a small Box2D thing (using box2dweb.js), but despite setting gravity to (0,0), and no forces/impulse being imparted on any objects, the only dynamic shape I have in the scene moves when I start the draw loop. I have no idea why O_O

Would anyone know why http://pomax.nihongoresources.com/downloads/temp/box2d/physics.html has the "ball" moving after hitting start?

The relevant bits of code are:

// shortcut aliasses
var d = Box2D.Dynamics,
    v = Box2D.Common.Math,
    s = Box2D.Collision.Shapes;

var ball,
    gravity = new v.b2Vec2(0,0);
    world = new d.b2World(gravity, true);

// setup the world box
var setupWorldBox = function(worldbox) {
  var fixDef = new d.b2FixtureDef;
  fixDef.density = 0;
  fixDef.friction = 0;
  fixDef.restitution = 0;

  var bodyDef = new d.b2BodyDef;
  bodyDef.type = d.b2Body.b2_staticBody;
  bodyDef.position.x = worldbox.width/2;
  bodyDef.position.y = worldbox.height/2;
  fixDef.shape = new s.b2PolygonShape;
  fixDef.shape.SetAsBox(worldbox.width/2, worldbox.height/2);
  world.CreateBody(bodyDef).CreateFixture(fixDef);
}

// draw loop
var drawFrame = function() {
   world.Step(1/60,10,10);
   world.ClearForces();
   ball.update(); // only updates the ball's DOM element position
   requestAnimFrame(drawFrame);
};

// start the game
function start() {
  var worldParent = document.querySelector("#world");
  setupWorldBox(worldParent.getBoundingClientRect());
  ball = new Ball(worldParent, document.querySelector(".ball"), d,v,s, world);
  drawFrame();
}

For the main body, and the following code for defining the "ball":

var Ball = function(gamediv, element, d,v,s, world) {
  var pbbox = gamediv.getBoundingClientRect();
  var bbox = element.getBoundingClientRect();
  this.el = element;
  this.width = bbox.width;
  this.height = bbox.height;

  var bodyDef = new d.b2BodyDef;
  bodyDef.type = d.b2Body.b2_dynamicBody;

  var fixDef = new d.b2FixtureDef;
  fixDef.shape = new s.b2PolygonShape;
  fixDef.shape.SetAsBox(bbox.width/2, bbox.height/2);

  bodyDef.position.x = bbox.left - pbbox.left;
  bodyDef.position.y = bbox.top - pbbox.top;

  this.b2 = world.CreateBody(bodyDef);
  this.b2.CreateFixture(fixDef);
};

Ball.prototype = {
  el: null,
  b2: null,
  width: 0, height: 0,

  // Box2D position for the ball
  center: function() { return this.b2.GetWorldCenter(); },

  // update the DOM element based on Box2D position
  update: function() {
    var c = this.center();
    this.el.style.left = c.x + "px";
    this.el.style.top = c.y + "px";
  }
};

Ball.prototype.constructor = Ball;

Neither of these bits of code introduces forces, as far as I can tell, so if anyone knows why the coordinates for the ball change anyway, please let me know, so I can turn this into something useful instead of something confusing =)

Upvotes: 0

Views: 571

Answers (1)

It turns out my code was creating a solid object as game world, which meant Box2D was trying to perform collision resolution because the "ball" was located inside another solid object.

The solution (based on http://box2d-js.sourceforge.net but with box2dweb API calls) was this:

// setup the world box
var setupWorldBox = function(worldbox) {
  var worldAABB = new Box2D.Collision.b2AABB;
  worldAABB.lowerBound.Set(0,0);
  worldAABB.upperBound.Set(worldbox.width, worldbox.height);
  var gravity = new b2Vec2(0, 0);
  var doSleep = true;
  var world = new b2World(worldAABB, gravity, doSleep);
  [....]
}

Upvotes: 1

Related Questions