Create a car with Phaser


How to create a simple car with the open source html5 game engine “Phaser“? Phaser uses the P2 physics engine to create physical accurate objects. Based on this example from the P2 physics page, I created a similar car in phaser. I don’t want to copy the same car, I rather want to understand how, why and when it works.
Here are the results, just the basic spring behavior with a constraint applied, as well as the full car. During the process I also created some code for better visual debugging, drag and drop, and a small endless level with generated jumps. Most of the code is uncommented, and to keep things clear and simple, it will not be discussed in this post. If you are interested in the full code, please leave a comment.

 

springs

Phasers P2 spring object has a few options like stiffness, damping and restLength. Check the documentations here. These values define the spring and how it effects the objects attached to it. The spring is basically not locked in any axis, which will let the objects bounce in every direction. To avoid this behavior we add a PrismaticConstraint to the same objects that the spring is attached to. This constraint locks the x or y movement, as well as upper and lower limits of the spring.
The example below demonstrates the behavior of a spring attached to a fixed point and a dynamic object like a wheel. A constraint is added to the fixed point and the dynamic object as well, to ensure that the spring is locked in the x direction and limit the y movement of the spring .

CG_wheel = game.physics.p2.createCollisionGroup(); //COLLISION GROUP
    
        game.physics.p2.updateBoundsCollisionGroup(); //UPDATE COLLISION BOUND FOR GROUPS
    
        //ADD BASE
        base = game.add.sprite(w/2, 100);
        game.physics.p2.enable(base,true, true);
        base.body.setRectangle(150,50);
        base.body.static = true;
        base.body.setCollisionGroup(CG_wheel);
    
        //ADD WHEEL
        wheel = game.add.sprite(w/2, 200); //FRONT WHEEL
        game.physics.p2.enable(wheel,true, true);
        wheel.body.setCircle(40);
        wheel.body.mass = 1;
        wheel.body.setCollisionGroup(CG_wheel);
        
    
        //ADD SPRING
        //Spring(world, bodyA, bodyB, restLength, stiffness, damping, worldA, worldB, localA, localB)
        spring = game.physics.p2.createSpring(base,wheel, 100, 10, 1,null,null,[0,0],null);
        
        //ADD CONSTRAINT
        //PrismaticConstraint(world, bodyA, bodyB, lockRotation, anchorA, anchorB, axis, maxForce)
        constraint = game.physics.p2.createPrismaticConstraint(base,wheel, false,[0,0],[0,0],[0,1]);
        //SET LIIMITS
        constraint.lowerLimitEnabled=constraint.upperLimitEnabled = true;
        constraint.upperLimit = -0.1;
        constraint.lowerLimit = -10;

It’s a fairly simple set up. Add physic bodies as usual, put them in the same collision group so they can not collide together. If you create collision groups you need to define later which objects collide with this collision group, otherwise it won’t collide with anything.
Once the objects are created we attach a spring to them, define bodyA, bodyB, restLength, stiffness, damping and offsets.

 //Spring(world, bodyA, bodyB, restLength, stiffness, damping, worldA, worldB, localA, localB)
 spring = game.physics.p2.createSpring(base,wheel, 100, 10, 1,null,null,null,null);

To lock the springs movement in an axis and add upper and lower limits, we add a prismatic constraint. We attach the constraint to the same objects as the spring. The value “axis” defines the lock, [1,0] locks to x direction, [0,1] locks to y direction. To create the limit, we need to set the limits to true, and add values to it.

 //PrismaticConstraint(world, bodyA, bodyB, lockRotation, anchorA, anchorB, axis, maxForce)
 constraint = game.physics.p2.createPrismaticConstraint(base,wheel, false,[0,0],[0,0],[0,1]);

 //SET LIIMITS
 constraint.lowerLimitEnabled=constraint.upperLimitEnabled = true;
 constraint.upperLimit = -0.1;
 constraint.lowerLimit = -10;

 

the car

The car is based on the same concept as the spring above, there are just two of them with two springs and two constraints. The springs and constraints are offset from the center with the same amount, one is the front wheel and one is the back wheel.
This demo features a endless level, and enables drag & drop to the car. Click the window and Use arrow keys to drive the car.

carBody = game.add.sprite(100, 100);; //CARBODY
    wheel_front = game.add.sprite(140, 130); //FRONT WHEEL
    wheel_back = game.add.sprite(60, 130);; //BACK WHEEL 
    CG_car = game.physics.p2.createCollisionGroup(); //CAR GROUP
    
    game.physics.p2.updateBoundsCollisionGroup(); //UPDATE COLLISION BOUND FOR GROUPS
    
    game.physics.p2.enable([wheel_front, wheel_back,carBody]); //ENABLE PHYSICS FOR THESE OBJECTS
    
    
        //DEFINE CAR BODY
        carBody.body.setRectangle(100,30);
        carBody.body.debug = true;
        carBody.body.mass = 1;
        carBody.body.setCollisionGroup(CG_car);
    
        //DEFINE FRON WHEEL
        wheel_front.body.setCircle(20);
        wheel_front.body.debug = true;
        wheel_front.body.mass = 1;
        wheel_front.body.setCollisionGroup(CG_car);
    
        //DEFINE BACK WHEEL
        wheel_back.body.setCircle(20);
        wheel_back.body.debug = true;
        wheel_back.body.mass = 1;
        wheel_back.body.setCollisionGroup(CG_car);
    
        //ADD SPRINGS
        //Spring(world, bodyA, bodyB, restLength, stiffness, damping, worldA, worldB, localA, localB)
    var spring = game.physics.p2.createSpring(carBody,wheel_front, 70, 150, 50,null,null,[30,0],null);
    var spring_1 = game.physics.p2.createSpring(carBody,wheel_back, 70, 150,50,null,null,[-30,0],null);
        
        //ADD CONSTRAINTS
        //PrismaticConstraint(world, bodyA, bodyB, lockRotation, anchorA, anchorB, axis, maxForce)
    var constraint = game.physics.p2.createPrismaticConstraint(carBody,wheel_front, false,[30,0],[0,0],[0,1]);
        
        //SET LIMITS
        constraint.lowerLimitEnabled=constraint.upperLimitEnabled = true;
        constraint.upperLimit = -1;
        constraint.lowerLimit = -8;    
    var constraint_1 = game.physics.p2.createPrismaticConstraint(carBody,wheel_back, false,[-30,0],[0,0],[0,1]);
        
        //SET LIMITS
        constraint_1.lowerLimitEnabled=constraint_1.upperLimitEnabled = true;
        constraint_1.upperLimit = -1;
        constraint_1.lowerLimit = -8;

This is the code for the car, as simple as the code from the spring. All the objects are in the same collision group and physics are enabled. The wheels and the inherent spring and constraint are offset from the center to create a front and a back wheel. Make sure that the objects are created nearly at the position where they will rest with the spring applied, otherwise it may jump and bounce around until it will rest at this position.

 

conclusion

This is the most basic car with phasers P2 physics engine. A car made out of 42 lines of code is awesome. Even if it was a bit fiddly to get all the values right, or as good as possible, to create a feel of driving a car. There might be other solutions to create a car also more complex cars with more values to play with. This one is simple and cost efficient, it will work on mobile devices as well.
In comparison to Box2d, I guess its a bit easier to understand the code, but it has no built in visual debugging for constraint and springs. Which makes it sometimes hard to see whats going on and why. The P2 physics engine is already built in to phaser and they work well together, so there is no need for Box2d anyway.