Search code examples
javascriptgame-physicsphaser-framework

Basic 2D pole-balancing setup in Phaser (Box2D)


Ignoring the task of actually balancing a pole by providing the appropriate forces at the appropriate times (that part's fine), does anyone have some basic guidance on how to setup the task of pole-balancing in Phaser? I have the Phaser-based Box2D plugin as well, if that makes it easier.

Basically I'm looking for the type of objects to create (e.g., bodies, joints), the creation/initialization process, and the process of applying forces in either direction. Doesn't matter to me that those forces are incorrect initially, I'm just not sure how to build the scene I want within Phaser.

I get the impression such things should be quite simple to do in Phaser, but it doesn't feel that way to me at present.


Solution

  • Using the Revolute Joint and Simple Force Box2D plugin examples as my starting point, it turns out it isn't too difficult at all:

    With a basic Phaser/Box2D setup from their examples (e.g., 800x600...), here is some code to drop into the create and the update methods. Basically I just create a static ground body, two dynamic bodies: cart and pole, and then use the revoluteJoint method to join the two dynamic bodies together.

    function create() {
    
        // Enable Box2D physics
        game.physics.startSystem(Phaser.Physics.BOX2D);
        game.physics.box2d.debugDraw.joints = true;
        game.physics.box2d.setBoundsToWorld();
        game.physics.box2d.gravity.y = 500;
    
        ground = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX, 575, 0); // game, sprite, cx, cy, density [static/kinematic/dynamic], world
        ground.setRectangle(800, 50, 0, 0, 0); // width, height, offsetx, offsety, angle (rads)
    
        cart = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX, 543);
        cart.setRectangle(60, 10, 0, 0, 0);
        cart.mass = 1;
    
        pole = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX, 495);
        pole.setRectangle(4, 100, 0, 0, 0);
        pole.mass = 0.1;
        pole.linearDamping = 4; // makes the pole fall slower (heavy air resistance)
    
        //bodyA, bodyB, ax, ay, bx, by, motorSpeed, motorTorque, motorEnabled, lowerLimit, upperLimit, limitEnabled
        game.physics.box2d.revoluteJoint(cart, pole, 0, -5, 0, 50);
    
        pole.angle = 5; // so it starts out falling to the right
    
        //Set up arrow keys for input
        cursors = game.input.keyboard.createCursorKeys();
    
        // track the angle of the pole
    
        game.add.text(5, 5, 'Pole balancing.', { fill: '#ffffff', font: '14pt Arial' });
        caption1 = game.add.text(5, 30, 'Angle: ' + pole.angle, { fill: '#dddddd', font: '10pt Arial' });
    }
    
    function update() {
    
        caption1.text = 'Angle: ' + pole.angle;
    
        if (cursors.left.isDown) {
            cart.applyForce(-5,0);
        }
    
        if (cursors.right.isDown) {
            cart.applyForce(5,0);
        }
    }