Sweshi's Tutorials

Cocoos Creator Mind Your Step 3D Game Tutorial

The Player Script

Prepare your mind, this one will be a bit code heavy. To start, double click and open the "PlayerScript" that we created. Open it up for editing, we want to add some code for the jumping logic.

import { _decorator, Component, input, Input, EventMouse } from 'cc'; const { ccclass, property } = _decorator; @ccclass("PlayerController") export class PlayerController extends Component { // check if we should jump or not private _startJump: boolean = false; // step count private _jumpStep: number = 0; start () { // switching on the mouse event listener when we click //and release the mouse buttons input.on(Input.EventType.MOUSE_UP, this.onMouseUp, this); } //function to run because of mouse event onMouseUp(event: EventMouse) { } update(dt: number): void { if( this._startJump){ // Handle branching logic of jump } } }

we have added the variable " private _startJump: boolean = false;" so that we are able to check whether the player can jump or not. Depending on whether the player is already jumping or not we might disable the player from jumping.

we have include the variable private _jumpStep: number = 0; because the jumps can either be with 1 or 2 steps so we need a variable to store how many spaces the player jumps.

In the start() function that runs when the game is starting, we included an event listener for the mouse input.on(Input.EventType.MOUSE_UP, this.onMouseUp, this);. this makes sure that we pick up any mouse up events and calls the "onMouseUp" function to do something.

That is the purpose of creating the "onMouseUp()" function after the start() function. later we will put some logic here.

The update() function runs every frame and is good for things that have to happen every frame. For now we include an if statement if( this._startJump){ // Handle branching logic of jump }. This checks that the player's start jump variable is true. If it is true then we can jump. The code that will follow will enable the player to jump, if not true then the player will not jump.

Add some additional variable after the "priavate:_jumpStep:number = 0;" variable. Add the following variables.

// Whether received jump command private _startJump: boolean = false; // The jump step count private _jumpStep: number = 0; // Current jump time private _curJumpTime: number = 0; // Total jump time private _jumpTime: number = 0.5; // current jump speed private _curJumpSpeed: number = 0; // current position of the private _curPos: Vec3 = new Vec3(); // The difference of the current frame movement position during each jump private _deltaPos: Vec3 = new Vec3(0, 0, 0); // Target position of the character private _targetPos: Vec3 = new Vec3();

The variables are self explained with the comments. _curPos is a vector 3 which will store the coordinates of the player's current position while the _targetPos will store the calculated position the player should go to after jumping.

Mouse Clicks

Since we have an event listener for in the start and have an empty function to be called once the mouse buttons are clicked and released, we just need to add some code for determing which mouse button was released so go to the "onMouseUp()" function and update it as follows;

onMouseUp(event: EventMouse) { if (event.getButton() === 0) { //jump by one step this.jumpByStep(1); } else if (event.getButton() === 2 ) { //jump by two steps this.jumpByStep(2); } }

The "event.getButton()===0" is true if the left button was clicked and released while the "event.getButton()===2" is true if the right mouse button was clicked and released. So using this if statement we can tell which mouse button the user interacted with and decide how much to jump.

We will create a separate function for running the jump code. We will call this function "jumpByStep()" and it will be recieving a number, 1 or 2. If the user clicked on the left mouse button, we shall pass a 1 if they clicked on the right mouse button, we shall pass a 2. The "jumpByStep" function will receive either numbers and calculate where to jump.

We simply send the number of steps to jump by when calling the function "jumpByStep(1)" or "jumpByStep(2)" based on left or right mouse clicks.

//recieve 1 or 2 depending on the mouse button clicked jumpByStep(step: number) { //check that if we are already jumping if (this._startJump) { return; } //Change the state of jumping to true so that //no other jump can occur until this one is done this._startJump = true; // Jump steps will be recieved from the onMouseUp // step is 1 or 2 depending on the mouse button clicked this._jumpStep = step; // Reset the jump time to 0 this._curJumpTime = 0; //calculate jump speed of player //divide the number of steps (1 or 2) by the amount of time to jump this._curJumpSpeed = this._jumpStep / this._jumpTime; //Get the current x,y and z position of the player this.node.getPosition(this._curPos); //calculate the new position for the player to jump to //target position = current position + steps Vec3.add(this._targetPos, this._curPos, new Vec3(this._jumpStep, 0, 0)); }

As can be seen from the comments the "jumpByStep" function will only run if _startJump is false. If it is true, it means the player is already jumping so we return to come out of the function. If it is false, we continue to calculate the jump action but first we set the _startJump to true so that the user is prevented from jumping if the user clicks on the mouse buttons before the jump is completed.

We then collect the number of steps the user will jump by from the function parameters and then we resent the jump tim e to 0. we also set the jump speed by dividing the number of steps (1 or 2) by the jump time.

We get the position of the player and add the number of steps to have a new position the player should land on after the jump

Complete PlayerController script
import { _decorator, Component, input, Input, EventMouse, Vec3 } from 'cc'; const { ccclass, property } = _decorator; @ccclass("PlayerController") export class PlayerController extends Component { // Whether received jump command private _startJump: boolean = false; // The jump step count private _jumpStep: number = 0; // Current jump time private _curJumpTime: number = 0; // Total jump time private _jumpTime: number = 0.5; // current jump speed private _curJumpSpeed: number = 0; // current position of the private _curPos: Vec3 = new Vec3(); // The difference of the current frame movement position during each jump private _deltaPos: Vec3 = new Vec3(0, 0, 0); // Target position of the character private _targetPos: Vec3 = new Vec3(); start () { // Your initialization goes here. input.on(Input.EventType.MOUSE_UP, this.onMouseUp, this); } onMouseUp(event: EventMouse) { if (event.getButton() === 0) { //jump by one step this.jumpByStep(1); } else if (event.getButton() === 2 ) { //jump by two steps this.jumpByStep(2); } } jumpByStep(step: number) { if (this._startJump) { return; } this._startJump = true; this._jumpStep = step; this._curJumpTime = 0; this._curJumpSpeed = this._jumpStep / this._jumpTime; this.node.getPosition(this._curPos); Vec3.add(this._targetPos, this._curPos, new Vec3(this._jumpStep, 0, 0)); } update(dt: number): void { if( this._startJump){ } } }

The only thing left now is to complete the logic for jumping in the update script , we can then go to the "update()" method and write the code for actually making the jump

update (deltaTime: number) { //we want to only jump if the _startJump is true if (this._startJump) { //we add the delta time to the jump time this._curJumpTime += deltaTime; // if the current jump time is more than what we have allocated then we stop the jump //meaning we have already jumped if (this._curJumpTime > this._jumpTime) { // end jump // force the player to the target position this.node.setPosition(this._targetPos); // mark the end of the jump by changing _startJump to false this._startJump = false; } else { // otherwise if we are still jimping // we tween so that we have a smooth jump ing animation // Get the current position this.node.getPosition(this._curPos); // calculate the length of this frame that should be displaced this._deltaPos.x = this._curJumpSpeed * deltaTime; // add the current position to the length of the displacement Vec3.add(this._curPos, this._curPos, this._deltaPos); // set the position after displacement this.node.setPosition(this._curPos); } } }

A number of things are going on in the update but the first thing we do is check if we can actually jump by checking if _startJump is true.

  • We have to add the delta time to our current jump time value so that its updated.
  • The if else block that follows is then about checking whether the player is still jumping or is done jumping. The if section assumes the player is done jumping because the time to jump has elapsed so we make sure the player is positioned where they should be after the jump
  • The else block assumes we still have time to jump and are still jumping so we tween. Tweening helps us create a smooth movement by generating intermediate frames to have a more natural looking effect.
  • To tween,
    • We get the current position of the player
    • We calculate the x position the player should land on by multiplying the jump speed to the delta time. This gives us the _deltaPos.x which is the position the player should will be at after the jump.
    • We then add this _deltaPos to the _curPos. This is an addition of where the player is plus where they are supposed to be. The value is then stored as the current position of the player.
    • Lastly, the player is then moved to that calculated position.

Now click on the "Player" node in the node heirarchy. Go to the inspector on the right side and click on the "Add Component" button. Search for "PlayerController" and click on it. This will add the script to the node and run the code for this node.

Cocos Creator 3D Tutorial: Mind Your Step  -  adding the script

Next, click on the "Main Camera" in the node heirarchy and go to the inspector. Change the position on the Z axis to 13

Cocos Creator 3D Tutorial: Mind Your Step  -  Main Camera in inpector.

Once this is done. we just need to change the camera clear colour to some blueish colour. So underneath the Node, there will be a cc.Camera component still in the inspector of the camera. Click on the "Clear Color" and change it to "#325AFF".

Cocos Creator 3D Tutorial: Mind Your Step  - camera colour.

To run the project, click on the preview in browser and click the play button as shown in the figure below.

Cocos Creator 3D Tutorial: Mind Your Step  - preview in browser.

You should be able to make the player jump by using the left or right mouse button releases.

Complete PlayerController Script
import { _decorator, Component, input, Input, EventMouse, Vec3 } from 'cc'; const { ccclass, property } = _decorator; @ccclass("PlayerController") export class PlayerController extends Component { // Whether received jump command private _startJump: boolean = false; // The jump step count private _jumpStep: number = 0; // Current jump time private _curJumpTime: number = 0; // Total jump time private _jumpTime: number = 0.5; // current jump speed private _curJumpSpeed: number = 0; // current position of the private _curPos: Vec3 = new Vec3(); // The difference of the current frame movement position during each jump private _deltaPos: Vec3 = new Vec3(0, 0, 0); // Target position of the character private _targetPos: Vec3 = new Vec3(); start () { // Your initialization goes here. input.on(Input.EventType.MOUSE_UP, this.onMouseUp, this); } onMouseUp(event: EventMouse) { if (event.getButton() === 0) { //jump by one step this.jumpByStep(1); } else if (event.getButton() === 2 ) { //jump by two steps this.jumpByStep(2); } } jumpByStep(step: number) { if (this._startJump) { return; } this._startJump = true; this._jumpStep = step; this._curJumpTime = 0; this._curJumpSpeed = this._jumpStep / this._jumpTime; this.node.getPosition(this._curPos); Vec3.add(this._targetPos, this._curPos, new Vec3(this._jumpStep, 0, 0)); } update (deltaTime: number) { //we want to only jump if the _startJump is true if (this._startJump) { //we add the delta time to the jump time this._curJumpTime += deltaTime; // if the current jump time is more than what we have allocated then we stop the jump //meaning we have already jumped if (this._curJumpTime > this._jumpTime) { // end jump // force the player to the target position this.node.setPosition(this._targetPos); // mark the end of the jump by changing _startJump to false this._startJump = false; } else { // otherwise if we are still jimping // we tween so that we have a smooth jump ing animation // Get the current position this.node.getPosition(this._curPos); // calculate the length of this frame that should be displaced this._deltaPos.x = this._curJumpSpeed * deltaTime; // add the current position to the length of the displacement Vec3.add(this._curPos, this._curPos, this._deltaPos); // set the position after displacement this.node.setPosition(this._curPos); } } } }

Videos