Tutorial: Getting started with WeChat games (Part VI)

Cocos Creator: Getting started with WeChat games (Part VI)

Note: This is a multi-part tutorial: Part 1 | Part 2 | Part 3 | Part 4 | Part 5

Introduction and getting help

You are welcome to post to the Cocos Creator category on the Cocos forums to talk about any issues you encounter during the development process. This tutorial does not teach how to code.

Please prepare your development environment before starting this tutorial. If you are having trouble with our tutorial, please take a look at the following documentation:

Preparing the development environment:


Let’s begin!

After building out the collision system in the previous tutorial, we have completed the development of the core gameplay. Next, we need to develop another important thing: the UI

Cocos Creator provides a lot of packaged UI components, which can meet normal development needs. Of course, for the special needs of some projects, we can also customize the built-in UI components. For this tutorial, the UI provided by Cocos Creator itself is more than enough.

In the first tutorial, we created a widget node under the Camera as the parent node of the HUD interface. This HUD interface will always be within the scope of the Camera. This means we don’t have to worry about the movement of the Camera causing the UI to be out of range and not displayed properly.

Using widgets, sprites, labels, and buttons, we can quickly piece together the following UI interface using the Cocos Creator editor:

Next, we need to implement the functions that will start the game when the button is pressed. Since our resource has only one picture, there is no resource to do the button pressed state. Therefore, we choose Scale to help show when the button’s state has changed.

33

When the button is pressed, the button will zoom. The zoom value and switching time can be set by changing both Duration and Zoom Scale.

34

Starting the game

Let’s take a look at what functions we need to implement after the start of the game button is pressed:

  1. The fish hook needs to start sinking
  2. The Main Menu UI needs to disappear so the player can play the game. (i.e. the game start button, game logo, and leaderboard button need to be hidden).

Previously, to aid in debugging, the start() function ran immediately upon game startup. Now that we have implemented a menu/game start system the start() function can be moved to the button click event.

First, in the start() method of the previous Hook.js script, remove the code for debugging when the fish hook starts to move.

start() {
  this.Startline(); // remove this line
}

Second, in the Property Inspector of the Play button, set Click Events to 2:

The click event has four parameters:

  1. the receiver node of the click event. This node must have a script.
  2. the name of the script component.
  3. the specified callback method.
  4. CustonEventData is the incoming parameter of the callback method (optional)

Third, in the level manager, use the mouse to drag the Hook node to Click Events, select the Hook script, and use StartLine() as the callback method.

In this way, a callback can be triggered after clicking, and the StartLine() method is called to make the fish hook start to sink.

We need a function to hide the splash/menu screen.

First, create a new script, MainUI.js for MainUI.

Second, implement a method called Hide(), which will control when the UI is hidden:

Hide () {
  this.node.active = false;
},

Third, in the second Click Event, select MainUI, the script MainUI.js script, and the callback method Hide().

Implementing scoring

Scoring this game is very simple. The text displayed in the Label needs to be changed according to how well the player does playing this game. Changing the display character can be done by assigning a value to the string property of the label.

There is a problem we need to pay attention to.

If the scoring requirements are simple, we can calculate and increase the score when the fish hook collides with the fish, and then change the display content of the score label.

If the scoring requirements are not so simple, we have more logic to write. For example, what if we need to change the color of the label font when the player reaches a certain score, or we need to let the score numbers jump for a few points.

With more complex requirements, these functions could be implemented in the collision callback method and the scoring will work fine. However, this method binds the UI and the fish hook tightly. This could complicate the UI during future development.

To prevent this from happening, we introduce a cross-script global data record. The gameplay logic only changes the value of the data, and the UI only needs to get the value from the data and display it. This is a superficial application of design patterns, but the benefits brought by doing this aren’t minute.

There are many ways to implement this. In this tutorial, a single design pattern will be used.

First, create GameData.js to use as a singleton.

Second, add the following code to GameData.js

var GameData = cc.Class({
    extends: cc.Component,
    statics: {
        instance : null
    },
    properties: {
        score : 0,
        depth : 0
    },
});

GameData.instance = new GameData();

module.exports = GameData;

Third, a singleton can be obtained through GameData.instance to read and write data, avoiding the coupling issue mentioned above. For example, in the HUD.js script:

var GameData = require("GameData");

cc.Class({
  extends: cc.Component,

  properties: {
    mScoreLabel : cc.Label,
    mDepthLabel : cc.Label
  },

  start () {

  },

  update (dt) {
    this.mScoreLabel.string = GameData.instance.score;
    this.mDepthLabel.string = "Depth: " + GameData.instance.depth.toFixed(2);
  },
});

Fourth, when the player clicks play another round, the scene data needs to be reset. A reset method can be added to Scene.js to take care of this.

    reset () {
        GameData.instance.depth = 0;
        GameData.instance.score = 0;
        // clear any fish on the hook
        this.mFishPool.removeAllChildren(true);
        // clear any remaining fish
        this.mController.removeAllChildren(true);
    },

Previewing

Let’s click on the Preview button to see how this game is playing. Once you start the game, you can press a button to start the game and start playing. How high of a score can you reach?

Conclusion

There is just one more installment in this tutorial series!

Stay tuned for Part 7 of this tutorial!