(click anywhere to close)
OPEN MENU

[Phaser] Tips & Tricks

category: Games | course: Phaser | difficulty:

When you've just started learning Phaser, there a few things you don't know. It's once you really start using it for creating something, that you run into problems and learn that most of the time Phaser has a cool, easy way to do it...or that there's a certain workaround or different approach that is favourable. Anyway, here's the sequel to the advanced guide, the professional tips & tricks!

For some parts I assume you use different states in your game. If you don't, that's fine, you'll just have to adapt the examples a bit to your specific situation.

Common mistakes and debugging

Here's a list of things that often go wrong with horrible results, without you realizing what the heck you did wrong this time. I'll also show you some ways to debug your code to find what causes the errors.

Common Mistakes
Declaring and referencing functions

If you're using states, often you'll get an error a certain function is undefined. This can have two reasons: the function is defined incorrectly, or it is called upon incorrectly. Let's say we call the function 'doStuff' in the standard 'update' function, it'd go like this:

update: function() {
	this.doStuff(aParameter);
},

doStuff: function(aParameter) {
	
},
Declaring and referencing variables 

In the same way, there can be some trouble with variables. If a variable isn't defined or of the correct type/value, it often throws vague errors or doesn't run your program at all. Remember this:

//GLOBAL VARIABLES
//Either in index.html
var globalThing = value;
var game = new Phaser.Game(blablabla);

//Or at the top of your first state, outside of the states object
var Scenes = {};
var globalTime = 0;

//They are used as you'd expect! For example:
globalTime = 2;


//LOCAL VARIABLES
//Set inside the object class of the state
Scenes.Main = function(game) {
   this.aVar = value;
   this.anotherOne = false;
}

//They are used with 'this.' in front. Always. Like this:
this.anotherOne = true;

If you somehow forget to put 'var' in front of your variables...It's actually no big deal, according to the JS compiler. What happens is: JS reads the variable, and thinks it has been declared earlier (because it has no var before it). However, it will not find this declaration, and will then continue to assign the variable to the highest level in the hierarchy of the game (which is the browser window in this case). So you've basically created a global variable, without it really being a global variable. It can even be useful, but I highly recommend you just don't use it, for it can cause weird errors that are very hard to debug (and you should learn proper programming, of course).

Mixing up syntax

Another error that can happen often, is that you're just in a flow, coding fast and happily, and without you realizing it you mix up different systems/syntaxes. You for example mix the syntax of a while-loop with the one of a for-loop, you mix the syntax for setting properties of an object with the one for setting variables, you call an object and use it's paramaters while you forget to pass any to it, etc. This kind of error is very hard to realize yourself, once you've made the mistake. So, now you know it, check it!

Forgetting some words

Especially when working with JS libraries, like Phaser, there's a very long line of code needed sometimes. You might forget to put a word in there, you might add one dot too much, you might forget that this one actually calls a function and does not return a boolean, etc. For example, a few of the mistakes I often made at the beginning:

//Adding a body to the player...WRONG
game.physics.enable(player);
//It's like this
game.physics.arcade.enable(player);

//Or forgetting the player already had a body...WRONG
player.velocity.x = 20;
//It's like this
player.body.velocity.x = 20;

//Or you might think you can quickly push a new object into an array...WRONG
var blockContainer = [];
var newBlock = this.add.sprite(50,50,'block');
blockContainer.push();
//You forgot to actually push something into it..
blockContainer.push(newBlock);
Resetting variables when switching states 

The Phaser's stateManager is quite powerful, and removes almost everything from a seen, but there might be some variables that are left over and remembered. If you need to come back to the same state within the same game (for example a Main Menu), you need to reset variables to the value they need to start with. For this, Phaser has a shutdown standard function (yes, next to preload, create and update). Within this function you can just set the variables you really need set to a certain value at the beginning of the scene.

Debugging
Logging to the console

If you're on chrome, hitting F12 will bring up the developer tools, and at the top you should see a few tabs, and the last of them is Console. This will display any errors it encounters loading your game, but it's also the place you can send information to test things. It's a simple as this:

console.log("I'm loggin' this!" data-lang="javascript">console.log("I'm loggin' this!");
console.log("Player's x position: " + player.x);
Phaser's built in debugging system

However, Phaser also has it's own built-in debugging system, to simplify matters a bit. It's basically the same as the console.log(), but it displays the result on the screen and updates in realtime. Just do:

//Debug functions must be put inside a special render function that is called just before Phaser renders the game to the screen
render: function() {
	game.debug.text(xPosition, yPosition, "Our player's speed is " + player.velocity.x);
}

So, now you know how everything's running the show, but you still can't find where the error is in those 30 new lines of code you just wrote? Well, the simplest method to find the culprit, is to simply comment out parts of your code, until you don't have the error anymore. This approach works better if you divide the block of code in two halves every time, instead of taking for example 5 lines every time.

Display your game's FPS

One thing you might need to display, is the FPS (Frames per Second) of your game. This shows you when or whether the game is lagging a bit, which can help you in making your game faster and your code more efficient. It goes like this:

//Set this flag to true in the create function
this.time.advancedTiming = true;

//Then read the FPS in the update function
this.time.fps

//For example: display it with Phaser's debugging system
game.debug.text(50,100,this.time.fps);

Phaser's useful properties/attributes and functions added to (almost) everything

Everything in Phaser has a bunch of properties you can read and set, which are pretty mandatory for creating anything.

var player = this.add.sprite(100,100,'playerImage');

//The x and y position
player.x, player.y

//The rotation
player.rotation

//The anchor (center point), (0 -> 1) in percentages of complete sprite
player.anchor.x, player.anchor.y

//The scale
player.scale.x, player.scale.y

//The width and height
player.width, player.height

//The name 
player.name

//Check if it exists
//If false, it is invisible. If true, it is visible
player.exists

//Check if it's alive
//If false, the game pretends it's not there. If true, it does affect gameplay like usual
player.alive

//Fix it to the camera (boolean)
player.fixedToCamera

//Check if it's in the game camera or game world (boolean, readonly)
player.inCamera, player.inWorld

//Kill it when it's outside of the game world's bounds
player.checkWorldBounds = true;
player.outOfBoundsKill = true;

//For controlling something's health
player.health

//Set a lifespan (in ms) until something's killed
player.lifespan

//Check whether it is being destroyed (boolean, readonly)
player.destroyPhase

Because phaser sprites are objects, you can always attach your own custom properties to it. Like player.roleInTeam, player.bulletsLeft, etc.

NOTE2: With any property that has an x and value, you can also just use the following: .setTo(xVal, yVal); Next to this (yes, there is more, more awesomeness!) there are also some standard methods useful for a lot of things.

//Crop the player's sprite into the rectangle specified
player.crop(rect);

//If the player's health property is set, the specified amount will be substracted from it
player.damage(amount);

//Destroy the sprite. This completely removes the sprite, never to be seen again.
// The destroyChildren boolean determines whether or not the sprite's children (if it were a group or container) should be destroyed too
player.destroy(destroyChildren);

//Kill the sprite. This simply makes the sprite invisible, frozen and indetectable, but it can be revived
player.kill();

//Check if this sprite overlaps with the 'someObject'
player.overlap(someObject);

//Completely reset something, giving it only a new x,y position and health value to start again with
player.reset(x,y,health);

//If a player was killed, you can revive it this way!
//(and setting an health along the way, but that's purely optional)
player.revive(health);

So, one important thing to remember is, that killing and destroying something is a different activity. Killing a sprite, will set 'alive' to false and 'exists' to false (and therefore 'visible' to false). But, the sprite will live on, and can be revived at any time. However, destroying a sprite, will remove all of it, forever, never to be seen again.

About efficiency and CPU-friendliness

This brings us to our next topic: efficiency of resources. The fact is: HTML5 games are not as powerful as PC or console games. We have to be extra careful with how we use our resources. Therefore, it's a good idea to look at what you really need, and what not. If you need something the first time, you of course need to create it. But if you for example need lots and lots of instances of bullets, but the bullets often fly off screen, you can reuse the bullets flying off screen as new ones. This can be done by kill()ing it, and later revive()ing it. If you don't need something anymore, you're better off completely destroy()ing it so it doesn't take up any more CPU.

Input: mouse, keyboard, touch, watever you like

We've actually got a nice seperate tutorial on all the input possibilities! Check it out

CONTINUE WITH THIS COURSE
Do you like my tutorials?
To keep this site running, donate some motivational food!
Crisps
(€2.00)
Chocolate Milk
(€3.50)
Pizza
(€5.00)