We’d love to hear from you. Whether you have a question that you’d like us to answer as part of our FAQ,  you’ve identified something that just doesn’t quite look right in one of our tutorials, you have a business opportunity or for any other reason, please use this simple form to contact us.

We’ll do our best to provide a prompt response.

Physics in Cocos Creator

Introduction

In this tutorial we are going to look at the basics of using the physics system built into Cocos Creator. The underlying physics engine used is the Box2D physics library. By using a physics engine, you can use simulation and mathematics to calculate the movement in your game world based on gravity, collisions and more

Physics in Cocos Creator

Just like in the previous tutorial, we define collision nodes that define the shapes of our various objects to the physics engine. We are going to create the following simple simulation:

Bowling Physics - Simple Simulation - Physics in Cocos Creator

Let’s start things off with creating the bowling ball. It’s a sprite I downloaded off the internet and created as a sprite node. I think attached a Rigid Body to it. Rigid Bodies are the heart of the physics simulation. These are the entities that the physics engine operates on.

Physics in Cocos Creator - Rigid Bodies

There are a few relevant settings here. Most important is type. In this case Dynamic, which means that this object is part of the physics simulation and in fact should be moved by the results of the physics calculations. Enabled Contact Listener is important to be selected if you want the collision callback to be called on this object’s script when a collision occurs.

We also need to define the physics shape of our object. This is nearly identical to the Collider Object we used earlier, but instead using special physics versions:

Special Physics

Be sure to use the Physics Component->Collider shapes and not the ones we used in the Collision tutorial. This is a painful mistake to make, trust me!

For our bowling ball, a Circle shape is a no-brainer. In addition to shapes there are some important physical properties you can define as part of the shape.

Physics Component -> Collider Shapes

Density is important, that’s mass * weight and determines how fast/hard your object moves in the world. Friction determines how “slippery” from icy to concrete, determines how two shapes interact if they slide across each other. Restitution is basically how “bouncy” your object is. A value of 0 will not bounce at all if a collision occurs, while 1 will bounce almost back to it’s starting point.

Next we need to turn physics on, which is done at the scene level. Attach the following script to your canvas or some other object in your scene:

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {
    onLoad () {
            cc.director.getPhysicsManager().enabled = true;
    }
}

Now let’s add some logic to our bowling ball. Attach the following script to your bowling ball object:

const {ccclass, property} = cc._decorator;

@ccclass
export default class BowlingBallController extends cc.Component {
    onLoad () {
        //this.getComponent(cc.RigidBody).enabledContactListener = true;
        this.node.on(cc.Node.EventType.MOUSE_DOWN,(event:cc.Event.EventCustom)=>{
            this.getComponent(cc.RigidBody).gravityScale = 0.8;          
            console.log("click");
        },this);
    }

    onBeginContact(contact, self, other) {
        this.getComponent(cc.AudioSource).play();
    }
    start () {
    }
}

This code listens for a mouse to be clicked on the bowling ball. In the properties for our ball we set the gravityScale to 0, so it was unaffected by gravity. In this code we turn gravity back on, which then causes our ball to start falling. I also have attached an audio source to ball, that plays a sound when a collision occurs. Notice the callback onBeginContact()? This is called when a collision between objects occurs. In this case we simply play our hit noise when a collision occurs. Once again you are passed in details of the object you collided with, as well as details of where the contact occurred in case you wanted to do additional calculations.

The rest of our scene is pretty straight forward, just giving us some objects to collide with:

Clipboard-Image_8

The pins are each just rigid bodies, but using Physics Polygon Colliders instead of circle colliders. Finally there is the floor, which is a simple node with a scaled Physics Box Collider attached. The biggest difference with this node is it’s stationary. We want it to be part of the physics simulation, but not affected by it. In other words, we want our ball and pins to hit the floor, but we don’t want the floor to move when hit. It is still created as a Rigid Body, but in this case Type is defined as Static:

Rigid Body

The other two types of Rigid Body are Kinematic and Animated. Animated is set up to work with the built in animation system, while Kinematic is for objects the user is meant to control directly. So instead of the physics simulation determining where the Kinematic object should move, code is instead used, and the physics engine responds to the changes. A Kinematic body is generally used for your character controller, where player input determines how the object should be moved.

With a Kinematic object, you can just move it around the scene normally, such as with the following code:

export default class KinematicController extends cc.Component {
    onKeyDown(e:cc.Event.EventCustom){
        switch(e.keyCode){
            case cc.KEY.right:
                this.node.x += 25;
                break;
                case cc.KEY.left:
                this.node.x -= 25;
                break;       
                case cc.KEY.up:
                this.node.y += 25;
                break;       
                case cc.KEY.down:
                this.node.y -= 25;
                break;                                                
        }
    }

    onLoad () {
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN,
            this.onKeyDown,this);
    }
}

When you run into other physics objects, they will respond accordingly. So a kinematic body is one whose position you control directly, but that will influence other physics objects in the simulation.

You can also move around Rigid Body objects, but you don’t do it by manipulating their position directly. Instead you can apply force and impulses to them and let the simulation engine do the work. So if you are working with a dynamic object, you can move it like this:

  case cc.KEY.right:
        this.getComponent(cc.RigidBody).applyForceToCenter(new cc.Vec2(10000,0),true);
        break;
        case cc.KEY.left:
        this.getComponent(cc.RigidBody).applyForceToCenter(new cc.Vec2(-10000,0),true);
        break;       
        case cc.KEY.up:
        this.getComponent(cc.RigidBody).applyLinearImpulse(new cc.Vec2(0,1000),new cc.Vec2(0.5,0.5),true);
        break;       
        case cc.KEY.down:
        this.getComponent(cc.RigidBody).applyLinearImpulse(new cc.Vec2(0,-1000),new cc.Vec2(0.5,0.5),true);
        break;

Detecting Collisions<<PreviousTable of ContentsNext>>Tilemaps

script ends --->