Implementing touch controls

In this section, you will learn how to set up the control scheme that makes your app playable. The Cocos2d-html5 framework, visual assets, and physics engine are all complete, and implementing touch controls lets users interact with those elements on the screen.

Cocos2d-html5 features touch implementation, but the BoxQuest sample app requires multi-touch controls, so we will import an external framework instead. Let's get started.

Download Freewill.js

Before we begin, you need to download Freewill.js, an external framework that provides multi-touch controls, from the BoxQuest repository on GitHub and save it in your js folder. You also need some new graphics to use as assets for the control scheme. In your images folder, create a new folder and name it freewill. Navigate to the freewill folder in the BoxQuest repository and save copies of all the files found there in your own freewill folder.

Now you can use Freewill.js in your app by modifying some of the files you created earlier. First, we need to make some adjustments for the new framework in index.html and styles.css, and then we can create a freewill object from that framework in SceneStart.js.

Adjust your code

Cocos2d-html5 lets us specify the JavaScript files we want to use, and loads them for us at runtime. We already specified SceneStart.js as one of these files, but now that we’re adding Freewill.js to your app, we need to make sure the framework recognizes it.

Open index.html in your text editor and locate the appFiles array. This array contains any additional JavaScript files you want to import into your app. Above the file path for SceneStart.js, add the following:

'./js/Freewill.js',

We also need to add a <div> overlay to receive the touch input. Place it as the first line in the <body>.

<div id="freewill"></div>

Save the file. Now that we created this basic element, we can style it as needed using CSS. Before the freewill overlay can receive touch input, we need to make sure it covers the entire screen while it's in the foreground. Open styles.css in your text editor. Below the existing code, add the following:

#freewill {
    bottom: 0px;
    overflow: hidden;
    position: fixed;
    top: 0px;
    width: 100%;
    z-index: 999;
}

Save the file.

Create a freewill object

Before you can start using Freewill.js in your app, you need to create a freewill object.

Open SceneStart.js in your text editor, and locate the code we used to add portals and coins sprites. Below the code that loads the finish portal, but above the scheduled update function, add the following:

this.freewill = new Freewill({
            container: document.querySelector('#freewill')
});

Here, we reference the <div> overlay we added to main.html, to receive the touch input. We can now add joystick and button controls to your app.

Add a joystick control

Immediately below the code we used to create the freewill object, we'll set up a joystick control to operate your hero’s movement. When we add a joystick object, we supply a base image and a pad image. The base is a stationary point on the screen where the joystick is located while the pad is the virtual stick, and moves in response to the user's touch input. In this case, we'll make your joystick invisible because we don't want any images interfering with the viewable screen.

The image values for an invisible object are arbitrary, so we'll use the buttonblue.png file from your freewill folder for both imageBase and imagePad. Because the user can't see the joystick in use, we don't need to update its position, so we set fixed to true and the coordinates to [0.0, 0.0].

The trigger component is important for this control scheme. It dictates the area in which touch events are registered. We override the default behavior to specify that the joystick registers any touch events on the left half of the screen. Finally, we set both the low and high opacities to 0 to make sure that the joystick does not appear.

Note the this.freewill.move reference at the beginning, which is important because it lets you implement your own custom onTouchStart, onTouchMove, or onTouchEnd functionality. These functions transform the user's touch input into on-screen movement. In this case, we need to implement only onTouchMove and onTouchEnd to move the hero.

this.freewill.move = this.freewill.addJoystick({
    imageBase: './images/freewill/buttonblue.png',
    imagePad: './images/freewill/buttonblue.png',
    fixed: true,
    pos: [0.0, 0.0],
    trigger: [0.0, 0.0, window.innerWidth / 2.0, 
    window.innerHeight],
    opacLow: 0.0,
    opacHigh: 0.0
});

In the Freewill.js framework, a joystick has an x and y velocity based on where the user’s finger is in relation to the base. In this case, if the trigger detects movement, we retrieve the velocity of the joystick and set the hero’s horizontal impulse to reflect that movement.

this.freewill.move.onTouchMove = function () {
            _g.LayerStart.hero.j[0] = this.velocity[0];
};

The joystick is released when the user's finger leaves the screen. To stop the hero's movement at that point, we reset the horizontal impulse force to 0 when the trigger detects the release. Because our scheduled update provides the hero’s impulse data to our web worker for every animation frame, this setting is all we need to implement horizontal movement.

this.freewill.move.onTouchEnd = function () {
            _g.LayerStart.hero.j[0] = 0.0;
};

Add a button control

We want your hero to be able to jump. For vertical movement, we use a button instead of a joystick.

Like the joystick, we want your button to be invisible, so the image, fixed, and pos values are arbitrary. This time, we set the trigger to the right half of the screen, and again set both opacities to 0.

this.freewill.jump = this.freewill.addButton({
            image: './images/freewill/buttonblue.png',
            fixed: true,
            pos: [0.0, 0.0],
            trigger: [window.innerWidth / 2.0, 0.0, window.innerWidth / 
                     2.0, window.innerHeight],
            opacLow: 0.0,
            opacHigh: 0.0
        });

Finally, we take the button object and implement onTouchStart behavior. In this case, we initiate a vertical impulse when the user touches the screen and onTouchStart occurs. The web worker determines whether the impulse is valid, based on your hero's position relative to the walls and surfaces, and makes the appropriate physics calculations.

this.freewill.jump.onTouchStart = function () {
            _g.LayerStart.hero.j[1] = -9.0;
        };

        this.schedule(this.update);

Save the file.

Add keyboard controls

Your app is now ready for a full test run in the Ripple emulator, but because of the multi-touch controls, it's difficult to navigate the hero by clicking the pointer. To avoid this issue, you can either deploy the game to a BlackBerry 10 device or add the basic keyboard controls from the BoxQuest sample app, which let you test your app more easily in a browser.

Open SceneStart.js in your text editor one more time. First, you add two lines of code to enable the keyboard controls. Near the beginning of the ctor function, below the _g.Layerstart = this; line that initializes the global namespace, add the following:
this.setKeyboardEnabled(true);
    document.querySelector('#freewill').style.visibility = 'hidden';
Now we need to apply those controls to your hero. Between the end of the ctor function and the beginning of the update function that supplies impulse information, add the following:
onKeyDown: function (e) {
        if (e === 38) {
            if (_g.LayerStart.hero.jumping === false) {
                _g.LayerStart.hero.jumping = true;
                _g.LayerStart.hero.j[1] = -9.0;
            }
        } else if (e === 37) {
            _g.LayerStart.hero.j[0] = -40.0;
        } else if (e === 39) {
            _g.LayerStart.hero.j[0] = 40.0;
        }
    },

    onKeyUp: function (e) {
        if (e === 38) {
            _g.LayerStart.hero.jumping = false;
        } else if (e === 37) {
            _g.LayerStart.hero.j[0] = 0.0;
        } else if (e === 39) {
            _g.LayerStart.hero.j[0] = 0.0;
        }
    },

Save the file.

Test your app in the Ripple emulator

Congratulations! You now have a finished Cocos2d-html5 app. If you added keyboard controls in the previous step, you can test the app in the Ripple emulator using the arrow keys to guide your hero through the game level.


The finished app running in the Ripple emulator.

Last modified: 2014-03-10

comments powered by Disqus