Win an Ipad
  Developer   Demos & Samples   Box2DCrates

Box2DCrates

Screenshot
Learn basic box2d functionality included in Moscrif. Box2d is a physical engine used for 2D games. Nintendo DS, Wii, several mobile platforms (including Android and iPhone) as well as most major operating systems also use the same engine.

Box2DCrates

To simplify development, Moscrif offers framework game 2D classes built from box2D native classes .Class PhysicsWorld is main class, which contains all other physics objects like bodies and joints. PhysicalWorld has same properties as real world like gravity on x and y axis, specified in object constructor or set by PhysicsWorld.setGravity method.


All objects interacting in the physics world are defined as body with different physical properties. Moscrif supports three types of bodies:

#static
Static body does not move under simulation and behaves as infinite mass. Static bodies can be moved manually by PhysicsBody.setPosition. A static body has zero velocity and does not collide with other static or kinematic bodies.

#kinematic
Kinematic body moves under simulation according to its velocity. Kinematic bodies do not respond to forces. They can be moved manually by the user, but normally a kinematic body is moved by setting its velocity. A kinematic body behaves as if it has infinite mass, but they do not collide with other static or kinematic bodies.

#dynamic
Dynamic body is fully simulated. It can be moved manually by PhysicsBody.setPosition, but normally they move according to forces. A dynamic body can collide with all body types and always has finite, non-zero mass. If you try to set the mass of a dynamic body to zero, it will automatically acquire a mass of one kilogram.


In Moscrif we can create body by PhysicsBody.addPolygonBody, or PhysicsBody. addCircleBody.


Joints are used to constrain bodies to the world or to each other. There are several different types of joints, with different behaviours. In our application, we use mouse joint to move crates to finger position. We create mouse joint using PhysicsWorld.createMouseJoint. MaxForce property is used to prevent violent reactions when multiple dynamic bodies interact and damping ratio is used to create a spring/damper effect similar to the distance joint.


Practically, this joint does not response directly to mouse or finger interaction. It allows setting position by b2MouseJoint.setTarget, where body tries to get while still interacting with other box2d bodies.


If device runs sample support accelerometer sensor, the gravity is adapted to real device position. For more information about sensors, see Sensors sample.


include "lib://box2d/physicsScene.ms" // create native application window
var app = new Moscrif.Window();
app._terminate = false; app.onStart = function()
{
    // creates paint used t draw information about fps
    this._paint = new Paint();
    this._paint.color = 0xff000000;
    this._paint.textSize = 15;     this._mouseJoint = null;     // creates physics world
    var xGravity = 0.;
    var yGravity = -9.8;
    var sleep = false;
    var enableCollisions = true;
    this._world = PhysicsScene.create(xGravity, yGravity, sleep, enableCollisions);     // load crates image into memory
    var imgBox = Bitmap.fromFile("app://box.png");     // creates paint for drawing of ground
    var paint = new Paint();
    paint.color = 0xaabbccdd;     // create ground
    var (width, height) = (System.width, 50);
    this._ground = this._world.addPolygonBody(null, #static, 0.0 /*density*/, 5.2/*friction*/, 0.3/*bounce*/, width, height);
    this._ground.setPosition(System.width/2, System.height - height/2);
    this._ground.onDraw = :sender, canvas :canvas.drawRect(-sender.width/2, -sender.height/2, sender.width/2, sender.height/2, paint);     // create walls
    (width, height) = (1, System.height);
    var leftMantinel = this._world.addPolygonBody(null, #static, 0.0/*density*/, 0.0/*friction*/, 1.0/*bounce*/, width, height);
    leftMantinel.setPosition(leftMantinel.width/2, System.height/2);
   
    (width, height) = (1, System.height);
    var rightMantinel = this._world.addPolygonBody(null, #static, 0.0/*density*/, 0.0/*friction*/, 1.0/*bounce*/, width, height);
    rightMantinel.setPosition(System.width - (rightMantinel.width/2), System.height/2);
   
    (width, height) = (System.width, 1);
    var topMantinel = this._world.addPolygonBody(null, #static, 0.0/*density*/, 0.0/*friction*/, 1.0/*bounce*/, width, height);
    topMantinel.setPosition(System.width/2, (topMantinel.height/2));     // create crates
    var (crateWidth, crateHeight) = (imgBox.width, imgBox.height);
    this._bodies = new Array();
    // set number of crates acording to screen width
    const cratesNum = System.width > 320 ? 12 : 4;
    for (var i = 0; i < cratesNum; i++) {
        var body = this._world.addPolygonBody(imgBox, #dynamic, 0.9 /*density*/, 0.3/*friction*/, 0.03/*bounce*/, imgBox.width, imgBox.height);
        body.setPosition((System.width / (5)) * (i%4 + 1) + rand(10), (System.height-(130+(i%5)*130) - rand(30)) - height/2, 0);
        this._bodies.push(body);
    }     if (Sensor.isAvailable(#acceleration)) {
        // create sensor
        var sensor = new Sensor(#acceleration, 40);
        sensor.onDataReceived = function(sender, timestamp, params)
        {
            // set gravity acording to device position
            this super._world.setGravity(-params[0] * 10., -params[1] * 10.);
        };
        // start senzor data receiving
        sensor.start();
    }
} app.onProcess = function()
{
    // return zero when quit requested
    if (this._terminate)
        return 0;
    // calculate physics
    this._world.step(1.0 / 40.0, 4, 8);
    this._world.clearForces();
    this.invalidate();
    return 1;
} app.onPointerPressed = function(sender, x, y)
{
    // if user cliked to quit button quit application
    if (y > (System.height - 50)) {
        app._terminate = true;
        return;
    }     this._mouseJoint = null;
    for(var body in this._bodies) {
        // calculate border of body
        var (bx, by) = body.getWorldCenter();
        var realBx1 = bx - body.width/2;
        var realBx2 = bx + body.width/2;
        var realBy1 = by - body.height/2;
        var realBy2 = by + body.height/2;
        // check if user cliked inside dthe body
        if ((realBx1 <= x && x <= realBx2) && (realBy1 <= y && y <=  realBy2)) {
            var mouseJointDef = { maxForce : 2500, frequencyHz : 10000, dampingRatio : 0.0,
                targetX : x / this._world.scale,
                targetY : (System.height-y) / this._world.scale
            };
            // crate mouse joint
            this._mouseJoint = this._world.createMouseJoint(this._ground, body, mouseJointDef, true);
        }
    } } app.onPointerDragged = function(sender, x, y)
{
    if (this._mouseJoint != null) {
        var b2y = (System.height-y) / this._world.scale;
        var b2x = x / this._world.scale;
        this._mouseJoint.setTarget(b2x, b2y);
    }
} app.onPointerReleased = function(sender, x, y)
{
    //destroy mouse joint when user release the crate
    if(this._mouseJoint != null)
        this._world.destroyJoint(this._mouseJoint);
    this._mouseJoint = null;
} app.onKeyPressed = function(sender, key)
{
    app._terminate = (key == #back || key == #end || key == #ok || key == #menu);
} app.onDraw = function(sender, canvas)
{
    // clear window using solid color
    canvas.clear(0xff999999);
    // draw physics world
    this._world.draw(canvas);
    // this._world.doDebugDraw(canvas);
    // draw infos
    canvas.drawText(String.printf("FPS: %.2f", System.avgFPS), 30, 50, app._paint);
    canvas.drawText("drag box, turn device or tap here to quit", 30, System.height - 30, app._paint);
} // initilaizes - allow FPS
app.init(true);
// runs main application object
app.run();

License

This article, along with any associated source codes and files, is licensed under The BSD License

 Bitmap graphics   Box2DCreates 
Write a Comment (0)
Subject
Please complete this mandatory field.
HTML Tags Not Allowed!
Comment
Please complete this mandatory field.