Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

How do I import and attach a PNG or GIF to a shape in Box2dWeb?

The best resource I could find online is at: http://www.jeremyhubble.com/box2d.html

However, this "tutorial" doesn't give much explanation about how images are actually used. So it is clearly possible, but I can't get the userData trick to work.

share|improve this question
add comment

2 Answers

up vote 9 down vote accepted

You are generally responsible for rendering the state of your box2d world - the "userData trick" you refer to is not really to do with the box2d framework.

userData is a placeholder for arbitrary data that you want to associate to a body. This could be anything - a string, function, object, etc. This data is typically used to help you render your world during the update loop, which is exactly what the resource you linked to does - If you look at the processObjects function it uses the imgsrc value to create an Image object and draws it onto the canvas at the correct location. (This isn't really a good idea because the image is created once per object per iteration - I would suggest it should only be created once)

Here's a quick sample that shows how you can use a PNG to represent a box2d object - you'll need an 50x50px image called "image.png" and the box2web javascript file from the project site in the same folder as the html.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <canvas id="canvas" width="1024" height="700" />

    <!-- Get this from the box2dweb project site -->
    <script type="text/javascript" src="Box2dWeb-2.1.a.3.min.js"></script>

    <script type="text/javascript">
    var CANVAS_WIDTH = 1024, CANVAS_HEIGHT = 700, SCALE = 30;

    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
            , b2MassData = Box2D.Collision.Shapes.b2MassData
            , b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape
            , b2CircleShape = Box2D.Collision.Shapes.b2CircleShape
            , b2DebugDraw = Box2D.Dynamics.b2DebugDraw;

    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");

    var world = new b2World(new b2Vec2(0, 2), true);

    // Create some objects in the world
    var fixDef = new b2FixtureDef();
    fixDef.density = 1.0;
    fixDef.friction = 0.5;
    fixDef.restitution = 1;
    var bodyDef = new b2BodyDef();

    for (var i = 0; i < 40; i++) {
        bodyDef.type = b2Body.b2_dynamicBody;
        bodyDef.position.Set((Math.random() * 400) / SCALE, (Math.random() * 400) / SCALE);
        bodyDef.linearVelocity.Set((Math.random() * 12) + 2, (Math.random() * 12) + 2);

        fixDef.shape = new b2PolygonShape();
        fixDef.shape.SetAsBox(25 / SCALE, 25 / SCALE);
        world.CreateBody(bodyDef).CreateFixture(fixDef);
    }

    // This is where you load the image data - make it a 50px x 50px image
    // You should use some sort of pre-loader to make sure the image is loaded prior to 
    // using it.
    var image = new Image();
    image.src = "image.png";

    // Set up the game loop - you might want to look into using window.requestAnimationFrame
    // or some variation of that.
    window.setInterval(gameLoop, 1000 / 60);

    function gameLoop() {
        // Update the box2d world
        world.Step(1 / 60, 8, 3);
        world.ClearForces();

        context.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);

        for (b = world.GetBodyList() ; b; b = b.GetNext()) {
            if (b.GetType() == b2Body.b2_dynamicBody) {
                var pos = b.GetPosition();

                context.save();
                context.translate(pos.x * SCALE, pos.y * SCALE);
                context.rotate(b.GetAngle());
                context.drawImage(image, -25, -25);
                context.restore();
            }
        }
    }

    </script>
</body>
</html>

Hope that helps!

share|improve this answer
1  
You are a god! I really appreciate your help. This gives me a great starting point and moving forward I think Cocos2d may be the best solution for a more advanced project. –  VinLucero Apr 25 '12 at 21:29
    
I read several tutorials, and reverse engineered so many box2d examples when all it took to learn was play with your short and simple code. –  hustlerinc Jul 24 '12 at 3:44
    
Glad I could help! –  Mike Goatly Jul 24 '12 at 9:32
add comment

Maybe this can help too. Have a look. http://codingowl.com/readblog.php?blogid=134

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.