Explore Free Phaser 2 & 3 Tutorials – GameDev Academy https://gamedevacademy.org Tutorials on Game Development, Unity, Phaser and HTML5 Thu, 23 Feb 2023 21:14:33 +0000 en-US hourly 1 https://wordpress.org/?v=6.1.1 https://gamedevacademy.org/wp-content/uploads/2015/09/cropped-GDA_logofinal_2015-h70-32x32.png Explore Free Phaser 2 & 3 Tutorials – GameDev Academy https://gamedevacademy.org 32 32 Create a Basic Multiplayer Game in Phaser 3 with Socket.io – Part 1 https://gamedevacademy.org/create-a-basic-multiplayer-game-in-phaser-3-with-socket-io-part-1/ Mon, 19 Dec 2022 12:57:07 +0000 https://gamedevacademy.org/?p=6753 Read more]]> In this multipart tutorial, we will be using Phaser 3 and Socket.io to create a simple multiplayer game. For our multiplayer game, we will follow the client-server game architecture. If you are not familiar with the client-server game architecture, the client is responsible for displaying the game to the player, handling the player’s input, and for communicating with the server. The server, on the other hand, is responsible for broadcasting that data to each client.

The goal of this tutorial is to teach you the basics of creating a multiplayer game. You will learn how to:

  • Setup a Node.js and Express server that will render our game and communicate with it.
  • Setup a basic Phaser 3 game that will act as our client.
  • Use Socket.io to allow the server and the client to communicate.

Course Files and Versions

You can download all of the files associated with the source code for part one here.

At the time this tutorial was written, the following versions were used. You may need to use these versions to have the same results from this tutorial.

  • Node.js: 10.13.0
  • JSDOM: 13.0.0
  • Express: 4.16.4
  • Socket.IO: 2.1.1
  • Datauri: 1.1.0

BUILD YOUR OWN GAMES

Get 250+ coding courses for

$1

AVAILABLE FOR A LIMITED TIME ONLY

Tutorial Requirements

For this tutorial, we will be using Node.js and Express to create our server. We will also be using NPM to install the required packages we need for the server to run. In order to follow along with this tutorial, you will need to have Node.js and NPM installed locally, or you will need access to an environment that already has them installed. We will also be using the Command Prompt (Windows) / Terminal (Mac) to install the required packages, and to start/stop our Node server.

Having a prior experience with these tools is a plus, but it is not required for this tutorial. We will not be covering how to install these tools as the focus of this tutorial is making a game with Phaser. The last thing you will need is an IDE or Text Editor for editing your code.

To install Node.js, click the link here: and choose the LTS version. You can download and use the current version with this tutorial, however, the LTS version is recommended for most users. When you install Node.js, NPM will also be installed on your computer. Once you have these tools installed, you can move on to the next part.

As a last note, we do not recommend this tutorial be used by educators looking for new classroom resources. Instead, try Zenva Schools which features K12-friendly courses on web development and game development – plus classroom management features.

Setting up the server

The first thing we are going to do is create a basic Node.js server that will serve our game files. To get started, create a new folder on your computer, it can be called anything you want. Then navigate inside this folder and create a new file called server.js. Open up server.js and add the following code to it:

var express = require('express');
var app = express();
var server = require('http').Server(app);

app.use(express.static(__dirname + '/public'));

app.get('/', function (req, res) {
  res.sendFile(__dirname + '/index.html');
});

server.listen(8081, function () {
  console.log(`Listening on ${server.address().port}`);
});

In the code above we:

  • referenced the express module, which is a web framework that will help us render our static files.
  • created a new instance of express and called it app.
  • supplied the app to the HTTP server, which will allow express to handle the HTTP requests.
  • updated the server to render our static files using express.static built-in middleware function in Express.
  • told the server to serve the index.html file as the root page.
  • had the server start listening on port 8081.

Before we can run the server, we will need to install the required modules for the server. Open your terminal/command prompt, and navigate to your project folder. Once there you will need to run the following command: npm init -f. This will create a package.json file in your project folder. We will use this file to keep track of all the packages that our project depends on.

Now, we will install express. In your terminal run the following command: npm install –save express. This will create a folder called node_modules in your project folder, and by adding the –save flag to the command, npm will save this package in our package.json file.

Setting up the client

With the basic server code finished, we will now work on setting up our client-side code. In your project folder, create a new folder called public. Any file we put in this folder will be rendered by the server that we set up. So we will want to put all of our static client-side files in this folder. Now inside the public folder, create a new file called index.html. Open up index.html and add the following code to it:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8">
    </head>

    <body>
        <script src="//cdn.jsdelivr.net/npm/phaser@3.0.0/dist/phaser.min.js"></script>
        <script src="js/game.js"></script>
    </body>

</html>

In the code above, we set up a simple HTML page and we referenced two JavaScript files, phaser.min.js (the phaser game framework) and game.js (our Phaser game code). Back in the public folder, create a new folder called js , and in this folder create a new file called game.js. Open up game.js and add the following code to it:

var config = {
  type: Phaser.AUTO,
  parent: 'phaser-example',
  width: 800,
  height: 600,
  physics: {
    default: 'arcade',
    arcade: {
      debug: false,
      gravity: { y: 0 }
    }
  },
  scene: {
    preload: preload,
    create: create,
    update: update
  } 
};

var game = new Phaser.Game(config);

function preload() {}

function create() {}

function update() {}

Let’s review the code we just added:

  • We created the configuration that will be used for our Phaser game.
  • In the config object, in the type field, we set the renderer type for our game. The two main types are Canvas and WebGL. WebGL is a faster renderer and has better performance, but not all browsers support it. By choosing AUTO for the type, Phaser will use WebGL if it is available, otherwise, it will use Canvas.
  • In the config object, the parent field is used to tell Phaser to render our game in an existing <canvas>  element with that id if it exists. If it does not exists, then Phaser will create a <canvas>  element for us.
  • In the config object, we specify the width and height of the viewable area of our game.
  • In the config object, we enabled the arcade physics that is available in Phaser, and we set the gravity to 0.
  • In the config object, we embedded a scene object which will use the preload, update, and create functions we defined.
  • Lastly, we passed our config object to Phaser when we created the new game instance.

With our basic client-side code setup, we will now test our server and make sure everything is working correctly. Back in the terminal/command prompt, run the following command: node server.js and you should see the following line appear Listening on 8081. Now, if you open up your web browser and navigate to http://localhost:8081/, you should see a black box on the web page, and if you open the console in the developer tools, you should see a log with the version of Phaser your game is running.

Blank Phaser 3 game running in Google Chrome

Adding Socket.IO

With our server now rendering our game, we will now work on adding Socket.IO to our game. If you are not familiar with Socket.IO, it is a JavaScript library that enables real-time, bi-directional communication between web clients and servers. To use Socket.IO, we need to update our client and server code to enable the communication between the two.

Back in your terminal, run the following command: npm install –save socket.io. If your server is still running, you can either: open a new terminal window and run the code in your project folder, or stop the server (CTRL + C) and then run the command. This will install the Socket.IO node package and save it in our package.json file.

Now, in server.js add the following code below the var server = require(‘http’).Server(app); line:

var io = require('socket.io').listen(server);

Then add the following code above the server.listen line:

io.on('connection', function (socket) {
  console.log('a user connected');
  socket.on('disconnect', function () {
    console.log('user disconnected');
  });
});

In the code above we:

  • referenced the socket.io module and had it listen to our server object.
  • added logic to listen for connections and disconnections.

Next, we will update the client side code to include the Socket.IO library. Open up index.html and add the following line at the top of the <body> element:

<script src="/socket.io/socket.io.js"></script>

Then, open up game.js and add the following line inside the create function:

this.socket = io();

Now, if you start the server back up again, and refresh your game in your browser, you should see the user connected/disconnected messages in your terminal.

Console information denoting users connecting and disconnecting

Adding players – Server

Now that we have our socket connections setup, we can move on to adding players to our game. In order to keep all of the player’s games in sync, we will need to notify all players when a user connects or disconnects from the game. Also, when a new player connects we will need a way to let the player know of all the other players in the game. To do all of this we will need to store some player data, and we will use the socket connections to send messages to our players.

For this tutorial, we will store the player data in memory on the server. Normally, we would want to store this data in some type of database, that way it would be persistent, and if the server fails, we could easily recover the state of the game.

In server.js add the following line below the io variable:

var players = {};

We will use this object to keep track of all the players that are currently in the game. Next, in the callback function of the socket.io connection event add the following code below the console.log(‘a user connected’); line:

// create a new player and add it to our players object
players[socket.id] = {
  rotation: 0,
  x: Math.floor(Math.random() * 700) + 50,
  y: Math.floor(Math.random() * 500) + 50,
  playerId: socket.id,
  team: (Math.floor(Math.random() * 2) == 0) ? 'red' : 'blue'
};
// send the players object to the new player
socket.emit('currentPlayers', players);
// update all other players of the new player
socket.broadcast.emit('newPlayer', players[socket.id]);

Let’s review the code we just added:

  • When a player connects to the web socket, we store some player data in the players object and we use the socket.id as the key.
  • We are storing the rotation, x, and y position of the player, and we will use this to control were we create sprites on the client side, and use this data to update all players games. We also store the playerId so we can reference it in the game, and we added a team attribute that will be used later.
  • We used socket.emit and socket.broadcast.emit to emit an event to the client side socket. socket.emit will only emit the event to this particular socket (the new player that just connected).  socket.broadcast.emit will send the event to all other sockets (the existing players).
  • In the currentPlayers event, we are passing the players object to the new player. This data will be used to populate all of the player sprites in the new player’s game.
  • In the newPlayer event, we are the passing the new player’s data to all other players, that way the new sprite can be added to their game.

When a player disconnects, we need to remove that player’s data from our players object, and we need to emit a message to all other players about this user leaving, that way we can remove that player’s sprite from the game.

In the callback function of the socket.io disconnect event add the following code below the console.log(‘user disconnected’); line:

// remove this player from our players object
delete players[socket.id];
// emit a message to all players to remove this player
io.emit('disconnect', socket.id);

Your server.js file should look like the following:

var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io').listen(server);

var players = {};

app.use(express.static(__dirname + '/public'));

app.get('/', function (req, res) {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function (socket) {
  console.log('a user connected');
  // create a new player and add it to our players object
  players[socket.id] = {
    rotation: 0,
    x: Math.floor(Math.random() * 700) + 50,
    y: Math.floor(Math.random() * 500) + 50,
    playerId: socket.id,
    team: (Math.floor(Math.random() * 2) == 0) ? 'red' : 'blue'
  };
  // send the players object to the new player
  socket.emit('currentPlayers', players);
  // update all other players of the new player
  socket.broadcast.emit('newPlayer', players[socket.id]);

  // when a player disconnects, remove them from our players object
  socket.on('disconnect', function () {
    console.log('user disconnected');
    // remove this player from our players object
    delete players[socket.id];
    // emit a message to all players to remove this player
    io.emit('disconnect', socket.id);
  });
});

server.listen(8081, function () {
  console.log(`Listening on ${server.address().port}`);
});

Conclusion

With our server code for adding players in place, this brings part one of this tutorial to an end. In part two we wrap up our multiplayer game by:

  • Adding the client side logic for adding players to our game.
  • Adding logic for player input.
  • Adding collectibles for the players to collect.

I hoped you enjoyed part one of this tutorial and found it helpful.

Note that if you feel a bit out of debt, don’t be afraid to explore some basic web development courses first for individuals or even for teachers to use in the classroom.

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
How to Create a Multi-Platform Idle Clicker Game with Phaser https://gamedevacademy.org/phaser-tutorial-how-to-create-an-idle-clicker-game/ Thu, 23 Jun 2022 13:52:49 +0000 https://gamedevacademy.org/?p=2642 Read more]]> Since the dominance of mobile games in the industry, no genre is more popular than the idle clicker.

In this tutorial, we’re going to use the well-established Phaser 2 framework – which offers cross-platform capabilities – to build an idle clicker game where you “attack” monsters to progress in the game. Of course, we’ll also set up the ability to buy auto-clickers that will “attack” monsters for you as well.

If you’re ready to explore this in-demand genre, let’s learn!

What is an idle click game?

Also known as clicker and incremental games, these type of games have you clicking something repeatedly or idling to gain some form of currency (e.g. cookies, money, energy) which you then use to buy upgrades. It’s a very simple concept at the core, but quite addictive!

Clicker games were first made popular in 2013 with a game called Cookie Clicker. Since then many games have been created in this genre, the themes and flavor of these games vary widely. From cookies to fantasy rpg, sci fi, farming, sand castles, etc.

One such clicker game that I’ve played quite a bit is Clicker Heroes, it’s a fantasy RPG style game where you click various monsters to progress. In this tutorial, we are going to build the foundations of a clicker game similar to Clicker Heroes that you can build upon and add your own style and flair.

Screenshot of Clicker Heroes game

Tutorial source code

You can download the tutorial source code here.

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

Getting started

Source Control

The first thing that I do when starting any project is create a folder, and initialize it for git source control. If you don’t already have git, you can download it for your OS from the official site. With any software development, it is critical to have backups. Using source control, specifically git, is a much more robust and safe solution than simply copying or zipping your files periodically. It’s also important to do micro commits, save your progress in very small increments so that you can roll back to any point if you find that you’ve added some new code that is breaking everything. Also it prepares your codebase automatically for upload to a service like github or bitbucket. There are many things beyond simply committing your code that you can do with git, if you are new to git I encourage you to checkout the Git and Github Fundamentals course at Zenva Academy.

After installing git for your system, open the folder you created in a command window, and simply type git init  and it will be ready to go.

Gathering Art

We need to get some sprites for the monsters. A great site to find free art that you can use for your projects is OpenGameArt.org. Much of the artwork is either public domain or licensed to the Creative Commons. A quick search and I’ve found a resource with a variety of monster sprites. This particular set is licensed under CC BY SA 3.0 which basically means that you must give credit to the original authors, and any modifications you make must be shared under the same license. There are other licensing options available to artists, and some do not allow the use of the resources in commercial applications, so be sure to check the licensing on the site.

OpenGameArt.org website with CC-BY-SA 3.0 license highlighted

The monster images that I’ve chosen come in various sizes, each with 4 frames representing various damage states. For this game, we don’t really need the extra damage states, so I have cropped all of the images to just the first frame. For the purposes of this tutorial, I think that 1 image per monster is all that we’ll need. It would be nice if these monsters were animated, but the single image works well for a placeholder right now.

In addition to the monsters, we’ll need some rpg icons for the upgrades and loot. It’s not likely that we’ll use all 496 images in this set, but we can prune the collection later before we are ready to release of the ones that we don’t use. We’ll also need something to use as a background for our world, this forest scene will do nicely.

You’ll find all of the sprites in the assets/images folder of the companion source code to this project. If you’re downloading your own selection of images to use, place them in there as well.

Reminder: Once you’ve added your files, go ahead and commit them to source control.

Setup Phaser

You’ll need to download Phaser, you can either clone the github repo or download the release or use something like Bower to install it. Phaser games are web based games, so first we need a HTML page to host it. Create a file called index.html in the root of your project folder and put this for the contents.

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Click of the Titans</title>
        <style>body {margin: 0;padding: 0;}</style>

        <script src="lib/phaser.min.js"></script>

        <script src="src/game.js"></script>
    </head>
    <body>

    </body>
</html>

Reminder: micro commits, commit your index.html file right now!

You may have noticed that we added a reference to game.js located in the src folder. We don’t have that file yet, let’s create it now.

var game = new Phaser.Game(800, 600, Phaser.AUTO, '');

game.state.add('play', {
    preload: function() {
        game.load.image('skeleton', 'assets/allacrost_enemy_sprites/skeleton.png');
    },
    create: function() {
        var skeletonSprite = game.add.sprite(450, 290, 'skeleton');
        skeletonSprite.anchor.setTo(0.5, 0.5);
    },
    render: function() {
        game.debug.text('Adventure Awaits!', 250, 290);
    }
});

game.state.start('play');

In Phaser, everything starts with an instance of the Game class. We are passing it the width and height of the game screen that we want as well as the renderer. Phaser supports both Canvas and WebGL based rendering, Phaser.AUTO tells it to pick based on what’s available in the browser (WebGL if available).

In the preload phase of our “play” game state we are going to load up one of our monster images so that we can have something to show other than a blank screen. Each state in Phaser has several phases in its lifecycle, and preload  is one of the first.

Next up is create , after assets are loaded, it’s safe to create sprites using them. The Sprite is one of the main game objects in Phaser, most everything that you create in the game world will generally have a sprite involved. Adding a sprite takes a few parameters: the x & y coordinates of where it should be located on the screen, and a key that can be used to reference it later. We’re also going to change the anchor for the sprite to the center of the image. The anchor is the point in space where the sprite is positioned or rotated around. By default the anchor is set to the top left most point of the image 0, 0  I ususally like to work with the anchor in the center of the image, because if I want to spin the sprite, I want it to spin around the center instead of the top left (like a wheel).

Finally, render  is one of the last phases in the lifecycle, it happens after update (we don’t need update for this game). Most of the time Phaser handles rendering internally, but for now we’ll just add some fun text to make our screen more exciting.

Reminder: now’s a great time to commit your file!

Running your game

We’re almost ready to fire up Phaser and see what we have, except that it’s not just as simple as clicking on index.html and loading it in your browser. Due to security restrictions the browser will not allow you to load assets asynchronously. For that reason you need to run a server, or load the files in a different manner. PhotonStorm has posted an article listing several options for servers, however if loading the software to run a server isn’t something that you are interested in, I have another option. If you are running Google Chrome, you can actually setup your game to run as a Chrome application quite easily. Doing this elevates your game out of the browser sandbox (and actually gives you a set of APIs to access native systems such as the file system and networking) and these restrictions no longer apply. There are however a different set of security restrictions involving resources located outside of the files packaged with the app. Depending on how you want to distribute your final product, creating a Chrome app may be a great choice. I’ll include the basic files needed to launch this as a Chrome App, if you are interested in learning more I encourage you to read more at the official documentation.

Once you launch your game, you should see this:

New Phaser game with Skeleton and "Adventure Awaits" message

Now you know that Phaser is up and running. We’ve loaded a sprite and written a bit of text to the screen! We’re almost done 🙂 … well not quite, but we’re ready to start actually making a game.

Setting the Stage

The first thing that we want to do is get rid of that boring black background and bring our world to life. In the preload  method, add all of the images that make up the forest background. There happen to be four different images for this because it is designed to be used as a parallax scrolling background. Typically this type of background is used in side scrolling platformer games, but it gives us the option of doing an animation effect later.

this.game.load.image('forest-back', 'assets/parallax_forest_pack/layers/parallax-forest-back-trees.png');
this.game.load.image('forest-lights', 'assets/parallax_forest_pack/layers/parallax-forest-lights.png');
this.game.load.image('forest-middle', 'assets/parallax_forest_pack/layers/parallax-forest-middle-trees.png');
this.game.load.image('forest-front', 'assets/parallax_forest_pack/layers/parallax-forest-front-trees.png');

In the create  method since we have 4 different images that make up the background, we’ll create a Group of TileSprite objects. Using a javascript array of the image keys, we can use the built in forEach method to quickly and elegantly create all four in the correct order.

var state = this;

this.background = this.game.add.group();
// setup each of our background layers to take the full screen
['forest-back', 'forest-lights', 'forest-middle', 'forest-front']
    .forEach(function(image) {
        var bg = state.game.add.tileSprite(0, 0, state.game.world.width,
            state.game.world.height, image, '', state.background);
        bg.tileScale.setTo(4,4);
    });

A TileSprite is a type of image that is meant to be repeated or tiled over a large area. To create one you need to pass it not only the x & y coordinates, but also a width and height for how big the area that it needs to cover should be. Just like the Sprite, you give it the image key to use. The final parameter that we pass it is our group, so that each one is automatically added to the background group. We want the background to cover the whole screen, so we’ll pass in the game world’s width and height. Also, in this case, our image isn’t really meant to be tiled like a mosaic, so we’ll scale the tiling so that it looks more like one image (play with the scale numbers to see what I mean about the tiling).

Let’s take a moment to talk about the group that we created. Groups are an extremely powerful feature of Phaser that are capable of a whole lot more than just the name suggests. At the very base level, they act as a collection, sort of like an array, and they have several methods available for traversing and manipulating the items in the collection. Another important aspect of groups is that the children of the group are positioned, rotated, and scaled all relative to the group itself. If we set group.x = 10; then it will move all of the children over by 10 as well. The position of the children is relative meaning that if a child item also has it’s x coord set to 10, then it will actually be placed at x 20 on the screen (assuming that the group itself is not a child of another parent that isn’t at 0,0). We will use groups extensively in our game and I encourage you to read the documentation to find out more about all of the methods and properties that are available.

Reminder: time to commit your files!

The Army of Darkness

After setting the stage, the next thing we need is something to attack. Time to unleash the horde of monsters that we’ve collected. In order to be able to use all of our monsters, we need to load each image. Let’s change the preload  section of our play  state to do just that. Each one needs a key to reference it by, and the path to the image file.

    this.game.load.image('aerocephal', 'assets/allacrost_enemy_sprites/aerocephal.png');
    this.game.load.image('arcana_drake', 'assets/allacrost_enemy_sprites/arcana_drake.png');
    this.game.load.image('aurum-drakueli', 'assets/allacrost_enemy_sprites/aurum-drakueli.png');
    this.game.load.image('bat', 'assets/allacrost_enemy_sprites/bat.png');
    this.game.load.image('daemarbora', 'assets/allacrost_enemy_sprites/daemarbora.png');
    this.game.load.image('deceleon', 'assets/allacrost_enemy_sprites/deceleon.png');
    this.game.load.image('demonic_essence', 'assets/allacrost_enemy_sprites/demonic_essence.png');
    this.game.load.image('dune_crawler', 'assets/allacrost_enemy_sprites/dune_crawler.png');
    this.game.load.image('green_slime', 'assets/allacrost_enemy_sprites/green_slime.png');
    this.game.load.image('nagaruda', 'assets/allacrost_enemy_sprites/nagaruda.png');
    this.game.load.image('rat', 'assets/allacrost_enemy_sprites/rat.png');
    this.game.load.image('scorpion', 'assets/allacrost_enemy_sprites/scorpion.png');
    this.game.load.image('skeleton', 'assets/allacrost_enemy_sprites/skeleton.png');
    this.game.load.image('snake', 'assets/allacrost_enemy_sprites/snake.png');
    this.game.load.image('spider', 'assets/allacrost_enemy_sprites/spider.png');
    this.game.load.image('stygian_lizard', 'assets/allacrost_enemy_sprites/stygian_lizard.png');

In the create  method is where we’ll want to create Sprite objects for these images so that they can exist in the game world. Much like the background images, it’s faster and easier to read if we put all the information that we need to load into an array. This time however, we need more than just the image key. We’re going to want to display the name of the monster on the screen below it, so that the player knows what they are facing. To do this we’ll create an array of objects that has a name property suitable for display, as well as the image key.

var monsterData = [
    {name: 'Aerocephal', image: 'aerocephal'},
    {name: 'Arcana Drake', image: 'arcana_drake'},
    {name: 'Aurum Drakueli', image: 'aurum-drakueli'},
    {name: 'Bat', image: 'bat'},
    {name: 'Daemarbora', image: 'daemarbora'},
    {name: 'Deceleon', image: 'deceleon'},
    {name: 'Demonic Essence', image: 'demonic_essence'},
    {name: 'Dune Crawler', image: 'dune_crawler'},
    {name: 'Green Slime', image: 'green_slime'},
    {name: 'Nagaruda', image: 'nagaruda'},
    {name: 'Rat', image: 'rat'},
    {name: 'Scorpion', image: 'scorpion'},
    {name: 'Skeleton', image: 'skeleton'},
    {name: 'Snake', image: 'snake'},
    {name: 'Spider', image: 'spider'},
    {name: 'Stygian Lizard', image: 'stygian_lizard'}
];

After that, we’ll need to create the actual sprites for them in order to render them in the game world. Time for another group!

this.monsters = this.game.add.group();

var monster;
monsterData.forEach(function(data) {
    // create a sprite for them off screen
    monster = state.monsters.create(1000, state.game.world.centerY, data.image);
    // center anchor
    monster.anchor.setTo(0.5);
    // reference to the database
    monster.details = data;

    //enable input so we can click it!
    monster.inputEnabled = true;
    monster.events.onInputDown.add(state.onClickMonster, state);
});

When it comes to sprites, groups have a special method create that we can use. For other game objects we need to create them using the normal game factories, and add them as children to the group, the create method only works for sprites. It takes the normal sprite parameters; position and image key, but also lets you pass in a flag as to whether or not the sprite “exists”. This parameter is most often used in object pooling, which we’ll cover a bit later. Each sprite we’ll set the anchor to the center, and set a reference to our monsterData item so that we can reference it later (to display the name).

We’re also going to want to be able to click the monsters (it’s a *click*er game after all), we can tell Phaser to register click events by setting inputEnabled to true. Doing so will enable several input events, we’re interested in what happens when we click the mouse button down (or tap it). For that we’ll tell it to use the onClickMonster  method of our state, and that it should be called in the context of our state (javascript “this”). We haven’t created that method yet, we’ll do that in a minute.

In this game, we only ever want to face one monster at a time, so we need a reference to the monster that we are currently facing. Another cool feature of a group is that we can let Phaser randomly select one using getRandom() . Then set the position of the monster to roughly the center of the screen, a little off so that we have room for some other things later.

this.currentMonster = this.monsters.getRandom();
this.currentMonster.position.set(this.game.world.centerX + 100, this.game.world.centerY);

Next we can modify our render method so that we can show the name of the monster that we are up against.

render: function() {
    game.debug.text(this.currentMonster.details.name,
        this.game.world.centerX - this.currentMonster.width / 2,
        this.game.world.centerY + this.currentMonster.height / 2);
}

Finally, we need to add that onClickMonster  handler so that something happens when we click them. For now, we’ll just change out the monster on each click so that we can test running through our list (epic insta-kill!). Each click we’ll set the currentMonster to another random one, and position it in the center of the screen. We’ll move the other monster off screen so that we can’t see it at the same time.

onClickMonster: function() {
    // reset the currentMonster before we move him
    this.currentMonster.position.set(1000, this.game.world.centerY);
    // now pick the next in the list, and bring him up
    this.currentMonster = this.monsters.getRandom();
    this.currentMonster.position.set(this.game.world.centerX + 100, this.game.world.centerY);
},

Reminder: time to commit your files again!

Phaser 3 game with tentacle dragon enemy in scene

Clicking For Great Justice

Obviously just clicking to cycle through the monsters isn’t much of a gameplay element. Instead we need to simulate RPG combat by clicking and dealing damage to the monsters. In order to deal damage, we need to know something about our player. The main hero of this game isn’t directly represented by a sprite on the screen, so we will just create a plain javascript object to hold useful information about them. Add this to the bottom of the create phase:

// the main player
this.player = {
    clickDmg: 1,
    gold: 0
};

Also in order to be able to kill the monsters, they need to have some health to damage. Let’s go back to our monster database from before, and add a maxHealth attribute to each one. For now, for the values of maxHealth, I’ve just chosen somewhat arbitrary numbers, by looking at the sprite and just making a few tougher than the others. Later we can get deeper into gameplay and balance out the toughness of the monsters. I also adjusted the spacing so that it looks a little more like a table and is easier to edit.

var monsterData = [
    {name: 'Aerocephal',        image: 'aerocephal',        maxHealth: 10},
    {name: 'Arcana Drake',      image: 'arcana_drake',      maxHealth: 20},
    {name: 'Aurum Drakueli',    image: 'aurum-drakueli',    maxHealth: 30},
    {name: 'Bat',               image: 'bat',               maxHealth: 5},
    {name: 'Daemarbora',        image: 'daemarbora',        maxHealth: 10},
    {name: 'Deceleon',          image: 'deceleon',          maxHealth: 10},
    {name: 'Demonic Essence',   image: 'demonic_essence',   maxHealth: 15},
    {name: 'Dune Crawler',      image: 'dune_crawler',      maxHealth: 8},
    {name: 'Green Slime',       image: 'green_slime',       maxHealth: 3},
    {name: 'Nagaruda',          image: 'nagaruda',          maxHealth: 13},
    {name: 'Rat',               image: 'rat',               maxHealth: 2},
    {name: 'Scorpion',          image: 'scorpion',          maxHealth: 2},
    {name: 'Skeleton',          image: 'skeleton',          maxHealth: 6},
    {name: 'Snake',             image: 'snake',             maxHealth: 4},
    {name: 'Spider',            image: 'spider',            maxHealth: 4},
    {name: 'Stygian Lizard',    image: 'stygian_lizard',    maxHealth: 20}
];

Phaser sprites come with both Health and LifeSpan components built in that provide all of the features that we need in order to get combat working. They provide us with a damage()  and heal()  method and take into account health and maxHealth in those methods. When you apply damage and the health drops to 0 (or below) it will automatically call kill()  and fire the onKilled  event. Similarly, there is a  revive()  method that allows you to bring a monster back from the dead fully healed. When a monster is revived, it fires the onRevived event. We will hook into those events to drop loot and change monsters. Inside the loop that creates the monster sprites, let’s set the health component based on the value in our data array.

// use the built in health component
monster.health = monster.maxHealth = data.maxHealth;

// hook into health and lifecycle events
monster.events.onKilled.add(state.onKilledMonster, state);
monster.events.onRevived.add(state.onRevivedMonster, state);

Next update the onClickMonster  method to deal damage to the monster based on the player’s clickDmg  attribute. When the monster’s health reaches 0, it will be killed.

onClickMonster: function(monster, pointer) {
    // apply click damage to monster
    this.currentMonster.damage(this.player.clickDmg);
}

Clicking on a monster will do damage, but it’s important to provide feedback to the player that this is happening. No one likes to click things and see nothing happen, it feels broken. Also, I think it’s time to get rid of the debug text and use an actual text object to display the monster’s name and health. Add these 2 Text objects to your create method. Again we’ll create another group so that moving the monster information around is easy. Creating Text objects is relatively straight forward, like most display objects you provide it the position on the screen (or relative to its parent), but instead of an image key, you pass it the string that you want to display. Optionally you can send in font styling data to change how it’s displayed. This font style information is very similar to standard HTML Canvas fonts.

this.monsterInfoUI = this.game.add.group();
this.monsterInfoUI.position.setTo(this.currentMonster.x - 220, this.currentMonster.y + 120);
this.monsterNameText = this.monsterInfoUI.addChild(this.game.add.text(0, 0, this.currentMonster.details.name, {
    font: '48px Arial Black',
    fill: '#fff',
    strokeThickness: 4
}));
this.monsterHealthText = this.monsterInfoUI.addChild(this.game.add.text(0, 80, this.currentMonster.health + ' HP', {
    font: '32px Arial Black',
    fill: '#ff0000',
    strokeThickness: 4
}));

Back in our onClickMonster  event, we want to update the text now to reflect the monster’s new health.

// update the health text
this.monsterHealthText.text = this.currentMonster.alive ? this.currentMonster.health + ' HP' : 'DEAD';

When a monster is killed it fires the onKilled  event, we want to push it back off screen and then select a new monster and revive them. The revive method optionally takes a health parameter that will set the health of the monster to the value provided. It then sets alive, visible, and exists to true, and then fires the onRevived event. Add the onKilledMonster  method to our state now.

onKilledMonster: function(monster) {
    // move the monster off screen again
    monster.position.set(1000, this.game.world.centerY);

    // pick a new monster
    this.currentMonster = this.monsters.getRandom();
    // make sure they are fully healed
    this.currentMonster.revive(this.currentMonster.maxHealth);
},

When a monster is revived, we want to get them into position on the screen, and reset the monster display text to reflect the new monster. After the kill handler, let’s add the onRevivedMonster  event handler to our state as well. Here we move the monster to the center area of the screen and update our text objects to reflect the new information.

onRevivedMonster: function(monster) {
    monster.position.set(this.game.world.centerX + 100, this.game.world.centerY);
    // update the text display
    this.monsterNameText.text = monster.details.name;
    this.monsterHealthText.text = monster.health + 'HP';
},

Ok, now we can see what is happening, and that is good. It still doesn’t quite feel exciting enough though, I think we can add more. For every click, let’s display the damage that we’re doing. For that, we’ll want to create a pool of text objects. Each click we need to display the damage number for a short period and then it should disappear. Instead of creating a new text object for each click (which we could do), it’s better to create a bunch up front and just change the properties. The reason is that in almost all programming situations, especially in JavaScript, creating new objects is an expensive operation. Not something that you want to be doing a lot of every frame. Let’s create a pool of about 50 text objects (I think I can do 30 clicks / second so that’s a decent buffer). The following should go in your create  method.

this.dmgTextPool = this.add.group();
var dmgText;
for (var d=0; d<50; d++) {
    dmgText = this.add.text(0, 0, '1', {
        font: '64px Arial Black',
        fill: '#fff',
        strokeThickness: 4
    });
    // start out not existing, so we don't draw it yet
    dmgText.exists = false;
    dmgText.tween = game.add.tween(dmgText)
        .to({
            alpha: 0,
            y: 100,
            x: this.game.rnd.integerInRange(100, 700)
        }, 1000, Phaser.Easing.Cubic.Out);

    dmgText.tween.onComplete.add(function(text, tween) {
        text.kill();
    });
    this.dmgTextPool.add(dmgText);
}

As you can see in order to create a pool of damage text objects to use we didn’t have to do anything special. We used the groups that we already know and love. A standard for loop will help us create 50 of them, and we’ll set them all to exists = false  so that they don’t render on the screen until we tell them to. Next, we’re going to add another super powerful tool in Phaser’s arsenal, a Tween. A tween allows you to modify various properties of an object over time. It uses one of several mathematical equations to “ease” these values from start to finish and create animation effects. For the damage text, we want it to fly out from where it was clicked in a random direction and also fade out so that by the time that it reaches its destination, it can no longer be seen. In the to  method of the tween, we set the final values that we want the alpha, y and x properties of the object to be, the starting values will be the values of the object when the tween begins. The second parameter is the time that it should take to complete the tween, we’ll set it to 1000 (the value is in milliseconds, so 1 second). The final parameter is the Easing equation that we want to use. When a tween animation is completed, an event is fired, we can hook into there and kill()  the text object (effectively setting it back to exists = false ).

Now we’ll turn these on so that clicking to do damage is really exciting. Every time we click, we’ll grab the first available dmgText object (i.e. not killed) from the group using getFirstExists(false) , the false tells the group that we want one that doesn’t exist. Then update the text to reflect the current click damage. We need to reset the alpha property from when the tween had adjusted it, and we want to start this one at the spot where the player clicked. Then we’ll start the tween again, and get our animation.

// grab a damage text from the pool to display what happened
var dmgText = this.dmgTextPool.getFirstExists(false);
if (dmgText) {
    dmgText.text = this.player.clickDmg;
    dmgText.reset(pointer.positionDown.x, pointer.positionDown.y);
    dmgText.alpha = 1;
    dmgText.tween.start();
}

Reminder: commit that code!

Demonic Essence enemy with damage displayed from attack

Phat Lootz

Killing monsters isn’t something that the player does just for sport, they’re in it for the rewards of gold and treasure. We need to drop some loot when the monster dies, let’s add a gold coin to our images loading in the preload method.

this.game.load.image('gold_coin', 'assets/496_RPG_icons/I_GoldCoin.png');

To start with, every monster will drop a single gold coin when it dies. The player will need to click on them to collect them, and so there could be quite a few laying around before they decide to do that. To create a pool of gold coins, again we’ll utilize the group. This time, since we’re creating a pool of sprites, we can use a special method called createMultiple. This method is very similar to the create  method in that it only creates sprites, for this one, it takes a new parameter, the number that you want to create. Since we’re not using a for loop this time to create them, we need a way to setup some defaults without having to loop through our newly created group, for that, we have another method called setAll. It takes the property and value and applies that to each object in the group. We also want to register the onInputDown handler, since adding a handler to an event is a method, we use callAll to execute the events.onInputDown.add  method on each child of the group.

// create a pool of gold coins
this.coins = this.add.group();
this.coins.createMultiple(50, 'gold_coin', '', false);
this.coins.setAll('inputEnabled', true);
this.coins.setAll('goldValue', 1);
this.coins.callAll('events.onInputDown.add', 'events.onInputDown', this.onClickCoin, this);

Again we need feedback in the UI so that we know that we are collecting gold. Add this text object to the create  method.

this.playerGoldText = this.add.text(30, 30, 'Gold: ' + this.player.gold, {
    font: '24px Arial Black',
    fill: '#fff',
    strokeThickness: 4
});

Now we can add our click handler for the coins. When a coin is clicked, the goldValue  of the coin is added to the player’s gold. We also have to update the UI so that we can see the change. Finally, we kill the coin so that it disappears back into our pool for reuse.

onClickCoin: function(coin) {
    // give the player gold
    this.player.gold += coin.goldValue;
    // update UI
    this.playerGoldText.text = 'Gold: ' + this.player.gold;
    // remove the coin
    coin.kill();
}

Next we need to add to the onKilledMonster  event so that we can actually drop these coins. Much like the dmgText objects, we’ll grab the first available coin and bring it to life positioning it somewhere randomly in the center-ish of the screen. We update the goldValue (even though we’re just setting it to 1 now) so that in the future we can drop different amounts of gold as we progress.

var coin;
// spawn a coin on the ground
coin = this.coins.getFirstExists(false);
coin.reset(this.game.world.centerX + this.game.rnd.integerInRange(-100, 100), this.game.world.centerY);
coin.goldValue = 1;

Dune Crawler enemy with Gold amount displayed in the upper left corner

As I mentioned earlier, the player has to click on the coins in order to collect them. After a few kills, if they don’t do that, the floor will become quite littered with gold. While piles of cash is always fun, eventually we might run out of new coins to spawn from our pool. What we need to do is automatically collect gold for the player after a short time so that the world doesn’t become cluttered.

To accomplish this, Phaser has a Timer object that we can use to create our own custom timed events. If the coin sits there not being clicked for 3 seconds, then we’ll “click” it for them, by firing the same onClickCoin  method that we use when they do click it. The timer event takes the duration, the handler, the context that the handler should fire in, and any other additional parameters that should be passed to the handler.

this.game.time.events.add(Phaser.Timer.SECOND * 3, this.onClickCoin, this, coin);

Since we are going to be calling the onClickCoin  method when the timer completes in addition to when the coin is clicked, we need to test and make sure that we don’t call it twice. If the player clicks the coin before the timeout, the timeout will still fire, but the gold will already be collected, and the coin already killed. We can add a simple test at the top of the function to make sure that when we collect this coin it is still alive.

if (!coin.alive) {
    return;
}

Reminder: commit the source, save your work!

Upgrades

I’m sure by now you’re tired of doing just 1 point of damage every click, and we’ve got nothing to spend our precious gold on! Time to create some upgrades. The upgrades menu is going to be a box, with some buttons inside that you can click on to buy things. For the background of the upgrades menu, we could use more art from the web, or create an image ourselves in a paint program, but instead we can utilize the HTML5 Canvas to build it for us. Instead of loading an image, Phaser has an object called BitmapData that creates a canvas for us. The result of the canvas can then be used in place of an image on a sprite. Instead of setting the key when it is loaded like with an image, instead we need to manually add it to Phaser’s asset cache. In the preload  method we will generate images (colored rectangles) for the background of the upgrades menu and also the buttons.

// build panel for upgrades
var bmd = this.game.add.bitmapData(250, 500);
bmd.ctx.fillStyle = '#9a783d';
bmd.ctx.strokeStyle = '#35371c';
bmd.ctx.lineWidth = 12;
bmd.ctx.fillRect(0, 0, 250, 500);
bmd.ctx.strokeRect(0, 0, 250, 500);
this.game.cache.addBitmapData('upgradePanel', bmd);

var buttonImage = this.game.add.bitmapData(476, 48);
buttonImage.ctx.fillStyle = '#e6dec7';
buttonImage.ctx.strokeStyle = '#35371c';
buttonImage.ctx.lineWidth = 4;
buttonImage.ctx.fillRect(0, 0, 225, 48);
buttonImage.ctx.strokeRect(0, 0, 225, 48);
this.game.cache.addBitmapData('button', buttonImage);

For the upgrades menu, we don’t need something as heavy as a sprite (with all the health and other stuff). Instead for things that are going to be purely user interface objects, it is better to use a Image. An Image object has the same transform information (position, scale, rotation) just not all the extra things that a sprite does. Instead of passing in an image key, we’ll pull the image out of the cache that we put it into earlier. The menu panel will also contain a group for the buttons, that way all of the buttons can follow the menu and be relative to its transforms. Because of the border on the background image, we’ll move the button group in a little bit.

this.upgradePanel = this.game.add.image(10, 70, this.game.cache.getBitmapData('upgradePanel'));
var upgradeButtons = this.upgradePanel.addChild(this.game.add.group());
upgradeButtons.position.setTo(8, 8);

Stygian Lizard enemy with newly added upgrade frame

Our first upgrade will be to the click damage so we can start killing faster. Let’s pick an icon from our library and add that to our image load.

this.game.load.image('dagger', 'assets/496_RPG_icons/W_Dagger002.png');

Phaser has another object in its bag of tricks, the Button object. A button is a subclass of an Image object that is designed to handle being clicked out of the box. It supports 4 different button states: Out, Over, Down, and Up. You can provide a spritesheet image with different looks for each of these states, it can make the button appear to actually be “pressed” for example, or change color when you hover over top of it. I’ve only generated a single background frame for our buttons for now, it still works fine without the other images. For the button we are going to add the icon, a label for what the upgrade is, and another text to display the gold cost for upgrading.

var button;
button = this.game.add.button(0, 0, this.game.cache.getBitmapData('button'));
button.icon = button.addChild(this.game.add.image(6, 6, 'dagger'));
button.text = button.addChild(this.game.add.text(42, 6, 'Attack: ' + this.player.clickDmg, {font: '16px Arial Black'}));
button.details = {cost: 5};
button.costText = button.addChild(this.game.add.text(42, 24, 'Cost: ' + button.details.cost, {font: '16px Arial Black'}));
button.events.onInputDown.add(this.onUpgradeButtonClick, this);

After creating the button, then add it to the buttons group.

upgradeButtons.addChild(button);

For now our button handler simply needs to test the one button that we have. First we’ll check that we can afford to purchase the upgrade, if we can then we’ll go through with it. We need to adjust the player’s gold from the cost, and update the UI to reflect that change. We also need to improve the player’s clickDmg attribute, and update the text on the button. Now we can spend our hard earned loot to get stronger!

onUpgradeButtonClick: function(button, pointer) {
    if (this.player.gold - button.details.cost >= 0) {
        this.player.gold -= button.details.cost;
        this.playerGoldText.text = 'Gold: ' + this.player.gold;
        this.player.clickDmg++;
        button.text.text = 'Attack: ' + this.player.clickDmg;
    }
}

Aerocephal enemy with Attack 21 as an upgrade

Now it’s time to add the second type of upgrade, the DPS upgrade. Until now the only way to deal damage to monsters is by directly clicking on them. While this is an important mechanic in our game, it can get tedious after a while. This is the part that makes this type of game fall into the “idle” genre. Players will continue to progress and deal damage to monsters even when they are not actively clicking them.

In order to add a new button, we need to repeat what we have, and change the effect of purchasing the upgrade. Doing this one button at a time will get unruly after a bit, so we want to create a database array of upgrades, just like we have for monsters. We’ll need the icon to display, the name of the upgrade, the level for the number of times that it has been upgraded, the cost in gold to upgrade, and a callback function that we can fire to provide a different effect for each upgrade.

var upgradeButtonsData = [
    {icon: 'dagger', name: 'Attack', level: 1, cost: 5, purchaseHandler: function(button, player) {
        player.clickDmg += 1;
    }},
    {icon: 'swordIcon1', name: 'Auto-Attack', level: 0, cost: 25, purchaseHandler: function(button, player) {
        player.dps += 5;
    }}
];

We need to add the dps property to our player, so that our purchase handler can take effect.

this.player = {
    clickDmg: 1,
    gold: 0,
    dps: 0
};

Now we can loop through our data and create all of our upgrade buttons in bulk. Because the buttons are about 48 pixels high, we’ll separate each one by 50. Instead of hard coding the text strings and icon, they will be populated from the data.

var button;
upgradeButtonsData.forEach(function(buttonData, index) {
    button = state.game.add.button(0, (50 * index), state.game.cache.getBitmapData('button'));
    button.icon = button.addChild(state.game.add.image(6, 6, buttonData.icon));
    button.text = button.addChild(state.game.add.text(42, 6, buttonData.name + ': ' + buttonData.level, {font: '16px Arial Black'}));
    button.details = buttonData;
    button.costText = button.addChild(state.game.add.text(42, 24, 'Cost: ' + buttonData.cost, {font: '16px Arial Black'}));
    button.events.onInputDown.add(state.onUpgradeButtonClick, state);

    upgradeButtons.addChild(button);
});

When we click an upgrade button now we need to increase its level and update the text to reflect the change. Then we’ll execute the purchaseHandler callback in the context of the state, passing the button and player along to the handler.

onUpgradeButtonClick: function(button, pointer) {
    if (this.player.gold - button.details.cost >= 0) {
        this.player.gold -= button.details.cost;
        this.playerGoldText.text = 'Gold: ' + this.player.gold;
        button.details.level++;
        button.text.text = button.details.name + ': ' + button.details.level;
        button.details.purchaseHandler.call(this, button, this.player);
    }
}

Ok, so we’re increasing both attack and dps (damage per second), but we haven’t setup dps to do anything yet. For dps to make sense, if we have 1 dps then after 1 second has passed we do 1 damage. Waiting the full second to apply any damage at all though is too choppy and slow. Instead we’ll update at 100ms (10 times a second). So, in order to apply 1 damage after 1 second, then we need to apply 0.10 damage every 100ms. Similar to the timer event that we used for the gold coins, there are also loop events that will repeat and call the handler at the duration over and over.

// 100ms 10x a second
this.dpsTimer = this.game.time.events.loop(100, this.onDPS, this);

Our dps handler is going to get called every 100ms whether we have upgraded or not. So we check if we have something to do first, if so, then make sure the monster is still alive to apply the damage. Then we’ll damage the monster and update the text to reflect the monster’s health. I don’t really want to display the decimals that might occur on the monster health from doing 10% damage, so we’ll round it for the display (not the actual health).

onDPS: function() {
    if (this.player.dps > 0) {
        if (this.currentMonster && this.currentMonster.alive) {
            var dmg = this.player.dps / 10;
            this.currentMonster.damage(dmg);
            // update the health text
            this.monsterHealthText.text = this.currentMonster.alive ? Math.round(this.currentMonster.health) + ' HP' : 'DEAD';
        }
    }
}

Reminder: don’t forget to commit!

Progression

Killing the same monsters over and over is boring. We need to keep increasing the difficulty so that the players can face a challenge and progress. Let’s add some world level stats to the preload  section.

// world progression
this.level = 1;
// how many monsters have we killed during this level
this.levelKills = 0;
// how many monsters are required to advance a level
this.levelKillsRequired = 10;

Each time we kill a monster now, we need to increase the kills stat. We also need to upgrade the monster’s health based on the level. With increased risk, comes increased reward, and we’ll also modify the coin value based on the world level as well. After 10 monsters have been killed, then we can progress to the next level.

onKilledMonster: function(monster) {
    // move the monster off screen again
    monster.position.set(1000, this.game.world.centerY);

    var coin;
    // spawn a coin on the ground
    coin = this.coins.getFirstExists(false);
    coin.reset(this.game.world.centerX + this.game.rnd.integerInRange(-100, 100), this.game.world.centerY);
    coin.goldValue = Math.round(this.level * 1.33);
    this.game.time.events.add(Phaser.Timer.SECOND * 3, this.onClickCoin, this, coin);

    this.levelKills++;

    if (this.levelKills >= this.levelKillsRequired) {
        this.level++;
        this.levelKills = 0;
    }

    // pick a new monster
    this.currentMonster = this.monsters.getRandom();
    // upgrade the monster based on level
    this.currentMonster.maxHealth = Math.ceil(this.currentMonster.details.maxHealth + ((this.level - 1) * 10.6));
    // make sure they are fully healed
    this.currentMonster.revive(this.currentMonster.maxHealth);
}

Since we’ll be getting a lot more money now, we also need to adjust the upgrade prices.

onUpgradeButtonClick: function(button, pointer) {
    // make this a function so that it updates after we buy
    function getAdjustedCost() {
        return Math.ceil(button.details.cost + (button.details.level * 1.46));
    }

    if (this.player.gold - getAdjustedCost() >= 0) {
        this.player.gold -= getAdjustedCost();
        this.playerGoldText.text = 'Gold: ' + this.player.gold;
        button.details.level++;
        button.text.text = button.details.name + ': ' + button.details.level;
        button.costText.text = 'Cost: ' + getAdjustedCost();
        button.details.purchaseHandler.call(this, button, this.player);
    }
}

Finally, we’ll add the level information to the UI so that the player knows how they are doing. By now adding text objects to reflect this information should be old hat to you!

// setup the world progression display
this.levelUI = this.game.add.group();
this.levelUI.position.setTo(this.game.world.centerX, 30);
this.levelText = this.levelUI.addChild(this.game.add.text(0, 0, 'Level: ' + this.level, {
    font: '24px Arial Black',
    fill: '#fff',
    strokeThickness: 4
}));
this.levelKillsText = this.levelUI.addChild(this.game.add.text(0, 30, 'Kills: ' + this.levelKills + '/' + this.levelKillsRequired, {
    font: '24px Arial Black',
    fill: '#fff',
    strokeThickness: 4
}));

We also need to update the level text when it changes inside the  onKilledMonster  method.

this.levelText.text = 'Level: ' + this.level;
this.levelKillsText.text = 'Kills: ' + this.levelKills + '/' + this.levelKillsRequired;

Spider enemy with various upgrades in Phaser 3 game

Reminder: commit commit commit

Finished the basics, what’s next?

What we’ve created here is a complete idle clicker RPG. Well, complete as in it’s playable. There’s still tons left to do in order to get this game turned into something that is really fun. In game development, they say that the last 10% of the work is the last 90% of your time. We’re pretty much 90% done I think 🙂

Here’s a list of things that would be great to add: (possibly in future tutorials)

  • monsters with animation
  • sounds & music!
  • more upgrades
  • critical hits
  • boss monsters
  • timed boost powers
  • different world backgrounds
  • achievements
  • leader boards

I hope that you have enjoyed this tutorial and making this game!

Please leave comments and questions below, I welcome any feedback and would love to see your games too!

]]>
Create a Loading Screen in Phaser 3 – Web Games Tutorial https://gamedevacademy.org/creating-a-preloading-screen-in-phaser-3/ Sun, 17 Apr 2022 10:13:19 +0000 https://gamedevacademy.org/?p=6656 Read more]]> Have you ever played a game where you met with a blank, black screen while things loaded?

Sometimes, there isn’t getting around loading screens for your game, especially as your game gets larger and larger. Loading screens exist to provide players with important feedback – not only to indicate what the game is doing but also so players don’t think the game crashed.

In this tutorial, we’re going to cover how to make a loading screen for Phaser 3 games – an important skill considering these games loading are at the will of your internet connection.

If you’re ready to provide better UI-based user experiences, let’s start learning.

Intro and Projects Files

One of the things that almost all games have in common is a loading screen, which can be used to inform the player how long they must wait to play the game. Even though no one likes waiting to play a game, a loading screen is a valuable tool. Instead of having players stare at a blank screen, the loading screen can be used to inform the player how much longer they have to wait, or at minimum let the player know the game is doing something.

In Phaser, before you can use any assets, you must first load them in preload function of the scene. If you load a large number of assets, it can take some time for all of the assets to be loaded into the game, and this is where a preloader really makes a difference.

The goal of this tutorial is to teach you the basics of creating a preloading screen by creating a progress bar that will dynamically update as the game loads the assets. You can see what we will be creating below:

You can download all of the files associated with the source code here:

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

Learn Phaser 3 with our newest Mini-Degree

The HTML5 Game Development Mini-Degree is now available for Pre-Order on Zenva Academy. Learn to code and make impressive games with JavaScript and Phaser 3!

Get Instant Early Access

Project Setup

In order to run your Phaser game locally, you will need a web server for running your game. If you don’t already have this setup, you can read how to do that here: Getting Start With Phaser. You will also need an IDE or Text Editor for writing your code. If you don’t already have one, I would recommend the Brackets editor since it is easy to use, and it has a feature called Live Preview that will allow you to run your Phaser game without installing a web server.

Once you have these setup, we will setup the basic code for our game. Open your IDE, and create a new file called index.html. We are going to create a basic html page, add a reference to Phaser, and create our Phaser game object. In index.html, add the following code:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
</head>

<body>
    <script src="//cdn.jsdelivr.net/npm/phaser@3.0.0/dist/phaser.min.js"></script>
    <script type="text/javascript">
        // The game config that is used by Phaser
        var config = {
            type: Phaser.AUTO,
            parent: 'phaser-example',
            width: 800,
            height: 600,
            scene: {
                preload: preload,
                create: create
            }
        };

        // Create a new Phaser Game object
        var game = new Phaser.Game(config);

        function preload() {
        }

        function create() {
        }

    </script>
</body>

</html>

Let’s review the code we just added:

  • We created the configuration that will be used for our Phaser game.
  • In the config object, in the type field, we set the renderer type for our game. The two main types are Canvas and WebGL. WebGL is a faster renderer and has better performance, but not all browsers support it. By choosing AUTO for the type, Phaser will use WebGL if it is available, otherwise it will use Canvas.
  • In the config object, the parent field is used to tell Phaser to render our game in an existing <canvas>  element with that id if it exists. If it does not exists, then Phaser will create a <canvas>  element for us.
  • In the config object, we specify the width and height of the viewable area of our game.
  • In the config object, we embedded a scene object which will use the preload  and create functions we defined.
  • Lastly, we passed our config object to Phaser when we created the new game instance.

If you try running your game, you should see a black screen, and if you open the console in the developer tools, you should see a log with the version of Phaser your game is running.

Loading Our Assets

Now that our project is setup, we can get started. Before we can create our preloader, we will need to load some assets into our game. To keep things simple, we are going to use one image and reload it a few times to simulate loading a large number of assets. The asset for the game can be downloaded here.

You will need to place the image in same folder as index.html.

To load our image and display it in our game, you will need to update the preload  and create  functions in index.html:

function preload() {
    this.load.image('logo', 'zenvalogo.png');
    for (var i = 0; i < 500; i++) {
        this.load.image('logo'+i, 'zenvalogo.png');
    }
}

function create() {
    var logo = this.add.image(400, 300, 'logo');
}


If you reload your game in the browser, you should see the logo appear in your game.

Creating the Preloader

With our assets loaded, it is time to create our preloader. In the preload  function, add the following code:

this.load.on('progress', function (value) {
    console.log(value);
});
            
this.load.on('fileprogress', function (file) {
    console.log(file.src);
});

this.load.on('complete', function () {
    console.log('complete');
});


This code creates a few event listeners that will listen for the progress, fileprogress, and complete events that are emitted from Phaser’s LoaderPlugin. The progress  and fileprogress events will be emitted every time a file has been loaded, and the complete event will only be emitted once all the files are done loading.

When the progress  event is emitted, you will also receive a value between 0 and 1, which can be used track the overall progress of the loading process. When the fileprogress  event is emitted, you will also receive an object containing information on the file that was just loaded. Both of these can be used to create custom preloader with the information that is provided.

Here is an example of the data that is sent:

For the preloader, we will use Phaser’s GameObject.Graphics to create the progress bar. In the preload  function, add the following code at the top of the function, above the code you already added:

var progressBar = this.add.graphics();
var progressBox = this.add.graphics();
progressBox.fillStyle(0x222222, 0.8);
progressBox.fillRect(240, 270, 320, 50);

Then, update the progress  event listener in the preload  function with the following code:

this.load.on('progress', function (value) {
    console.log(value);
    progressBar.clear();
    progressBar.fillStyle(0xffffff, 1);
    progressBar.fillRect(250, 280, 300 * value, 30);
});


In the code above, we are creating two separate rectangles, progressBar and progressBox. The progressBox rectangle is going to be used as a border/container around the progressBar, and the progressBar will be used to track the overall percentage of the assets being loaded. We are doing this by calculating the width of the rectangle to be based on the progress value we are receiving. So, every time we receive the progress event, we should see the rectangle grow.

If you reload the game, you should see a nice progress bar that fills up as the assets are being loaded. However, there is one problem with it. When the all of the assets are loaded, the preloader is staying on the screen, and the logo image is being loaded over top of it. To fix this, we can update the complete event listener to destroy our preloader once all assets are loaded.

In the complete event listener, add the following code below the console.log():

progressBar.destroy();
progressBox.destroy();


Now, if you reload your game, the progress bar should disappear before the logo image is displayed on the screen.

Adding Some Text

We have the main part of our preloader done, but we can easily enhance the preloader by adding some additional text to it. First, we will add a simple ‘Loading…’ message to the preloader. In the preload function, add the following code below the progressBox lines:

var width = this.cameras.main.width;
var height = this.cameras.main.height;
var loadingText = this.make.text({
    x: width / 2,
    y: height / 2 - 50,
    text: 'Loading...',
    style: {
        font: '20px monospace',
        fill: '#ffffff'
    }
});
loadingText.setOrigin(0.5, 0.5);


Then, in the complete event listener, add the following code:

loadingText.destroy();


Let’s review what we just added:

  • We created two new variables, width and height. These variables are getting the width and height of the current viewable area of our game.
  • We created a new Phaser Text GameObject called loadingText. This game object is using the width and height variables we just created, and we set the style and default text of the game object.
  • We set the origin of the game object to be (0.5, 0.5), which will help center our game object.
  • Lastly, we updated the complete event listener to destroy our loading text once all the games assets were loaded.

If you reload your game, your screen should look like this:

Next, we are going to add some additional text that will display the percent of the loading bar. To do this, we just need to create another text game object, and update the text to use the value that is being sent to the progress event listener. In the preload function add the following code below the loadingText code:

var percentText = this.make.text({
    x: width / 2,
    y: height / 2 - 5,
    text: '0%',
    style: {
        font: '18px monospace',
        fill: '#ffffff'
    }
});
percentText.setOrigin(0.5, 0.5);


Now, in the progress event listener, add the following code above the progressBar code:

percentText.setText(parseInt(value * 100) + '%');


Lastly, in the  complete function add the following code:preload 

percentText.destroy();


Here is a quick summary of what we just did:

  • Created a new Phaser Text GameObject called percentText.
  • We set the origin to (0.5, 0.5) to help center the object.
  • In the progress event listener, we are updating the text of the object, every time a file is loaded. We are multiplying the value by 100 since the value that is emitted is between 0 and 1.
  • Lastly, we updated the complete event listener to destroy the object.

If you reload your game, you should see the progress bar percentage update as the progress bar fills up.

With the progress bar now showing the percentage, we will now add some text to display which asset has been loaded. Once again, we will create another text game object and we will update the text of the game object with the file data that is being sent to the fileprogress event listener. In the preload function add the following code below the percentText code:

var assetText = this.make.text({
    x: width / 2,
    y: height / 2 + 50,
    text: '',
    style: {
        font: '18px monospace',
        fill: '#ffffff'
    }
});
assetText.setOrigin(0.5, 0.5);


Then, in the fileprogress event listener, add the following code:

assetText.setText('Loading asset: ' + file.key);


Lastly, in the  complete function add the following code:

assetText.destroy();


Now, if you reload your game, you should see the asset text being updated as each asset is loaded.

For this example, we ended up outputting the asset key instead of the file name since we are only loading the one image. If you want to output the file name, you can update the following line:

assetText.setText('Loading asset: ' + file.key);


to be:

assetText.setText('Loading asset: ' + file.src);


Here is the completed index.html file:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
</head>

<body>
    <script src="//cdn.jsdelivr.net/npm/phaser@3.0.0/dist/phaser.min.js"></script>
    <script type="text/javascript">
        var config = {
            type: Phaser.AUTO,
            parent: 'phaser-example',
            width: 800,
            height: 600,
            scene: {
                preload: preload,
                create: create
            }
        };

        var game = new Phaser.Game(config);

        function preload() {
            var progressBar = this.add.graphics();
            var progressBox = this.add.graphics();
            progressBox.fillStyle(0x222222, 0.8);
            progressBox.fillRect(240, 270, 320, 50);
            
            var width = this.cameras.main.width;
            var height = this.cameras.main.height;
            var loadingText = this.make.text({
                x: width / 2,
                y: height / 2 - 50,
                text: 'Loading...',
                style: {
                    font: '20px monospace',
                    fill: '#ffffff'
                }
            });
            loadingText.setOrigin(0.5, 0.5);
            
            var percentText = this.make.text({
                x: width / 2,
                y: height / 2 - 5,
                text: '0%',
                style: {
                    font: '18px monospace',
                    fill: '#ffffff'
                }
            });
            percentText.setOrigin(0.5, 0.5);
            
            var assetText = this.make.text({
                x: width / 2,
                y: height / 2 + 50,
                text: '',
                style: {
                    font: '18px monospace',
                    fill: '#ffffff'
                }
            });

            assetText.setOrigin(0.5, 0.5);
            
            this.load.on('progress', function (value) {
                percentText.setText(parseInt(value * 100) + '%');
                progressBar.clear();
                progressBar.fillStyle(0xffffff, 1);
                progressBar.fillRect(250, 280, 300 * value, 30);
            });
            
            this.load.on('fileprogress', function (file) {
                assetText.setText('Loading asset: ' + file.key);
            });

            this.load.on('complete', function () {
                progressBar.destroy();
                progressBox.destroy();
                loadingText.destroy();
                percentText.destroy();
                assetText.destroy();
            });
            
            this.load.image('logo', 'zenvalogo.png');
            for (var i = 0; i < 5000; i++) {
                this.load.image('logo'+i, 'zenvalogo.png');
            }
        }

        function create() {
            var logo = this.add.image(400, 300, 'logo');
        }

    </script>
</body>

</html>


You can download the completed example here.

Conclusion

With the asset text now being displayed, this brings this tutorial to a close. As you can see, adding a preloader to your game is a great solution when you will be loading a large number of assets, and you want to keep the players informed of the games current state. With Phaser, it is really easy to add a simple preloader and you can easily extend these examples to create a more complex preloader.

I hoped you enjoyed this tutorial and found it helpful. If you have any questions, or suggestions on what we should cover next, let us know in the comments below.

]]>
How to Make an HTML5 Game https://gamedevacademy.org/how-to-make-a-html5-game/ Thu, 06 Jan 2022 09:30:39 +0000 https://gamedevacademy.org/?p=1585 Read more]]> Although Flash games have departed from this world, there is still a significant demand for browser-based and cross-platform games. Whether you yourself actively play them or not, more and more games from professional and indie developers alike come out each day.

This phenomenon is largely thanks to HTML5 games which have filled the gap to keep up with these eager gamers. In addition, thanks to the advancement of technology and new frameworks, HTML5 game development has reached extensive heights, allowing for multiplayer experiences, 3D graphics, and more! It is not unwise to say that gaming is now just as viable via a browser as it is on many other devices!

Assuming this sounds like an exciting prospect to you as a game developer, in this guide we’re going to delve into the topic of HTML5 game development and give you the run-down of how you can make your own games! Sit back, relax, and prepare to enhance your game development skills in entirely new ways!

What exactly is an HTML5 game?

Let’s start from total zero. What is HTML5? that’s a tricky question. There is an official definition of HTML5, which simply stands for the latest revision of HTML (the markup language used all over the world to build websites), and the more hyped definition (what most people understand when HTML5 is mentioned) which is all the “new” features of the web technologies that have come out in the last few years (JavaScript API’s like the Canvas or WebAudio, semantic HTML tags, etc).

For our purpose, we’ll use bits of the two. HTML5 is HTML in its latest version, which includes a whole bunch of cool features that make web technologies an open standard with endless possibilities combining HTML, CSS and JavaScript.

Having HTML along with all these superpowers that go beyond making a simple website allows us to make, among other things, games. These are HTML5 games.

BUILD YOUR OWN GAMES

Get 250+ coding courses for

$1

AVAILABLE FOR A LIMITED TIME ONLY

 Building blocks

The very basic building blocks of a HTML5 game are those of the web:

  • HTML
  • CSS
  • JavaScript

Similarly to what happens with HTML5, when people talk about CSS3 they usually refer to the new things that come with CSS’s latest specifications, but in an analog manner, CSS3 is simply the latest CSS. Ignoring for a second the semantics of these definitions and thinking of the hyped versions of these terms, we also may need, in order to make HTML5 games:

  • HTML5 (JavaScript API’s)
  • CSS3

With the above you can make awesome games that will run on modern web browsers on mobile and desktop, but some games might require more features, so there are more building blocks that you can add.

For instance, you may want to make 3D games. If that is the case there is also WebGL, which is a JavaScript API to render 2D and 3D graphics on the browser, using the GPU for greater performance.

Road crossing game made with HTML5

Server side

If you want your games to saved data remotely you’ll need a server-side for your game. You can develop your own backend using any server-side language, you’ll need well a server in this case.

  • JavaScript (NodeJS)
  • PHP
  • Java
  • Python
  • Ruby

Or you can use a third-party Backend-as-a-Service provider such as Firebase or Parse. Some have free versions you can use and they’ll start charging you once you surpass certain limits. Some of these providers are particularly focused on games, some are mostly conceived for mobile apps but can be used for games too.

How to distribute a HTML5 game

The easiest way to distribute a HTML5 is to simply put it out there! By being built as a website, you can just embed it in on a page and publish it. Just like that.

If you want to distribute it through proprietary platforms you have to go through a process called wrapping. Basically, you create a native app for the platform you wanna distribute it to (iOS, Android, etc) and put your game inside so that this app acts like a web browser and “runs” your game.

For desktop platforms such as Windows, Mac or Linux there is a tool called NWjs that allows you to pack your HTML5 games for these platforms.

We can only cover the basics here, but we encourage you to read our more in-depth advice about publishing games.

Match 3 game made with HTML5

HTML5 game frameworks

Most games share some concepts, that of sprites (graphic elements that represent enemies, players, elements in your game), scenes or stages, animations, sound, loading graphic assets, etc. Since most game developers want to focus on their actual game and not in creating this whole abstraction layer, it is recommended you use a HTML5 game frameworks.

HTML5 game frameworks and libraries that contain building components you can use to create your own games. These libraries are Open Source projects created and maintained by people who want to contribute to the HTML5 gamedev environment. In many cases they created the frameworks for their own games, and after realizing that other people would want to not only use it but also contribute to it they released them as Open Source code, so everybody wins.

Picking what game engine to use is an important decision, so make sure you do proper research before making your choice. No matter what engine you pick, you will have to get familiar with its code and inner working if you want to use properly, so they shouldn’t be treated as black boxes.

What can help you make your choice:

  • Is your game for desktop, mobile or both?
  • Do they have an active community?
  • Are there many people using the framework nowadays?
  • Is it being maintained or the Github page looks like an abandoned town?

Sometimes looking at real games gives you more insight than just words. This project compares different engines by making the exact same Breakout game in all of them.

Some popular free frameworks are:

Solar system project made with Babylon.js

HTML5 game development courses

Video courses are a great way to learn new technologies. The main difference between a video course and just watching YouTube videos is that there is more structure. Good courses have a clear goal and build on to it step by step. Below a list of courses and tutorials by Zenva that can give you the tools you need to create HTML5 games.

General Game Development

Phaser

WebGL, 3D, and XR

HTML5 Skills

At the GameDev Academy, as you know already we have a bunch of HTML5 game development tutorials, mostly on Phaser, LimeJs, Quintus and BabylonJS. There are other great places to find good quality HTML5 gamedev tuts:

HTML5 for Schools

Are you a teacher looking to help students get into frameworks like Phaser or teach them core and relevant web development skills? Try out Zenva Schools – an online platform offering coding-based courses for use in the classroom. The platform comes with video lessons, text summaries, quizzes, classroom management features, reporting, and more to help support learning HTML5!

HTML5 gamedev communities

You can find plenty of active communities on the Internet, some focus on gamedev in general and some others just in HTML5 gamedev.

Web:

Facebook:

Other Communities:

HTML5 gamedev challenges

  • The Global Game Jam® is an annual event, usually occurring in January every year. Participants work concurrently around the globe, and around a central theme, and then work together to create a game.
  • j13k competition: the competition is over but you can still read the Blog, subscribe to the Newsletter, and check the Resources for tools.

 HTML5 gamedev podcasts

I just know Lostcast, a podcast created by the guys from Lost Decade Games (whom we’ve interviewed in the past). In the podcast episodes they talk about they HTML5 games and game development in general.

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
How to Install Webpack https://gamedevacademy.org/install-webpack-tutorial/ Fri, 15 Nov 2019 16:00:06 +0000 https://phasertutorials.com/?p=2972 Read more]]>

You can access the full course here: Discover Developer Tools for JavaScript Apps

In this lesson, we’re going to start the process of converting our client-side code to Node Modules and modern JavaScript. We’ll start by creating a package.json file which holds our Node Package Modules (NPM) configuration. This sets our project directory up to install our NPM dependencies. The first things to install are Webpack and Webpack dev server. Next we’ll install Phaser from NPM.

For this project, the client-side code in the stater-files resides in the folder named zenva_mmorpg. Open this folder in your editor.

Folder for project receiving webpack

Next, create a client folder inside zenva_mmorpg that will hold our client code. The other files, including index.html and folders/files under assets can stay where they are for now. We will migrate them to client in a later step.

Client folder as seen in project folder

In your terminal, change directory to client and follow instructions below to setup the client folder with a package.json file that will contain our NPM dependencies and other project details. Just follow the directions in the video lesson substituting author name for your name.

Ensure your terminal/command prompt is in the client folder in the same location as the package.json file and enter npm init and press enter.

npm init

Accept the defaults except those noted below:

Command Prompt with Webpack installation configuration

Next, open the client folder in your editor and notice the newly created package.json file. Click on the file to open it and notice its contents match what you entered into the terminal.

Package.json file for Webpack

Next, back in terminal, we can start installing our dependencies into our client folder. Some dependencies are needed for production for use in running our code while other dependencies are only needed for development. These are distinguished during installation by adding a --save-dev flag to the npm install command.

Webpack is an example of a dev-dependency, so we install Webpack itself along with the Webpack command line interface (CLI) and the Webpack development server.

WebPack-cli provides a flexible set of commands for developers to increase speed when setting up a custom webpack project.

Webpack-dev-server provides a development server that provides live reloading while using Webpack during development.

Ensure your terminal/command prompt is in the client folder in the same location as the package.json file.

npm install --save-dev webpack webpack-cli webpack-dev-server

You’ll notice that a couple of things have changed in our client folder. Our package.json file has been updated to include the dependencies we installed. As well, we now have a node_modules folder. There is generally no need to touch the node_modules folder. If you do look inside, it may seem like a lot of files got added to our project but rest assured that Webpack will include only the production pieces of code we need in the final bundle it creates.

Node Modules folder added to Project

Currently, we have Phaser.js linked in our index.html file which loads it separately. Since we are using Webpack now we can npm install phaser  as a dependency and we will no longer have to link to it inside index.html. Notice the install difference as Phaser is actually a Production dependency. We therefore add the flag --save instead of --save-dev.

Note: As of NPM version 5, installed modules are added as a dependency by default, so the --save flag is no longer needed.

Ensure your terminal/command prompt is in the client folder in the same location as the package.json file.

npm install phaser

The other advantage of including Phaser this way is we can more easily manage the version of Phaser we are using or upgrading.

Package.json with dependencies added by Webpack

Notice our package.json file now contains both Development dependencies (e.g. Webpack) as well as Production dependencies (e.g. Phaser).

Transcript

So now that we’ve talked about what Webpack is, we’re going to work on adding Webpack to our client-side code.

So in the source code that was provided, you’ll see two folders, one will be ZENVA_MMORPG, this is our client-side code, and the other one is the REST API code, that’s where’s we have our server-side logic. So, right now we’re shifting our focus just on the client-side code, so if you can go ahead and open up the ZENVA_MMORPG folder, inside your code editor, and then inside you will see we have an index.html file, and we have an assets folder. That will have all of our audio, css, images, JavaScript, and everything that we used in the previous courses to start building our MMORPG.

All right, so the first thing that we’re going to do, is let’s go ahead and make a new folder, we’re actually going to go ahead and call it client. So this is going to keep, this will contain all of our client-side logic. For now, we will not drag the index.html file in our assets folder in there, we will do that later.

So, to actually use Webpack, we need to install it as a dependency, so the first thing we should do is actually create a package.json file for our code. So, if we go ahead and switch over to our Terminal, let’s go ahead and go cd into the client folder, and let’s go ahead and run the npm init command.

So, if you recall, the npm init command is going to walk us through creating a package.json, so for a package name, we’re going to go ahead and just leave it as client, we’ll do 1.0, for our version, description we’ll just do client side code for zenvo mmorpg. For our entry point, we’re going to go ahead and do source and then index.js, test command, we’ll go ahead and just leave that a blank for now, we won’t worry about git repository or keywords, and as for author, I’m going to go ahead and put my name, you can go ahead and put yours, and then for our license, we’re just going to go ahead and leave that as the default license.

And then, we just need to go ahead and verify the information we put in. Yes, and then now, if you go ahead and check, we should have, inside our client folder, our package.json.

Perfect, so now, we can go ahead and start, actually installing some of our dependencies, so do go ahead and install Webpack, we just need to do npm install, –save, but instead of just -save, we’re going to go ahead and do save-dev, and what this will do, is it’s going to install this dependency as a dev dependency, which shows that it’s needed, well, for development, but it’s actually not needed in our production code. We’re going to go ahead and do webpack, we’re going to do webpack-cli, and then webpack-dev-server. And then we’ll go ahead and hit Enter to start installing your dependencies, so, webpack-cli, webpack-dev-server, are additional packages that are helpful while you are working with Webpack,

So, what Webpack test server will do, is it’s going to run a development server that’s going to bundle and run our code as we’re working on it, so that way we can actually test our changes in real time, where if we’re just doing the webtag build, we would actually have to build our source code every time we make a change, and then run another server to test it. That’s why webpack-dev-server is really nice, is because we can actually do it while we’re developing. And webpack-cli is just a set of commands for developers that makes it very easy to set up a custom Webpack project.

All right, perfect, so now these are installed. The next package we’re going to go ahead and install is we’re going to go ahead and install Phaser. So, currently, we have our Phaser library included with our source code, since we’ll be switching to Webpack, we can install Phaser as a dependency, and then reference it, and then when our code gets bundled, Phaser will be bundled with our code, and we don’t actually have to include that file separately.

So we’re going to go ahead and do npm install -save and we’ll do phaser, and another benefit of doing this, is we can easily upgrade our version of Phaser, without having to download and save the source code, and then upload it into our server, and since we are including it as a dependency, we can easily update our dependency to get the newest version, re-bundle our code and push it up to our server, and then we’ll be using the new version of Phaser.

All right, so now that Phaser installed, let’s go ahead and switch back to our code editor. And you will see our package.json’s been updated with our dev dependencies and our regular dependency.

Interested in continuing?  Check out the full Discover Developer Tools for JavaScript Apps course, which is part of our MMORPG Academy.

]]>
An Introduction to Webpack https://gamedevacademy.org/webpack-intro-tutorial/ Fri, 08 Nov 2019 16:00:32 +0000 https://phasertutorials.com/?p=2970 Read more]]>

You can access the full course here: Discover Developer Tools for JavaScript Apps

Webpack is an open source JavaScript (JS) static module bundler for modern JS Applications. This has two important implications. One, it means that Webpack is a JS Tool that runs at BUILD-time; not RUN-time which makes it an important part of a modern development process. Secondly, Webpack extends its power and flexibility with various plugins that not only ties together all your code and assets but allows you to incorporate linters for code quality and tools to ensure modern JS will run in all browsers. We will look in greater detail at these tools in upcoming lessons.

Webpack allows you to write as many JS files you want and organize those files along with styles, images and more in a way that makes sense for developing and supporting your project and then bundles everything together in such a way that the end result is an bundled file that is transformed, minified and optimized to run efficiently in any browser you are targeting.

Webpack diagram showing assets to final package

Webpack does this by creating a dependency graph of every part of your project then uses that information to intelligently generate one or more files based on your project needs. Webpack and its plugins are installed in the normal way using Node Package Manger (NPM).

Note: As of Webpack 4, it does not require a config file. This is important because the webpack config file could be a barrier to starting modern projects for many developers. Webpack now bundles your entire frontend app together using intelligent defaults significantly lowering the barrier of entry for the majority of devs. Devs or organizations wanting to take more fine grain control of code bundling still have the option to customize a webpack config file!

Transcript

So the first tool that we’re gonna look to use is Webpack. So if you’re not familiar, Webpack is a module builder and what that means is, Webpack is a tool that we use during development of our code. It’s not something that’s actually used during the run time of our assets. So, it’s only used during development.

So Webpack is a tool where you use a configuration to explain how you want the builder to load specific things. You describe to Webpack how you want to load your JavaScript files or how you want it to look at your SVG, CSS, or JPEG files. Then when you run your – the Webpack builder – it will go into our entry point so what is the main file of our program and it will walk up and down our program to grab all of these assets and it will figure out what needs to be done with them.

So in the case of how we’re going to be utilizing it for our project is we’re going to have all of our JavaScript files separated out as they are now and it’s going to go through and bundle all these files together and to create one JavaScript file for us. So this would be our bundle – it’s gonna bundle everything in together so that way all of our code is optimized into one location.

Furthermore, we’re gonna be able to use plugins like Babel to take our JavaScript code that will be written in ES6 syntax and it can modify and transform it back into ES2015 standard. So that way it’s supported across all browsers. And this is another benefit of using Webpack because we can use these plugins to do all this for us and then that way it ends up in our bundled file.

So to actually use Webpack, it’s actually quite easy. It’s available through NPM so we can install it like any other node package and then what we need to do is we actually need to create a configuration file so Webpack config file and that’ll allow us to tell Webpack how to bundle our code.

Interested in continuing?  Check out the full Discover Developer Tools for JavaScript Apps course, which is part of our MMORPG Academy.

]]>
How to Install Node.js for Phaser Games https://gamedevacademy.org/phaser-nodejs-setup-tutorial/ Fri, 18 Oct 2019 15:00:56 +0000 https://phasertutorials.com/?p=2960 Read more]]>

You can access the full course here: Node.js and Express for Game Development

Node.js is a cross-platform, Javascript runtime environment that executes Javascript code outside of a browser. To follow the videos, you will need Node.js installed on your machine.

Go to nodejs.org on your browser.

Node.js homepage with 10.16 LTS version available

From here we will be able to download a version for our particular operating system (macOS here). There are 2 versions available for download. You are welcome to use the current release (with the latest features) but we recommend the LTS (long term support) version for this course.

Downloading on Mac

Click on the LTS version. We are prompted to download the node.js package. Let’s save it in our install directory.

Saving of Node.js LTS version on Mac

Let’s run the installer (this step will vary based on your operating system). Click Continue.

Node.js Installer on Introduction

Next accept the License Agreement. Click Continue.

Node.js license agreement

The installer displays the space that will be taken by by the installation. Click Continue.

Node.js Installer on Installation Type screen

Node.js begins to install. This may take a few minutes.

Now that Node is installed, let’s open a new terminal (command prompt). Type the following:

$ node -v

This displays the version of Node installed (and being resolved) on our machine.

Terminal displaying node version number

$ npm -v

This displays the version of NPM installed (and being resolved) on our machine.

Terminal display npm version number

Transcript

So for our API, we will be dealing with this using Node.js. If you’re not familiar, Node.js is an open-source, cross-platform JavaScript runtime environment that executes JavaScript code outside of a browser. And so to follow with the videos, you will need to have Node.js installed on your machine.

So in your browser, if you go to nodejs.org, you’ll be taken to this page here, and you’ll be able to download a version for your particular operating system. So it’ll be two different versions. One will be LTS and the other one will be current, so I recommend the LTS version. So this is the long-term support. This is currently the supported version of Node.js. You are welcome to use the current release that has the latest features, but I do recommend the LTS version since that’s what we’ll be using for this course.

So to download it, go ahead and click on the LTS button. You’ll be then prompted to download the package. Go ahead and save. So then after the package has been installed, you’ll wanna go ahead and run your installer for your appropriate operating system, so this may be different, because I am on a Mac.

So after you run the installer, you’ll be prompted and it’ll let you know you’ll be installing Node and npm, so to install Node, you’ll need to agree to the software license agreement. So if you wanna go ahead and pause the video and read that.

Then next you’ll see you’ll go ahead and continue through the prompts until you install Node on your machine. This may take a few minutes. All right, so to verify if Node is installed and working correctly, let’s go ahead and open up a new terminal or command prompt. And then once you’re there, if you go ahead and do node -v, it’ll show you which version of Node that you currently have installed on your machine, and which one’s been resolved. And then also, if you do npm -v, it’ll show you which version of npm is currently installed as well.

Interested in continuing? Check out the full Node.js and Express for Game Development course, which is part of our MMORPG Academy.

]]>
A Bite-Sized Guide to HTML5 Game Design https://gamedevacademy.org/html5game-tutorial-guide/ Fri, 11 Oct 2019 15:00:54 +0000 https://phasertutorials.com/?p=2953 Read more]]>

You can access the full course here: Bite-Sized HTML5 Game Development

Part 1

Learning Goals

  • Basic Phaser development environment.
  • Setting up a web server.

In order for you to start making games with Phaser you will need to have a web browser (Google Chrome will be used for this course), code editor, and a web server.

There are many different code editors out there that are free to use, and it doesn’t matter which one you choose.

  • A list of code editors that are free
    • Brackets(https://brackets.io)
    • Atom(https://atom.io)
    • Sublime text(https://www.sublimetext.com)
    • Visual Studio Code(https://code.visualstudio.com/)

A web browser is a program that will receive requests from the browser, and we will send, it will serve files as a response. 

A browser doesn’t allow you to load files from the file protocol due to security reasons. The web would be a very dangerous place if random websites could get access to the files on your computer. This is why you cannot just go and open a Phaser game by double clicking on the index.html file.

You have to load the game through a web server. The simplest way to get a web server up and running is to install the Brackets code editor.

Brackets code editor homepage

You can download Brackets from here: http://brackets.io

The direct link to download Brackets is here: Download Brackets

Brackets comes with a built-in web server and it is free to use.

  • Web Server-Brackets
    • Download and install Brackets (https://brackets.io)
    • File-Open Folder
    • Live preview

Always keep the Chrome Developer Tools open when working.

Chrome Developer tools as seen in the Inspector Console

There is a more advanced way of using a web server and this involves using a called http server.

The first step is to install Node JS, and you can download Node JS from here:  https://nodejs.org/en/

The direct link to download Node JS is here: Node JS Download

Node.js homepage for Windows download

Node JS is an application that allows you to run JavaScript code on a server, in this case your computer. 

For Window Users Only: Once you have downloaded Node JS you will need to download Git Bash, and this will give you access to a terminal on your system.

Mac users will already have access to the Mac terminal.

You can download Git Bash for windows here: https://gitforwindows.org/

The direct link to download Git Bash for windows is here: Git Bash

Git homepage for Windows download

The first step is type “npm” in the terminal

If you type this and it is installed you will see this:

Terminal with npm run

Once you verify that the npm is installed you can then type “npm install http-server -g” this is the name of the package that we want installed for us.

We now need to navigate and find our folder where the game is located.

In my case the game is located in the D drive, the www folder>Phaser3>crossy-rpg this will be different in your case.

If you have issues with using the command line options here you can just use Brackets, Brackets is much easier to use and doesn’t require this extra setup for the http server setup.

So in the terminal you type “cd d:” this brings you to the D drive.

Then type “cd www/phaser3/crossy-rpg/”

Now you should be inside the correct folder in the terminal.

Terminal with change directory commands run

Now that you are inside the correct folder you then type “http-server” and that should launch the web server for that particular folder.

You should now see that the server is available in different URLs.

Terminal with http-server command run

You then can copy one of the URLs and go back into Google Chrome or whatever web browser you are using and paste the copied code into the navigation bar.

IP address being copied from Termianl

IP address copied to Chrome URL bar

And now the game will be working just like it should.

Learning Summary

  • There are three basic requirements for Phaser development
    • Web browser
    • Code editor
    • Web Server
  • A list of code editors that are free
    • Brackets(https://brackets.io)
    • Atom(https://atom.io)
    • Sublime text(https://www.sublimetext.com)
    • Visual Studio Code(https://code.visualstudio.com/)
  • Web Server-Brackets
    • Download and install Brackets (https://brackets.io)
    • File-Open Folder
    • Live preview

Brackets view with arrow pointing to lightning bolt icon

  • Web Server-http-server
    • Download and install Node.js (https://nodejs.org)
    • (Windows Only) install Git Bash (https:gitforwindows.org/)
    • Open terminal, install http-server: npm install http-server -g
    • Navigate to the project folder, run the server: http-server

Part 2

Learning Goals

  • Game Design Documents
  • Importance of scoping
  • Outlining game requirements

Game design documents(GDD’s) are used in the game industry to describe and communicate the concepts and requirements of a game that will be developed.

These documents can be very short or very long. The length will depend on the type of game and scope of the game as well.

The GDD’s allow you to see everything in one place for the game that is being developed. It makes it easy for people who are developing a game on a team to get an idea of what the game should be, or other people who might just be interested in the development of the game. They can look at the GDD and see exactly what mechanics are going to be in the game and even see the type of art being used in the game.

GDD’s can be used if you are working on a team or if you are just a solo developer.

You will want to include the concept of the game, the game mechanics, the theme, the genre, the targeted platforms, and any art or sound assets in the GDD.

A simple template for a GDD:

Game Design Document template

You can use just about word processing software to write the GDD in.

A GDD is considered to be a “live” document because it should be constantly updated and everyone working on the game should have access too the document at all times.

Learning Summary

  • Game Design Documents (GDD)
    • Short documents to describe a game concept and requirements.
    • Used by and number of people (1 or many)
    • Includes:
      • Concept
      • Mechanics/UI
      • Platforms
      • Assets
  • Game Design Document filled out regarding Frogger style game

  • Game Design Document explaining game mechanics and assets

  • Challenge
    • Make a GDD of your game idea
    • Share it in the comments

 

Transcript 1

Hi there. My name is Pablo Farias Navarro, and I will be your instructor in this course. In this course, you’ll learn to create from absolute scratch the game that you are seeing on the screen. Where you have to move one character from one end of the screen to the other end of the screen. Sort of like Frogger or Crossy Road, games like that.

And you’ll be learning how to create this game using the Phaser framework. The only requirement for this course is for you to have basic JavaScript skills. We’re gonna introduce Phaser from absolute scratch. So, you’ll learn how to build this amazing game. You’ll be learning about Sprites, which are the, you know, players and enemies on the screen. You’ll learn how to work with Groups, a convenient way of dealing with multiple Sprites. We’ll go through how to detect user inputs so that you can move that character and we will work on the computer and on a touch screen as well.

We’ll go through the basics of collision detection, so you can learn how to detect when different elements are overlapping, something key when making games and we’re going to end up by covering some basic camera effects. So as you can see, when the player runs into one of the enemies, there’s a shake up camera effect and also fade out before the game restarts. So you’re going to learn how to do that, which will also give us the chance to introduce events, another important topic. When it comes to our courses, and besides making courses I also take a lot of courses all the time. I’m always learning things. Something that I really like about courses since one of the reasons why we make them is because they empower people to learn regardless of their own learning style.

For example, let’s say that you are a visual learner, you’re going to watch somebody creating the game on the screen, but if you are somebody who learns by doing, a kinesthetic learner, you can follow along, you can code along, and build everything and play around with the code, the source code, so you can learn as well. We recommend that students revisit the lessons so that once you complete a lesson, you can watch it again in the future when you need a bit of a reminder of how to do something and also it always helps if you are building your own projects.

So if you already have a game idea, you can start working on that game and put in practice the things that you learned in the course. You can put them in your own game as you learn them. We’ve seen that people who plan for success really get the most out of our material. For example, people who allocate certain days of the week to complete the courses, and stick to that plan even if it’s once a week. Ideally, three times a week, but depends on how much time you have.

So it really adapts to your own schedule and learning style and if you make learning a priority, you will get so much out of this training. Alright, well thanks for watching this introduction, now let’s get started and let’s start making games.

Transcript 2

In order for you to start making games with Phaser, you will need to have installed a web browser, I’ll be using Google Chrome, a code editor and a web server.

You can use whichever code editor you are already familiar with. Well, lets start with the beginning here. What is a web browser? A web browser is simply a program that will receive requests from the browser, it will serve files as a response. It will send our game as a response. The simplest way to get a web server running, that doesn’t require any advanced technical knowledge, is to install the Brackets Code Editor. When you open brackets go to file and open the folder. Find the folder that you want to serve with the web server so I’m gonna find the folder where my game is located, already had it here, so I’m gonna select that folder that will show me all of the files here, and then what you do is you press this live preview button.

So when you press that, brackets opens a Chrome page and it serves your files using a web server. So you can see that we have a specific URL here. This is the URL of this web server.

Transcript 3

So, the concept of our game is the casual game, two dimensional and I’m going to use the analogy that it’s Frogger-style. Frogger is an old Atari game where the player controls a, sort of like a Valkyrie, who needs to reach a treasure and avoid dragons.

So, that is a very short description, it’s a very simple description of a game and what I want to do now is add some concept art and some ideas. So, I’m going to start by going into Google Images and finding a screen-shot of that Frogger game that I mentioned. I’m going to take a scren-shot of this and add it to my game design document and now what I’m going to do is make a quick sketch of what the game looks like. So, this already gives an idea of what the game does.

Now, what platforms is this game going to be made for? So, first of all this is going to be a cross-platform game, which will work on both desktop and mobile and it will be a browser game, so it is run on the web browser. In terms of user interface we don’t really have any proper user interface but we want to describe how the player interacts with the game so that is how you interact with this game. It’s really simple. Now, what about the game mechanics?

You’ve got dragons moving up and down if the player is hit by a dragon the game restarts. The player wins if they reach the treasure and the game will restart. Player moves in only one direction. Now, the assets. First of all, what is going to be the style of the game? I would describe this as pixel art, 8-bit style with a retro kind of feel, like a retro RPG sort of feel, like old Final Fantasy or Zelda games.

We are going to need Sprites, so we need a background for the game, we need a Sprite for the player and one for the enemy and for the treasure. So this game doesn’t need that many assets, these are all the assets that we need.

Interested in continuing? Check out the full Bite-Sized HTML5 Game Development course, which is part of our Bite-Sized Coding Academy.

]]>
How to Set up and Test Phaser for RPGs https://gamedevacademy.org/phaser-setup-tutorial/ Fri, 13 Sep 2019 15:00:27 +0000 https://phasertutorials.com/?p=2938 Read more]]>

You can access the full course here: Intro to RPG Development with Phaser

Part 1

Learning Goals

  • Developer tools.
  • Setting up a web server.
  • Installing VS code.
  • Downloading Phaser.

Obtaining the Chrome Web Server Browser Extension

Before we can jump in and start coding there are a few setup tasks that we need to complete. The first thing we need to do is have a local web server running on our machine. We will be using a Chrome browser extension to setup our web server. You are welcome to use another route as far as the webserver goes, but this course will only be covering the Chrome browser extension we use in this course. In order to get the Chrome extension you will need to visit this link here to obtain it: https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=en

Web Server for Chrome plugin Launch screen

This is a very simple browser extension that you just simply point it to a local folder where you want to host files and then it will spin up your server for you. Once you have the extension added to your Chrome browser you will see it in the Chrome apps menu:

Chrome Web Server icon button

In order to use the extension you will just click on the icon, and a new window will open:

Chrome Web Server options screen

All you need to do now is click on “Choose Folder”:

Choose Folder option for Chrome Web Server

So once you select the folder, all the assets that are in that folder will be made available on the server. Then if you click the link provided:

Chrome Web Server URL address

You will see a list of all the current assets in that directory:

Chrome Web Server showing index directory for project

Currently the directory is empty so that is why it is showing the way it is. The second toll that you are going to need is an Editor. There are many free editors out there to download and use.

Obtaining the Code Editor

We will be using VS Code in this course. Again you are welcome to use any editor of your choice, but we will only be covering VS Code in the course. In order to download VS Code you can visit this link here: https://code.visualstudio.com/

Visual Studio Code download button for windows

Once you have the installer downloaded all you need to do is run the installer and follow all the on-screen prompts for the installation.

Obtaining the Phaser Library

The final tool we need now is the actual Phaser 3 library. You can visit this link to obtain the Phaser library: https://phaser.io/download/stable

Phaser.io website with Download menu option circled

At the time of this course the latest version of Phaser is Phaser 3.16.2 “Ishikawa.” There are a few different ways to obtain the Phaser library from here:

Phaser 3.16.2 min.js file

You can download the min.js file.

Summary

Summary for tutorial on getting Phaser setup

Part 2

Learning Goals

  • Basic project setup.
  • Creating a basic HTML page.
  • Running the server.

In this lesson we will begin by setting up our project structure. You should begin this lesson by first downloading the course assets, and you can download these assets from the course home page (NOT AVAILABLE IN THE FREE WEBCLASS). Once you have downloaded and extracted the assets folder you should see two folders called “assets” and “images:

Assets folder for Phaser project

The audio folder has five different sound effects in it, we will use these in our game for the player attack, when the player takes damage, etc:

Audio assets for Phaser project

In the images folder there are a few sprite sheets, one of them is characters, the other one is items:

Sprite assets for Phaser project

There is also a test spawner image, and a UI folder that contains two buttons for us to use in our game:

Button assets for Phaser project

In order to start setting up our project structure we will need to create a new folder and call it “zenva_mmorpg” once you have this folder created you can place the assets folder inside this folder:

Assets folder being added to Phaser project folder

We now need to create a new folder inside the assets folder that is now in the zenva_mmorpg folder and call the folder “js”:

JS folder added to Phaser project

Create a new subfolder in the js folder called “lib”:

Phaser.js and Phaser.min.js added to JS sub folder

The lib folder will be used to keep track of any external libraries that we wanna use for our game.  We will need Phaser inside of the lib folder. For the time being we are going to include both the Phaser and the Phaser minified file. One other folder that we need to make inside the assets folder is the “css” folder:

CSS folder added to Phaser project hierarchy

We will use this folder to keep track of any external CSS files. We now have the basic structure of our project in place and now we can open up the folder inside the code editor. One way to do this in VS Code is when you open VS code without any folders selected you can click on the File Icon in the upper left hand corner and then choose Open Folder:

VS Code Explorer with Open Folder selected

Once you choose Open Folder you will need to navigate to where you have the folder you just created in the previous steps:

Phaser project folder being selected for VS Code

This will reload the code editor once you open the zenva_mmorpg folder in VS Code. You will see that we have our assets in here now, and they are listed on the left side of the editor:

Phaser project folder open in VS Code

Next we need to start up the Webserver for hosting our files, open the Chrome browser and click on Apps:

Chrome Web Server icon circled as well as URL

Once the Chrome webserver has been opened click on Choose Folder:

Web Server for Chrome with Zenva MMORPG folder selected

You will then choose the zenva_mmorpg folder you just created previously:

Phaser project folder selected into directory

This will be the root of our project. So now when we click on the link, you will see that the localhost 8887 is now hosting our static files. You will see that we have the assets folder and images:

Web Server for Chrome showing project root directory

You can switch back to the code editor now, and next we need to create an HTML page. Because this is a JavaScript library, we will be including the JavaScript files in our HTML page. The HTML page will be what is rendered to the end user when they visit our site. Create a new file:

New file button in VS Code

Name the file “index.html” We then need to create the basic structure of the HTML page, so open this file in the code editor. See the code below and follow along:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="user-scalable=0, initial-scale=1, minium-scale=1, maximum-scale=1, width=device-width, minimal-ui=1">
        <title>Zenva MMORPG</title>
    </head>
    <body>
        <div id="phaser-game"></div>
        <script src="assets/js/lib/phaser.min.js" charset="utf-8"></script>       
    </body>
</html>

Save this file. Switch back to the browser and refresh the page, you will see a few things and the first is that our asset list has went away. The reason for this is that when a server detects an index.html page, the server will render that page at the root path. You can see that our index page is being rendered, but we don’t have any content currently, but if you look at the title on the tab you can see that it has the tile name we specified:

Port URL shown for Web Server for Chrome

Right click on the webpage and choose inspect:

Right-click menu with Inspect in Chrome selected

Click on the Console:

Console selected via Chrome's Inspector

Summary

Phaser Library

  • In order to create your game, you will need to include the Phaser library. The library is available via direct download, on a CDN, NPM, and on GitHub.
  • When you are developing your game, it is important to keep an eye on the version of Phaser you are developing against. Some features may not be backwards compatible.

 

Transcript 1

For our course, we’ll be using the Phaser 3 framework for developing our game. If you’re not familiar, Phaser is a fast, free and fun open-source HTML5 game framework that offers WebGL and Canvas rendering across desktop and mobile web browsers. The framework itself is written in JavaScript, so games can be compiled to iOS or Android and native apps by using third-party tools, and you can also use JavaScript or TypeScript for your game development.

The only requirement for using Phaser is the web browser has to support the Canvas HTML tag, which most browsers currently support.

Some of the benefits of using the Phaser framework is there’s a lot of options right of the box. Phaser comes with a fantastic plugin system, offers device scaling, mobile browser support. It offers things like asset preloading. It has built-in physics. It also includes a plugin for Facebook instant games.

So before we start working on our game, I wanted to share a few additional resources with you that are very helpful. The first is the labs.phaser.io website. This has replaced the Phaser 2 examples that you’ll find on the Phaser site and is exclusive to Phaser 3. On this site, you’re gonna find over 700 different examples of how you can use Phaser, and how each of the individual components work.

So for example, if we wanna go ahead and take a look, we’ll go and take a look at Game Objects. We’ll go ahead and do Sprites, and you’ll just see we have all these different examples for rendering a single Sprite, if we wanted to move a Sprite across the scene, and many more.

The second resource I want to share with you is the Phaser 3 API documentation, which is hosted on GitHub. The documentation is still a work in progress, but there is a lot of great information here. So if you want to look up the different things that are available for a particular class, like for example, if we wanted to look up more information on a sprite, we can search for it, and then you’ll see it’ll break it down.

It gives you all of the available methods, the properties, what’s expected, and there’s just a lot of great information. And what’s nice is for each method, they’ll be a link to the original source code. So you can go ahead and take a look at it in GitHub.

So the next resource is the GitHub repo itself. Phaser is under active development, and there is a new releases quite often, so in the repo they’ll be links to all of the resources I listed before, plus a few additional ones. You’ll also find things like release notes, how you can get the current version of Phaser. You’ll also get things like the TypeScript definition and a few links to a few different project templates.

The last resource I wanna share with you is the Phaser 3 forums. So there is an active community that is currently using Phaser, and then there’s a lot of a support for it. So if you have any questions, you can always search the forum. There’s a good chance someone else may have had the same question or ranted the same issue, or even if you’d just like to share your current game, or anything that you’re currently working on, this is the place to share it.

Transcript 2

Before we can jump into the code, there are a few setup tasks we have to do in order to run our game. The first thing we have to do is, we need to have a local webserver running on our machine. The reason for this is that it has to do with browser security. So we can create an index HTML page, and we can view it in our browser by using the file local path to view that file. However, once it comes time to load in external assets using the file path, the browser will block this for security reasons. So in order to not be hindered by the browser security, we need to be able to host our assets over HTTP and that’s where our web server will come in.

So there are many options available to you. Some are OS specific, other ones can be tied to the browser you’re currently using. So on the Phaser 3 site you’ll see some examples like you can use WAMP or XAMPP, Mongoose. You can use MAMP if you’re on Mac OS. You can also use things like grunt, Python, http-server for node.js, you can do php built-in web server.

So, for this course, we will be going another route and we’ll be using a Chrome browser extension, and I’ll be showing how we can set that up to serve our web server. You are welcome to use another one – however, that is out of scope for this course.

So to get the Chrome extension, if you go ahead and do a search for web server for chrome, you should see it as the first result. So it is a very simple Chrome extension where you just point it to a local folder where you want to host files and then it will spin up your server for you. So to use it we just need to click the Add to Chrome button. Click Add App and then you’ll see on your chrome apps you’ll have a new app added.

So to use the Chrome extension, you just go ahead and click on the app, a new window will open. So you just need to click on Choose Folder to where you should serve your files from and then, what will happen, is any assets in that folder will start being – will be made available and if you click this link here. You’ll see a list of the current assets in that directory. So currently this directory is empty, so that’s why it’s showing this.

So the second tool you’re going to need is an Editor. So there are many Editors out there, each with their pros and cons, just to list a few of them: there is Sublime Text, Atom, VS Code, Brackets, WebStorm. You could use Notepad, Notepad++. So for this course I’m going to show you – so for this course I will be using VS Code, and you’re welcome to also use VS Code. However if you have a personal preference, you are welcome to use any code editor that you would like to use.

So to get VS Code, if you come down here, you click on this link, and you should be taken to the VS Code version for the OS you’re currently on. If you go ahead and click on the Download for Mac button, this will download the installer, then you just need to run the installer and follow the instructions.

Finally, the last tool we need is, we actually need the Phaser library itself. So to get the library, if you click the Download button up here on Phaser, you’ll be taken to this page and then if you click on this button over here, it’ll take you to the stable releases. So at the time of this recording, Phaser 3.16.2 is the latest version.

So there are few different ways to get the Phaser library. It’s available on npm, so you can install it from ther,e and it’s also hosted on the jsDelivr CDN, so you can include the script tag on your web page, if you would just like to use Phaser that way. You can also clone the Gallop Repository, if you’d like to go that route, you can download Phaser as a .zip and you can also get direct links to the JavaScript file and the Minifier JavaScript file.

So if you click the links those files will be downloaded for you in your browser. So if you like to take a look at the source code while developing, I definitely recommend getting the Phaser.js file, since it’s the unminified version and it’d be easier to read. For production-ready, I definitely do recommend that you use the Phaser.min file, since it’s already minified for you if you’ll be including Phaser that way in your project.

Transcript 3

To begin, we are gonna start setting up our project structure. In the course links below, you will see a link to our assets. So, if you go ahead and download the asset folder and you extract it, you will see two folders inside. One will be audio and one will be images. Our audio has a few sound effects that we’ll be using for our game throughout our courses. Some of these include, like, an item pickup, when the player attacks, when the player takes damage. In the images folder, you’ll see a few sprite sheets. One of ’em will be characters and the other will be items. So, this will be a few different assets we’ll be using throughout our game. You’ll also see a test spawner image. And you also have a UI folder that has a few UI buttons inside it.

So to start setting up our project structure, we’re gonna go ahead and create a new folder called zenva_mmorpg. We’re gonna go ahead and take our assets folder and place it inside this folder. So now in here, we’ll have assets. And let’s go ahead and make another folder and we’ll call it js. This will be used to keep track of all our JavaScript files that we’ll use in our game.

And let’s go ahead and make a new subfolder called lib. The lib folder will be used to keep track of any external libraries that we wanna use for our game. We’ll, of course, will have Phaser inside here. For the time being, we’ll include both the Phaser and the Phaser minified file. One other folder we wanna go ahead and make over in here is we’ll make a css folder. We’ll use this to keep track of all any external CSS files that we create while making our game.

So now that we have our basic structure for our project in place, let’s go ahead and open up the folder inside your code editor. One way to do this in VS Code is when you open up VS Code without any folders selected, you can go ahead and click on the File icon here and then choose Open Folder. We’ll go navigate to the folder we just created. This will go ahead and reload the code editor and you’ll see that we have our assets in here.

Next, we’re gonna go ahead and start up our web server for hosting our files. We’re gonna go ahead and come into Chrome, go click on Apps, click on Web Server. And we’re gonna go ahead and Choose Folder and we’re gonna go ahead and choose the folder we just created. And that will be the root of our project. So now, when we click on the link, you’ll see the localhost 8887 is now hosting our static files. In this, we have our assets folder, we’ll have our images. So you’ll see, that’s serving up that file through HTTP. So we’re gonna go ahead and go back. And then let’s switch back to our code editor.

So, the first thing we need to do is create an HTML page. So the HTML page, because this is a JavaScript library, we’ll be including the JavaScript files in our HTML page, and that HTML page will be what is rendered to the end-user when they visit our site. So we’re gonna go and come up and we’re gonna go and create a new file, and we’re gonna go ahead and call this index.html.

So then we just need to create the basic structure of an HTML page. So, we’ll do DOCTYPE html and then we’ll create our html tags. And let’s go ahead and create a head tag. And then a body tag. Okay, so the head tag for our HTML file is used to put any meta information for our webpage here. This includes things like any viewport meta tags we wanna have, if we want to have a title displayed on our webpage, and it’s also used to including external resources that we want to be loaded before our webpage starts to render.

And then our body tag is used to render the content of the page. This will be like any of the text, the images, anything we show on the site. For the purpose of our game, this is where we’re gonna have our canvas element. And it’s also where we can include any JavaScript files that we want to be loaded after our page has started loading.

So the first thing we’re gonna do in our head tag is we’re gonna create a new meta tag, which I’m gonna give it a character set of utf-8. And then we’re also going to create another meta tag, and this is going to be a viewport meta tag. And we’ll do content equals user-scalable=0 to initial-scale=1. We’ll do minimum-scale=1, maximum-scale=1, width=device-width, and minimal-ui=1. We’ll close our tag.

So, what this meta tag does is, by default, if it’s not provided, a mobile device will try to render that page at a typical desktop screen width and then it will try to scale that page to fit the mobile device. This can lead to a bad user experience, because trying to render that large page on that small device means the user has to zoom in to try to view the content. It’s not a very pleasant experience.

By including that tag, it allows us to set the width and height of our viewport. So you’ll see, what we did is we went to the device-width, which allows it to then treat that as the maximum width and our page will be rendered much more cleanly.

So next, we’ll go ahead and we’ll add a title property and we’re just gonna go and call this Zenva MMORPG. And then down in our body, let’s go ahead and create a div and we’re going to give this div an id of phaser-game. And then next, we’re going ahead and load in our external JS files. So we’re gonna do script src and we’ll do assets, JavaScript, lib, and we’ll do phaser.min, and we’ll give it a character set of utf-8. And we’ll have our closing script tag.

All right, so if we go ahead and save our changes and we switch back to our browser and we refresh the page, you’ll see a few different things. First is our asset list has went away. The reason for this is when the server detects an index.html page, the server will render that page at the root path. So if we would have named our HTML page something like main.html page or game.html, we would still see a list of our files here.

So you’ll see that our index page is being rendered but we don’t have any content currently, but if you look at the title in the tab here, you’ll see that it has the title we specified. Then we’ll go ahead and we’ll do Inspect, we’ll do Console. Let’s do that for now.

Interested in continuing? Check out the full Intro to RPG Development with Phaser course, which is part of our MMORPG Academy.

]]>
Creating Mobile Games with Phaser 3 and Cordova https://gamedevacademy.org/creating-mobile-games-with-phaser-3-and-cordova/ Sun, 23 Jun 2019 23:44:37 +0000 https://gamedevacademy.org/?p=6497 Read more]]> Find the source code for this example here.

Photon Storm’s Phaser is one of the most trusted frameworks for developing professional-quality 2D games in JavaScript. With Phaser, it’s feasible to make performant games that run smoothly in all major browsers, across all major systems, while only having to maintain one codebase. And now, the latest installment of Phaser has made its debut: Phaser 3.

But did you know that the same code that runs in your browser can be wrapped into a “native” mobile application? By combining Phaser 3 with Apache Cordova, we can produce games that not only run in the browser, but can also be published to the App Store and Google Play Store.

In this article, we’ll use Phaser to make a simple “game” that can be built for iOS, Android, and the Web. Though the result won’t truly be a “game” in the playable sense, the concepts it introduces will be referenced again in future tutorials where we will, indeed, create playable games.

Pre-requisites (things to install!)

We’ll be dealing with purely JavaScript (and tiny bit of HTML) through this tutorial, so all you need to install manually is Node.js. This will give you the node and npm executables on your system.

Once Node.js is installed, download the Apache Cordova command line by running this command in your terminal/command prompt:

npm i -g cordova

Learn Phaser 3 with our newest Mini-Degree

The HTML5 Game Development Mini-Degree is now available for Pre-Order on Zenva Academy. Learn to code and make impressive games with JavaScript and Phaser 3!

Get Instant Early Access

Project Setup

Cordova includes boilerplate projects that make it much simpler to start off with a mobile-enabled project, so let’s take advantage of that, by running:

cordova create hello

This will create a directory named hello, and copy multiple files into the project.

Next, let’s install Phaser into our project. In our project directory, run the following:

cd www
npm init
npm i --save phaser

For those unfamiliar with npm, the above command downloads the source code of the Phaser framework and saves a local copy in the www/node_modules folder. This way, we have a copy of the code without having to download it from a CDN on every run. The reason we have to have a separate package.json file in the www directory is that static files are served from the www directory, and not from our project root. If Phaser were installed in the project root, we would never be able to access it in the browser.

Next, let’s add support for running our app in a browser. We’ll add support for running on iOS and Android later. Run this:

cordova platform add browser

Next, we’ll want to add support for live-reloading our changes when we edit our file. Otherwise, Cordova will only ever serve one version of our files, which will lead to a lot of head scratching and wondering why errors seemingly don’t vanish, even after changing your code! Run this command:

cordova plugin add cordova-plugin-browsersync

Now that we’ve set our project for development, let’s run the HTTP server:

cordova run browser --live-reload

Now, you should be able to visit http://localhost:8000/index.html to view your game in action.

Basic Game Code

First, let’s remove the starter code that Cordova gives us; we won’t be needing it anymore. Remove the <div id="app">...</div> code in index.html, and add a reference to our downloaded Phaser source, so that the file looks like the following, ignoring comments:

<html>
    <head>
        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
        <link rel="stylesheet" type="text/css" href="css/index.css">
        <title>Hello World</title>
    </head>
    <body>
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
    </body>
</html>

Feel free to remove the Content-Security-Policy tag in the head. Though it’s a smart choice for security, if you are unfamiliar with CSP, it can be a rather confusing roadblock for such a simple tutorial.

Next, let’s add some code in js/index.js to start up a Phaser instance:

document.addEventListener('deviceready', function() {
    var config = {
        type: Phaser.WEBGL,
        parent: 'game',
        scene: {
            preload: preload,
            create: create
        }
    };
    
    var game = new Phaser.Game(config);
    
    function preload() {
    }
    
    function create() {
    }    
});

Even in this relatively small code snippet, there’s quite a bit going on:

  1. We create a configuration object, which we pass to the Phaser.Game constructor to specify where the framework should call our code.
  2. We indicate to Phaser, via, type: Phaser.WEBGL, that we want to use the WebGL-based renderer, which is faster than plain Canvas 2D-based rendering.
  3. We tell Phaser to render into an existing <canvas> where id="game", or to create such a <canvas> element if one does not exist.
  4. We embed a scene object, which points to two functions Phaser will call at different points in the game lifecycle.

Now, let’s run our game! Type the following in your terminal:

cordova run browser -- --livereload

Next, to actually see the game in your browser, visit http://localhost:8000 in your browser. Check out the output!

Empty black screen for new Phaser based game

Beautiful! It’s an empty black screen!

Adding Game Objects

As you can probably imagine, nobody wants to just sit there and stare at an infinitely-blank screen. So let’s spruce it up and add something that moves!

Phaser has long been based on object-oriented programming, but Phaser 3 introduces the categorization of certain objects as game objects, which share common functionality while achieving different goals. The kind of game object we’ll be adding now is called a sprite, which in the 2D world means “image that represents an object.” Common examples of sprites include animated sprites, which are often used to represent characters in games.

Even though a sprite by itself is just an image, in the context of a game engine like Phaser, it is frequently associated with physics computations, and provides an abstraction through which a game can programmatically change what’s visible on screen in a logical way.

Using an asset from Kenney, let’s load an image and draw it to the screen.

File screen with sheet.png and sheet.xml selected

First, let’s download the Tappy Plane Asset Pack. Copy SpriteSheet/sheet.png and SpriteSheet/sheet.xml into the local www/img directory. We’ll load these into our game by modifying our preload and create functions as follows:

function preload() {
   this.load.atlas('sheet', 'img/sheet.png', 'img/sheet.json');
}
    
function create() {
    this.add.sprite(400, 300, 'sheet', 'planeBlue1.png');
}

Note that img/sheet.json is included in the project assets, and is based on the contents of img/sheet.xml.

Quite a bit happened in the lines above. First, we told Phaser that we have a texture file, img/sheet.png, and that the framework should use the contents of img/sheet.json to find the location of frames within the image. img/sheet.json contains a map of frames that map names (i.e. planeBlue1.png) to distinct locations and sizes within the texture file, which contains the entire Tappy Plane pack compressed into a single image.

Next, we created a sprite that references planeBlue1.png within our sheet asset. As mentioned earlier, though a Sprite is just an image, in Phaser, we can use it to perform physics computations and another complex transformations.

Refresh the page to see the current game:

Phaser 3 game with airplane object

Animating the Sprite

The blue plane sprite included in Kenney’s Tappy Plane pack includes three frames, which can be combined to create an animation. Change the create function as follows:

function create() {
    this.anims.create({
        key: 'plane',
        repeat: -1,
        frameRate: 10,
        frames: this.anims.generateFrameNames('sheet', { start: 1,  end: 3, prefix: 'planeBlue', suffix: '.png' })
    });
        
    var plane = this.add.sprite(400, 300, 'sheet').play('plane');
}

Firstly, we register an animation configuration in Phaser’s AnimationManager. Using the generateFrameNames helper, we specify that the animation contains the frames planeBlue1.png, planeBlue2.png, and planeBlue3.png. The animation we create, named plane, can be applied to any sprite; however, for this example, we will only apply it to our plane sprite.

Next, we add .play('plane') to our instantiation of the plane sprite. Reload the page, and you’ll see the plane’s turbine spinning infinitely!

Note that the plane key corresponds to the key of the animation object we created.

Adding a Background

Of course, a game with a boring, empty background is (usually) a boring, empty game. Let’s add a background sprite, right before creating our plane. create should look like this:

function create() {
    this.anims.create({ ... });
    this.add.image(0, 0, 'sheet', 'background.png').setOrigin(0);
    var plane = this.add.sprite(400, 300, 'sheet').play('plane');
}

Note the setOrigin(0), which tells the image to position itself according to its top-left corner, rather than the middle (the default origin is 0.5).

Let’s take a look at the game now:

Phaser 3 game with airplane sprite and mountain background

Scaling the Game

As you’ve likely noticed, there’s still a lot of dead space. We can eliminate this by explicitly sizing the game canvas to the size of our background image, 800x480.

Modify the game configuration like so:

var config = {
    type: Phaser.WEBGL,
    parent: 'game',
    width: 800,
    height: 480,
    scene: {
        preload: preload,
        create: create
    }
};

And voila, empty space gone!

Phaser 3 airplane game with appropriate scaling

One caveat to mobile development is that there is no guarantee of the size of a screen. Even within the context of one device, a resize of the window or orientation switch can throw the scaling of your game completely off-balance. However, with some simple math, we can responsively resize our game. Change your create function as follows (source):

function create() {
    window.addEventListener('resize', resize);
    resize();

    // Earlier code omitted
}

Next, implement the resize function that auto-resize our game canvas:

function resize() {
    var canvas = game.canvas, width = window.innerWidth, height = window.innerHeight;
    var wratio = width / height, ratio = canvas.width / canvas.height;

    if (wratio < ratio) {
        canvas.style.width = width + "px";
        canvas.style.height = (width / ratio) + "px";
    } else {
        canvas.style.width = (height * ratio) + "px";
        canvas.style.height = height + "px";
    }
}

Now, the game will resize automatically when the window does!

Infinite Scrolling

As is the nature of Tappy Plane and Flappy Bird, our background should scroll infinitely. Fortunately, it’s simple to implement this in Phaser. First, let’s update our game configuration to point to an update function we will create. This function will be called once per frame.

var config = {
    type: Phaser.WEBGL,
    parent: 'game',
    width: 800,
    height: 480,
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

Next, let’s change our create function to declare the background image as a tile sprite instead. A tile sprite is a special sprite that can update its position relative to the camera, to create parallax/infinite scrolling phenomena.

this.bg = this.add.tileSprite(0, 0, 800, 480, 'sheet', 'background.png').setOrigin(0);

Lastly, let’s actually implement that update function:

function update() {
    this.bg.tilePositionX += 5;
}

 

Refresh the game, and you’ll see the background continuously scrolling, repeating itself once it reaches the end of the screen.

Note that though we are adding to tilePositionX, it looks as though the background is moving to the left. It helps to think of tile sprites as an endless wallpaper, that we are only viewing a certain piece of at a time. When tilePositionX increases, this is analogous to the viewer’s eyes moving to the right, which creates a parallax effect moving to the left.

Building the Game for iOS and Android

Now for the fun part: Running our game on mobile! First off, add the ios and android platforms to the codebase:

cordova platform add ios android

If this errors, you may need to delete package-lock.json.

Next, we can use cordova to run our app in an emulator:

cordova emulate ios

This will bring our app up in the iOS Simulator (granted, you’ll need to install that, which comes bundled with XCode, first):

iOS simulator running airplane flying Phaser 3 game

Distributing the Game

Lastly, we eventually will want to publish and distribute our game. Whether through the App Store, the Google Play Store, or another app distribution platform, our game needs to be downloadable and easily accessible in order for our users to get their hands on it.

Firstly, you’ll need to build your app in release mode. Try the following for iOS:

cordova build --release ios

The steps to build a properly signed application for iOS are quite intensive, and include the following steps:

  • Sign the application
  • Register an app ID
  • Make a provisioning profile
  • Modify app configuration
  • Submit to the App Store

This process is well summarized in this article; for the sake of not reinventing the wheel, I’ve linked to it, rather than rewriting content.

After that, you’re done! Good work.

Conclusion

Apache Cordova is a great solution for running applications originally aimed at web browsers on mobile devices. By wrapping such applications in webview wrappers, Cordova lets us produce a “native” (notice the quotes) experience across multiple platforms. This is great when writing games, because it eliminates the need for rewriting code to target different platforms.

With Phaser, we can create games with Cordova that run in the browser, iOS, and Android.

Stick around for the next tutorial, where we continue with the Tappy Plane Pack and turn this into a real game!

]]>