I have to write a simulation of balls falling in a container for Android. First, I tried using Box2Dweb in a HTML5 canvas, but with 3 solid bodies and 50 balls, it performs really slow, even in desktop computer with Firefox (curiously, with Chrome it performs really well). Here is the live demo.
And here is the code.
var b2Vec2 = Box2D.Common.Math.b2Vec2
, b2BodyDef = Box2D.Dynamics.b2BodyDef
, b2Body = Box2D.Dynamics.b2Body
, b2FixtureDef = Box2D.Dynamics.b2FixtureDef
, b2Fixture = Box2D.Dynamics.b2Fixture
, b2World = Box2D.Dynamics.b2World
, b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape
, b2CircleShape = Box2D.Collision.Shapes.b2CircleShape
, b2DebugDraw = Box2D.Dynamics.b2DebugDraw
;
var world = new b2World(
new b2Vec2(0, 10) //gravity
, true //allow sleep
);
var fixDef = new b2FixtureDef;
fixDef.density = 1.0;
fixDef.friction = 0.5;
fixDef.restitution = 0.2;
var bodyDef = new b2BodyDef;
//create ground
var canvas = $('#canvas'),
offsetX = (canvas.width() / 30) / 4,
offsetY = (canvas.height() / 30) / 5; //center the machine on the screen.
bodyDef.type = b2Body.b2_staticBody;
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(5, 0.5);
bodyDef.position.Set(5 + offsetX, 10 + offsetY);
world.CreateBody(bodyDef).CreateFixture(fixDef);
fixDef.shape.SetAsBox(0.5, 7);
bodyDef.position.Set(0 + offsetX, 3 + offsetY);
world.CreateBody(bodyDef).CreateFixture(fixDef);
bodyDef.position.Set(10 + offsetX, 3 + offsetY);
world.CreateBody(bodyDef).CreateFixture(fixDef);
//create some objects
var numObjects = 50;
bodyDef.type = b2Body.b2_dynamicBody;
for(var i = 0; i < numObjects; ++i) {
fixDef.shape = new b2CircleShape(
0.6 //Math.random() + 0.1 //radius
);
bodyDef.position.x = Math.random() * 9 + offsetX;
bodyDef.position.y = Math.random() * 9 - 2;
world.CreateBody(bodyDef).CreateFixture(fixDef);
}
//setup debug draw
var debugDraw = new b2DebugDraw();
debugDraw.SetSprite(document.getElementById("canvas").getContext("2d"));
debugDraw.SetDrawScale(30.0);
debugDraw.SetFillAlpha(0.5);
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
world.SetDebugDraw(debugDraw);
var rate = 60;
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / rate);
};
})();
//update
(function update() {
requestAnimFrame(update);
world.Step(1 / rate, 10, 10);
world.DrawDebugData();
world.ClearForces();
})();
My question is, what if I write a native implementation using Android canvas (no the HTML5 one) and Box2D? Will I achieve a smooth movement for the balls?
And the hidden cuestion is: Is the performance so poor because of drawing or because of so many physical calculus? Usually, how much performance can I win going to native when there are physical calculus involved?