How to Make A Mobile Virtual Pet Game with HTML5 and Cordova

by Pablo Farias Navarro

In the busy world we live in, most people don’t have the time to take care of pets anymore, so virtual pets were invented. Virtual pets are computer programs that simulate the interaction with a real pet, so that you can have a play with them and keep them healthy and strong.

Given their popularity and how they’ve adapted from 4-bit Tamagochi keyholders to Android hits such as Pou, I thought it’d be interesting to create a HTML5 virtual pet game demo to cover the basics of the Open Source Phaser game library and some basic Cordova API usage.

I’m very passionate about HTML5 game development and want this tutorial to be a starting point for web developers who want to leverage their existing JavaScript skills for game development. If you’d like to learn more about these topics feel free to check my free online course Intro to HTML5 Game Development at Zenva Academy.

Some other Phaser tutorials I’ve authored and co-authored:

Tutorial Source Code

You can grab the tutorial source code and game assets in a ZIP file from here. You can also clone it from Github.

If you want to see the finished product go here to see it live.

Who made the game artwork?

All the artwork of this game was created by my company Zenva and you can use it for commercial and non-commercial projects, no attribution required (although if you make the next Candy Crash please buy me a world round trip).

Learning Objectives

In this tutorial you’ll learn how to create a simple virtual pet game for Android (and any other platform really) using the HTML5 Phaser engine and Cordova.

After completing this tutorial you will know how to:

  • Work with sprites, animations, tweens and states in Phaser.
  • Handle user input in Phaser.
  • Put together a simple virtual pet game.
  • Add Cordova to your game and use the Vibration Cordova Plugin.
  • Test your game on a mobile device using the Intel XDK.
  • Learn how to build for Android with and without Crosswalk.

Hybrid Apps

Before we dig into the tutorial requirements and recommended development environment I want to talk about hybrid apps, which is what we are building here.

A normal web app or HTML5 app is purely HTML, CSS and JavaScript and works just fine in any (up to date) web browser.

A hybrid app is a HTML5 app that is “wrapped” as a native app in “webview”. A webview is a native widget that renders HTML/CSS/JavaScript in a native app. Cordova is an Open Source tool that allows us to wrap our HTML5 apps and games in native platforms, and that also provides a bunch of API’s to access native device features (such as the phone camera, accelerometer, file system, notifications, etc) so that we can access these features in our HTML5 apps and games.


Image: (CC) Laig

Over time, some of these API’s have become standards and are supported by all browsers (without having to include Cordova). Cordova can be extended to include basically any native feature by creating Cordova Plugins.

Cordova or Phonegap?

I get this asked very often and see this question posted all the time so let’s get it out of the way: The project was originally called Phonegap. Then, Adobe bought the startup that created this awesome product, along with the trademark Phonegap. The Open Source project was given to the Apache foundation and was renamed to Cordova. Currently, Phonegap is nothing but Cordova + some custom default configurations + Adobe services including the ability to build in the cloud.

In this tutorial I’ll just talk about Cordova, but keep in mind that it all applies to Phonegap too as per the above definition!

Tutorial Requirements

This tutorial assumes you have basic JavaScript skills. If that is not the case feel free to check my JavaScript course at Zenva Academy for a very fast-paced learning experience.

No prior experience with Phaser, Cordova, Android or game development in general is required to follow this tutorial.

Games built with Phaser can’t be ran by just double clicking on the index.html file. They need to be run using a web server. For a Phaser game that doesn’t include any Cordova API usage you are good to go with the usual web server alternatives such as WAMP for Windows , MAMP on the Mac , Python’s simple HTTP server or Node.js http-server package.

The game we build in this tutorial uses the Vibration Cordova plugin so that the phone vibrates when the pet is made spin. This will obviously don’t work in your computer (unless it actually supported this capability). Nonetheless this game will not break if Cordova is not present, you can still run it from a normal web browser.

In order to run the game in your computer with the Cordova API’s working you can use any of the following alternative:

  • The Intel XDK comes Cordova and supports device emulation as it incorporates a tool called Ripple Emulator.
  • The Ripple Emulator can be installed as a standalone Chrome extension.
  • You can install the Android SDK and the Cordova command line tools to run the game in an Android emulator.

The tool I’ll be using through out this tutorial is the Intel XDK, as it allows to easily emulate, test and debug on the device, and build to test and publish to Android. The XDK can be used as a code editor but my personal preference and what I used to make the game is Sublime Text.

HTML5 Game Development

Through out human history, as soon as a new technology comes out (electricity, computers, the Internet, virtual reality) somebody in some corner of the world will make a game with it. HTML5 was of course no exception.

You can make games without any library using simply JavaScript and HTML, but that path is only recommended if you want to spend time making a game framework instead of making an actual game. The reason being, most of what’s needed to make a game: displaying images, moving images around, animating stuff, can be abstracted with a framework and somebody has done it before. Framework developers will make sure that’s done right, so that you can focus on your game’s content.

In an ideal world you could treat a HTML5 game framework as a black box and ignore what’s inside, but the reality is, in HTML5 game development you have to look inside your framework .

Looking inside your game framework will put you in a huge advantage when it comes to using the framework. Since we are dealing with cutting edge technologies, not everything is documented, not everything is on Google or Stack Overflow. Learning how your framework works will ease your development process and save you heaps of time down the road.

Some popular free and Open Source frameworks include Phaser, Quintus, MelonJs, Crafty,Babylon.js for 3D games. I’ll be using Phaser in this tutorial as it’s a great one for both beginners and more advanced users. Phaser has one of the largest communities at the moment and is constantly being improved and adapted to new platforms as they come out.

Have the following ready before we begin

As usual, I’m turning a simple tutorial into an ebook of epic proportions, but that’s how I like to write so lets summarize what you need so far so that we can start coding:

It All Started with a Hello World

Our HTML file will look like so:

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" /> <title>Learn Game Development at ZENVA.com</title> <script src="js/phaser.js"></script> <style> body { padding: 0px; margin: 0px; background-color: black; } </style> </head> <body> <script src="js/main.js"></script> </body> </html>

phaser.js is the Phaser library you downloaded from Github. You can also use the minified version instead. Normally I like to develop with the non-minified version so that I can inspect the code easily.

main.js will be the entry point of our game, let’s take a look at a first skeleton of this file:

//this game will have only 1 state
 
var GameState = {
 
  //load the game assets before the game starts
 
  preload: function() {
 
  },
 
  //executed after everything is loaded
 
  create: function() {
 
  },
 
  //game loop, executed many times per second
 
  update: function() {
 
  }
 
};
 
//initiate the Phaser framework
 
var game = new Phaser.Game(360, 640, Phaser.AUTO);
 
game.state.add('GameState', GameState);
 
game.state.start('GameState');

Let's go step by step:

1) We create a new Game object like so:

var game = new Phaser.Game(360, 640, Phaser.AUTO);[/javascript]

The Phaser object will be available in our scope as we included phaser.js. When creating a new game, we can enter the width, height and the rendered that will be used to display the game on the screen.

Phaser uses a third-party rendering library called Pixi.js, a WebGL renderer with Canvas fallback. If we set it to auto, Phaser will try to render it using WebGL and if that fails, it will use the Canvas API, all of this 100% behind the scenes.

2) We need to add a State to our game.

[javscript]game.state.add('GameState', GameState);

A state in Phaser is a type of JavaScript object that will have certain default methods. The main methods are the following (to see all the available methods see the documentation for the State object):

  • preload() in this method you preload all your game assets, show a progress bar and define some other game configuration. In my sidescroller game tutorial at the HTML5 Hub I implemented a progress bar.
  • create() this method is executed after all the game assets have been loaded. In createyou start (as the name suggests) creating objects in order to initialize your game.
  • update() this method is called many times per second and it’s where you incorporate things that need to be checked for at all times. For example, collision detection, user input, or if a sprite leaves the screen.

As you see in the code, we create a GameState object that has these basic methods and we assign it to our Phaser game.

Why do we need to preload assets?

What the preloading process does is load the assets (images, tilesheets, audio files, json files) from the disk to the RAM memory. Reading a file from the RAM is much faster than doing so from the disk. When you need to show a character in your game or play a sound, you want that to occur without delay. If you were to load assets from the disk as needed, your game would feel choppy (think of a website where images load one at a time, or that Facebook timeline where some elements never finish loading). That’s why we load everything to memory first, then it’s fast to access during the game play.

3) Fire up the state:

game.state.start('GameState');

This will call the preload() method of the state, and our game will then begin after the assets have been loaded.

More on states and asset preloading

Have you checked my other Phaser tutorial at the HTML5 Hub? in there I explain how to incorporate multiple states in your game and how to add a loading progress bar.

Challenge: Add a loading progress bar to this game as well!

Preloading Assets

Let’s load some of the game images in our preload method. All of these assets are loaded by an object called Loader which is available in our Phaser Game object:

//load the game assets before the game starts
 
  preload: function() {
 
    this.game.load.image('backyard', 'assets/images/backyard.png');   
 
    this.game.load.image('apple', 'assets/images/apple.png');   
 
    this.game.load.image('candy', 'assets/images/candy.png');   
 
    this.game.load.image('rotate', 'assets/images/rotate.png');   
 
    this.game.load.image('toy', 'assets/images/rubber_duck.png');   
 
    this.game.load.image('arrow', 'assets/images/arrow.png');   
 
  },

This is loading all the images and for each image, a label or “key” is given. When we refer to a particular image later in the code it will always be by it’s key (example we will refer to “rubber_duck.png” as “toy”).

If you take a look at the image files, you’ll see we haven’t loaded the file pet.png. This file is contains a spritesheet, which is a group of different images. The Loader class has a method called spritesheet that allows us to load this type of images so that we can later refer to individual frames and create animations. Let’s add the following to our preload method:

this.load.spritesheet('pet', 'assets/images/pet.png', 97, 83, 5, 1, 1);

See the documentation for see what each parameter means.

Sprites

Let’s add our first image, the background. In the create method add:

this.background = this.game.add.sprite(0,0, 'backyard');

If you reload the page you should see our nice backyard background image:

The coordinates in Phaser (and when working with the Canvas and WebGL) have the origin on the top-left corner. X is positive to right and Y is positive downwards. When you place a sprite you specify the coordinates of the sprite’s top left corner (this is what’s called the Sprite’sanchor point, and it can be moved as well). So what we did with the background was to place it’s upper-left corner on the upper-left corner of the screen.

Adapting for Mobile

So far, the image will look the same size no matter the site of the browser or the device. If we want to make our game adapt to different screen sizes, Phaser comes with a ScaleManager object that provides us with a few options. There are 4 available scaling modes that you can use (if you read my sidescroller game tutorial at the HTML5 Hub you may recall I mentioned 3 modes, well a 4th one called RESIZE was added very recently!).

The following image is very self-explanatory as what each mode does (the image is from my retro RPG Huungree, built on HTML5 and available for iOS and Android, if you want to learn about the development process of this game watch this video).

In this tutorial we’ll use the one SHOW_ALL, which will adjust the game so that it fits in the device but without altering the aspect ratio. The following code will go at the beginning of the create method. It will set this type of scaling and it will also make sure the game is centered vertically and horizontally, and that if the size of the screen changes (example resizing the browser’s border) the game will adjust as well.

//scaling options this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL; //have the game centered horizontally this.scale.pageAlignHorizontally = true; this.scale.pageAlignVertically = true; //screen size will be set automatically this.scale.setScreenSize(true);

You should now see the same background image as before but it should fit the size of your browser.

The Pet

After adding the background, let’s add now the pet. See how we specify, besides the asset key, the frame that we want displayed (in this case the first one, index 0), counted from left to right (remember the pet is a spritesheet which contains many frames):

this.pet = this.game.add.sprite(100, 400, 'pet',0);

When we place the pet I’d like to set the coordinates for the center of the pet, not for it’s top-left corner (as it’s the default in all sprites in Phaser). For that, we need to modify the pet’s anchor point to be it’s center instead of it’s top left corner:

this.pet.anchor.setTo(0.5, 0.5); //it refers to the half in x and y, you can also do this.pet.anchor.setTo(0.5)

The pet will have an animation played whenever it eats something or grabs a toy. You could of course have many different animations in your game, and ideally different animations for different situations. In our game, this animation will be composed of the frames 0, 1, 2, 3 then back to 0. Frame 4 is for when the pet dies.

The way we work with frame animations in Phaser is firstly we define the animation and give it a unique key (that we will use later to refer to it):

this.pet.animations.add('funnyfaces', [0, 1, 2, 3, 2, 1, 0], 7, false);

The array specifies the frames, the “7″ is the duration of each frame in miliseconds, the last parameter refers to looping, if you set it to true the animation will repeat itself. More info in the Animation class documentation.

If you want to play this animation at any point in time just do:

this.pet.animations.play('funnyfaces');

See if it works! then delete it, as we are not animating the pet yet.

Dragging the Pet Around

We want to allow the player to drag the pet around, for that we need to enable user input in the pet sprite, and to enable dragging:

//draggable pet
 
this.pet.inputEnabled = true;
 
this.pet.input.enableDrag();

You should be able to drag around your pet now.

Adding the buttons

We want to have 4 buttons as shown on the image bellow. The images have already be loaded in our preload method. Now, we want to listen to click/touch events on them so that we can select them. Once selected, we want to dim the image a bit. When an item is selected, if we then click anywhere on the background, an item will be created. For example if you click on the apple button and then click on the background, an apple should be created on the background.

The only button that will work differently is the spinning one, but we’ll implement that one later on.

Let’s create a sprite for each button. The following goes after we create the pet sprite:

//buttons
 
    this.apple = this.game.add.sprite(72, 570, 'apple');
 
    this.apple.anchor.setTo(0.5);
 
    this.apple.customParams = {health: 20};
 
    this.apple.inputEnabled = true;
 
    this.apple.events.onInputDown.add(this.pickItem, this);
 
    this.candy = this.game.add.sprite(144, 570, 'candy');
 
    this.candy.anchor.setTo(0.5);
 
    this.candy.customParams = {health: -10, fun: 10};
 
    this.candy.inputEnabled = true;
 
    this.candy.events.onInputDown.add(this.pickItem, this);
 
    this.toy = this.game.add.sprite(216, 570, 'toy');
 
    this.toy.anchor.setTo(0.5);
 
    this.toy.customParams = {fun: 30};
 
    this.toy.inputEnabled = true;
 
    this.toy.events.onInputDown.add(this.pickItem, this);
 
    this.rotate = this.game.add.sprite(288, 570, 'rotate');
 
    this.rotate.anchor.setTo(0.5);
 
    this.rotate.inputEnabled = true;
 
    //this.rotate.events.onInputDown.add(this.rotatePet, this);   keep this commented out until we add rotatePet()
 
    this.buttons = [this.apple, this.candy, this.toy, this.rotate];
 
    //nothing selected
 
    this.selectedItem = null;

Basically, for each button we are:

  • Creating a new sprite.
  • Setting the anchor point to the center of the sprite, so that we use that point to place a sprite instead of the top-left corner.
  • We are adding a “customParams” object to each sprite. This is not a Phaser feature, but rather a way to save specific properties to a sprite that I like to use. I prefer to put every custom data there so that it doesn’t accidentally override some Sprite property I wasn’t aware of. As you can see, each item will add/subtract and amount or health and fun.
  • Enabling user input on the sprite.
  • Setting a method for when the user clicks/touches the sprite. In this case a pickItemmethod for the apple, the candy and the toy, and a rotatePet method for the spinner.

I want to keep all the buttons in an array which I called “buttons”, so that I can access all buttons later in the code (for example for clearing a selection).

I also want to keep track of the currently selected button/item which I’ll be doing inthis.selectedItem.

Picking Items

When I tap on an item, the pickItem method is called. Let’s implement this method in our GameState object (see how you can add all the methods you want to your State objects, that’s ok as long as you don’t use any of the reserved names such as preload, create, etc):

//pick an item so that you can place it on the background
 
  pickItem: function(sprite, event) {
 
    if(!this.uiBlocked) {
 
      //clear other buttons
 
      this.clearSelection();
 
      //alpha to indicate selection
 
      sprite.alpha = 0.4;
 
      //save selection so we can place an item
 
      this.selectedItem = sprite;
 
    }
 
  },

This method is an event handler called whenever the user clicks or touches the apple, the candy or the toy. The first parameter gives us the sprite, the second parameter gives us an object with information about the event (such as coordinates, etc, feel free to try console.log(event) to see it all).

this.uiBlocked is a variable that we’ll set to true when an animation is taking place, so that the player has to wait for that to be finished before they can select a new item.

The first thing we do is clear any existing button selection, then we set the sprite’s alpha property (transparency) to 0.4. 1 means it’s not transparent, 0 means it’s invisible, everything in in between will be a degree of transparency. Lastly, we assign the selected sprite to the this.selectedItem property.

The clearSelection method is very straightforward and all it does is set the alpha values of the buttons back to 1, and clears the this.selecteItem object.

//clear all buttons from selection
 
  clearSelection: function() {
 
    //set alpha to 1
 
    this.buttons.forEach(function(element){element.alpha = 1});
 
    //clear selection
 
    this.selectedItem = null;
 
  },

Placing Items in the Background

After the creation of our background sprite in the create method, we’ll also enable input and add an event listener:

this.background.inputEnabled = true;
 
this.background.events.onInputDown.add(this.placeItem, this);

The placeItem method will be executed whenever there is a click or a touch event on the background sprite. This method will grab the coordinates of the event and will create a new sprite on that location. We will later on make the pet move towards the new item and “eat it”.

//place selected item on the background
 
placeItem: function(sprite, event) {
 
    if(this.selectedItem && !this.uiBlocked) {
 
      //position of the user input
 
      var x = event.position.x;
 
      var y = event.position.y;
 
      //create element in this place
 
      var newItem = this.game.add.sprite(x, y, this.selectedItem.key);
 
      newItem.anchor.setTo(0.5);
 
      newItem.customParams = this.selectedItem.customParams;
 
}

You should be able now to tap on an item then place it on the background, but the pet isn’t doing anything yet.

Pet Stats

Our little pet will have two properties: health and fun. If any of the two goes down to zero, the pet dies and it’s game over for you.

Let’s give our pet an initial amount of the two of them. Add this after the pet sprite creation in the create method:

//custom properties of the pet
 
this.pet.customParams = {health: 100, fun: 100};

Virtual pets are very demanding creatures. They need your constant attention andt hey will die if you forget about them for long. Our pet will have it’s health and fun decrease over time. We’ll create a method called reduceProperties that will be called every 5 seconds and that will make your pet be less healthy and less entertained as time goes by.

Before that, it’s important that we can visualize the current health and fun of our pet. Let’s add the following at the end of the create method:

//stats
 
    var style = { font: "20px Arial", fill: "#fff"};
 
    this.game.add.text(10, 20, "Health:", style);
 
    this.game.add.text(140, 20, "Fun:", style);
 
    this.healthText = this.game.add.text(80, 20, "", style);
 
    this.funText = this.game.add.text(185, 20, "", style);
 
    this.refreshStats();

And add the refreshStats method as well:

//show updated stats values
 
  refreshStats: function() {
 
    this.healthText.text = this.pet.customParams.health;
 
    this.funText.text = this.pet.customParams.fun;
 
  },

Now we can implement our timer to decrease the pet’s properties every 5 seconds (or some other time if you’d like). Add the following at the end of the create method:

//decrease health and fun every 10 seconds
 
this.statsDecreaser = this.game.time.events.loop(Phaser.Timer.SECOND * 5, this.reduceProperties, this);
 
this.statsDecreaser.timer.start();

What we just did was create a looping timer that calles the reduceProperties method (that we’ll implement next) every 5 seconds. We save this loop in a property of the GameState object so that we can initiate it or stop it at our convenience. reduceProperties will look like so:

reduceProperties: function() {
 
    this.pet.customParams.health = Math.max(0, this.pet.customParams.health - 20);
 
    this.pet.customParams.fun = Math.max(0, this.pet.customParams.fun - 30);
 
    this.refreshStats();
 
  },

If you reload the game on your browser, you should see how the health of the pet and fun decrease every 5 seconds.

What about Phaser’s in-built “health” property for sprites?

If you did your homework and read some of Phaser’s source code and documentation, you might have seen that sprites in Phaser already have a “health” property. Then why are we not using it? Phaser’s in-built health/alive/dead properties are great to use in games where you actually killing sprites. In this case, I wanted health to be just another property (along with “fun” but also more could be added) so opted to just put it all in customParams. I didn’t want to have to treat “health” like a special case and I also didn’t want to add direct properties to a sprite as they might collide with other existing sprite properties.

Game Over

If either the health or the fun of the pet reaches zero, the pet will die and it’s game over! the game will then reload.

Whenever we want to check something “at all times” (example, I want to always be checking whether the pet still has health or fun) we use the update method, which gets called up to 60 times per second. When the pet dies, we’ll change the pet frame to 4 which is the dead pet frame. After two seconds we’ll reload the game and start over.

//game loop, executed many times per second
 
  update: function() {
 
    if(this.pet.customParams.health <= 0 || this.pet.customParams.fun <= 0) {
 
      this.pet.customParams.health = 0;
 
      this.pet.customParams.fun = 0;
 
      this.pet.frame = 4;
 
      this.uiBlocked = true;
 
      this.game.time.events.add(2000, this.gameOver, this);
 
    }
 
  },
 
  gameOver: function() {   
 
    this.game.state.restart();
 
  },

Grabbing Items and Tweens

So far, the pet has a very sad story. It loses health and fun over time until the game reloads. Let’s give the pet some positive input as well! time to allow the pet to eat it’s food and play with it’s toy.

When we place an item in the background, we’ll move the pet towards the item, we’ll animate the pet (using the funnyfaces animation we defined previously), the pet stats will be updated to those of the item, and the item will disappear.

The pet movement will be implemented using a tween. Tweens allow you to create a transition between two values for a property (or many properties) of a sprite. Phaser’s tween implementation is based on this other implementation in case you want to know more about it.

When creating a tween, we define which properties will change, the duration of the transition, and we can speficy a callback for when the process finishes.

After the tween is completed, we want our pet to animate and to update it’s stats. This is the final version of placeItem:

//place selected item on the background
 
  placeItem: function(sprite, event) {
 
    if(this.selectedItem && !this.uiBlocked) {
 
      //position of the user input
 
      var x = event.position.x;
 
      var y = event.position.y;
 
      //create element in this place
 
      var newItem = this.game.add.sprite(x, y, this.selectedItem.key);
 
      newItem.anchor.setTo(0.5);
 
      newItem.customParams = this.selectedItem.customParams;
 
      //the pet will move to grab the item
 
      this.uiBlocked = true;
 
      var petMovement = game.add.tween(this.pet);
 
      petMovement.to({x: x, y: y}, 700);
 
      petMovement.onComplete.add(function(){
 
        this.uiBlocked = false;
 
        //destroy item
 
        newItem.destroy();
 
        //animate pet
 
        this.pet.animations.play('funnyfaces');
 
        //update pet stats
 
        var stat;
 
        for(stat in newItem.customParams) {
 
          //make sure the property belongs to the object and not the prototype
 
          if(newItem.customParams.hasOwnProperty(stat)) {
 
            this.pet.customParams[stat] += newItem.customParams[stat];
 
          }
 
        }
 
        //show updated stats
 
        this.refreshStats();
 
        //clear selection
 
        this.clearSelection();
 
      }, this);
 
      petMovement.start();     
 
    }
 
  },

Now our lovely pet can move to the items, consume them happily and improve it’s stats!

We only have one thing to implement, the spinner which will make the pet rotate and increase it’s “fun” levels.

Rotating the Pet

Our rotation will take place in a method called rotatePet. Make sure to uncomment the input listener for the “rotate” sprite so that rotatePet is called when the button is clicked.

//rotate the pet
 
  rotatePet: function(sprite, event) {
 
    if(!this.uiBlocked) {
 
      this.uiBlocked = true;
 
      //alpha to indicate selection
 
      this.clearSelection();
 
      sprite.alpha = 0.4;
 
      var petRotation = game.add.tween(this.pet);
 
      petRotation.to({ angle: '+720' }, 1000);
 
      petRotation.onComplete.add(function(){
 
        this.uiBlocked = false;
 
        sprite.alpha = 1;
 
        this.pet.customParams.fun += 10;
 
        //show updated stats
 
        this.refreshStats();
 
      }, this);
 
      petRotation.start();
 
    }
 
  },

See how we are also using a tween here, but this time we modify the angle property and for a longer time than we did for x and y in the previous method.

Our game demo is complete except for one thing: I’d like my phone to vibrate every time I make the pet spin. For that, we need to incorporate Cordova into our project, so that we can access the vibration capabilities of our devices.

Adding Cordova and the Vibration Plugin

For this tutorial I’ll be using the IntelXDK to add Cordova, the Vibration Cordova Plugin, and to build for Android. You can alternatively add this plugin to your project using Cordova’s command line.

In order to enable the Vibration Plugin on your project, go to Project then scroll to Cordova 3.x Hybrid Mobile App Settings, then Plugins and Permissions, and check the checkbox for the Vibration plugin.

We then need to make sure we are including cordova.js in our index.html file. cordova.js is a “phantom library”, there is no cordova.js file in our folder, but making reference to it will allow us to access all of these native API’s from our HTML5 game. So make sure you add this in your index.html’s header:

<script src="cordova.js"></script>

What about the deviceready event?

If you have worked with Cordova in the past you should know that you always have to wait for a “deviceready” event before firing up any Cordova-related code (such as API usage). When working with the Phaser engine we don’t need to do that, as Phaser will look for Cordova and if it finds it, it will make sure that the deviceready event has been fired before initiating the game.

Testing the Game on Mobile

If you go to the Test tab of the XDK you can push the game to the cloud and then retrieve it on your phone for a quick preview. On Android, you’ll need to install the Intel App Previewapp from the Playstore and link it to the same Intel account you are using on the XDK.

Before we add the vibration specific code, make sure you can run your app on the Intel App Preview (if you are having trouble using it please post your questions on their official support forum)

Making the Device Vibrate

Let’s now add some simple native API usage to our game. In our rotatePet method, right after setting the alpha value of 0.4, add the following code:

//vibrate device if present
 
      if(navigator.vibrate) {
 
        navigator.vibrate(1000);
 
      }

Now if you test again on your phone, it should vibrate when you tap on the spinner icon. It’s really that simple!

Building for Android

When building to Android with the Intel XDK you have two options: Crosswalk for Android or just Android. You can access both options on the Build tab of the XDK.

In order to explain what Crosswalk does I’ll explan how this process works without it first: all Android phones have a “webview” available which is a native widget that allows you to render HTML5 apps and games. When you build an app with Cordova without the use of Crosswalk, the existing webview of the phone is used to render the app. The problem with this approach is that different Android versions and models have different implementations of this webviews, so sometimes certain HTML5 features that work on one phone won’t work on a different phone, or certain things of your app/game might look different on different phones.

When using Crosswalk you don’t just install the HTML5 app but also a Chrome-based webview, so no matter what implementation of the webview the phone you are targeting has (as long as it’s Android 4+), it will show your game/app using the Chrome webview that YOU have provided. This gives you full control as a developer and it protects your game from operating system updates that could break certain features you are using.

As most things in life, everything has advantages and disadvantages. If you are not using Crosswalk, you can make pretty lightweight apps which is a huge plus on the Playstore. When using Crosswalk, you are pushing in an entire webview implementation so the file is super heavy. For example, our virtual pet game’s APK file is 837 kb with a normal Android build (without the slightest efforts of minification or compression), whereas the Crosswalk builds are 20.5 MB and 17.7 MB (one for x86 and one for arm systems).

Conclusion

We’ve come a long way and have a simple demo for a game that illustrates many of Phaser’s basic concepts and also incorporates basic Cordova API usage so that you hopefully have broken the ice with these amazing tools.

In order for it to be a published game you should add more features and make it more entertaining of course.

If you have any comments or questions feel free to use the commenting area bellow! Also you can check my free online course Intro to HTML5 Game Development at Zenva Academy.

For more complete information about compiler optimizations, see our Optimization Notice.

1 comment

Top
Arif D.'s picture

Thank you very much for being a great article. I made agario game. I am now my developer in the direction of the information I have given. thanks

Add a Comment

Have a technical question? Visit our forums. Have site or software product issues? Contact support.