0% found this document useful (0 votes)
25 views107 pages

PhaserByExample v2 5

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views107 pages

PhaserByExample v2 5

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 107

Game Object Creator

The role of the Game Object Creator is to create Game Objects based on
configuration objects. You can also elect to have them automatically added
them to the Scene, or not. This makes Creator functions very useful for
creating Game Objects in advance, so you can avoid object instantiation
during time-critical parts of your game, such as when it is running.
The main differernce between the Game Object Creator and the Game Object
Factory is that all Creator functions take configuration objects. Where-as
the Factory functions take fixed arguments. Which one you use is up to you.
The Creator is more flexible and has some powerful features when parsing the
config objects, but the Factory functions are easier to understand, remember
and parse from languages like TypeScript.
The Creator itself is a very small class, providing just a few properties and
hooks. Its power comes from the fact that all Game Objects register them-
selves with it, dynamically extending the class with new methods. You can
even create your own Game Objects that include a creator function, allowing
you to extend the Creator to suit your own needs.
Every Scene has an instance of the GameObjectCreator class. By default,
this is mapped to the Scene’s make property. For example, here is how to
create a Sprite via the Game Object Creator:
const sprite = this.make.sprite({
x: 400,
y: 300,
key: "playerAtlas",
frame: "idle",
});
The above example makes some assumptions, such as the texture key and
frame name, but you should take it as an example of a simple configuration
object, rather than something you can copy and paste.
Internally, there is no actual sprite method in the Game Object
Creator itself. If you were to open the class file in an editor, you
won’t find it. This is because each Game Object is responsible for its
own creator function. The Sprite creator code can be found in the

428
src/gameobjects/sprite/SpriteCreator.js file within the Phaser repos-
itory. Nearly all Game Objects have similar Creator.js files, which are
responsible for registering themselves with the Creator.
All Creator functions call the static GameObjectCreator.register function,
and pass it the name of its own creator function, sprite, and a callback. The
register function will take this callback and add it to the Creator, under
the sprite property.
And it is this callback that is invoked whenever you call this.make.sprite in
your game code. In this case, it’s responsible for creating the Sprite instance
from the config object and adding it to the display list, but any actual logic
can take place here.
The callback is invoked using the Game Object Creator as the context, mean-
ing that this within the callback is a reference to the Creator itself.
It’s important to understand that while each Scene has its own instance of
the Game Object Creator, registration of Game Objects with the Creator is
global. This means that once a Game Object has been registered, its creator
function is available to use from any Scene in your game.
At the end of the day, the Creator is all about convenience. It allows you to
create Game Objects without having to worry about the internal details of
how they are created. It also allows you to extend the Creator with your own
Game Objects, or even override the existing ones, allowing you to customize
the Creator to suit your own needs.

How to set Configuration Properties


As we’ve seen above, you pass in configuration objects to the Creator func-
tions in order to make the Game Objects. These config objects are parsed by
the Creator and the values are used to set the properties of the Game Object
being created, such as its position, scale, or rotation.
However, the way in which these properties are parsed is where the real
power of the Creator comes in. Most properties are set through a Phaser
function called GetAdvancedValue, which allows the properties to expressed
in 5 different ways.
For brevity we’ll focus just on creating a Sprite and settings its x/y coor-

429
dinates. However, you can actually use this approach on nearly all Game
Object properties (see the table below).

1. Explicit Value
The first and most obvious way is to simply provide a fixed value:
const sprite = this.make.sprite({
x: 400,
});
The Sprite will have an x position of 400.

2. Random Array Value


You can pass in an array of values, in which case a random element from the
array will be selected and used:
const sprite = this.make.sprite({
x: [400, 500, 600],
});
The Sprite x position will be randomly picked from the given array. So, its x
coordinate could be 400, 500 or 600. You can pass in as many values as you
like, and the Creator will pick a random one from the array each time.

3. Random Integer Between Min and Max


You can pass in an object with a randInt property. This should be a 2
element array, where the first element is the minimum value and the second
is the maximum. A random integer between the two will be selected and
used:
const sprite = this.make.sprite({
x: { randInt: [100, 600] },
});
The Sprite x position will be a random integer between 100 and 600.

430
4. Random Float Between Min and Max
You can pass in an object with a randFloat property. This should be a 2
element array, where the first element is the minimum value and the second
is the maximum. A random float between the two will be selected and used:
const sprite = this.make.sprite({
x: { randFloat: [100, 600] },
});
The Sprite x position will be a random float between 100 and 600.

5. Callback Value
Finally, you can pass in a callback function. This should return a value,
which will be used as the property value:
const sprite = this.make.sprite({
x: function (key) {
return Math.random() * 800;
},
});
The Sprite x position will be a random float between 0 and 800. The callback
is sent one parameter, the key of the property being set. In the example
above, key would be x.

Game Object Configuration Properties


The following table lists all of the properties you can set on any Game Object.
Most Game Objects have additional properties beyond this list, however, the
following are common to all Game Objects.
All property values can be expressed via any of the 5 methods outlined above.
Property | Data Type |

431
Game Object Factory
The role of the Game Object Factory is to create Game Objects for you and
add them to the Scene, making them immediately ready for use.
The Factory itself is a very small class, providing just a few properties and
hooks. Its power comes from the fact that all Game Objects register them-
selves with it, dynamically extending the class with new methods. You can
even create your own Game Objects that include a factory function, allowing
you to extend the Factory to suit your own needs.
Every Scene has an instance of the GameObjectFactory class. By default,
this is mapped to the Scene’s add property. For example, here is how to
create a Sprite via the Game Object Factory:
const sprite = this.add.sprite(x, y, key);
Internally, there is no actual sprite method in the Game Object Factory
itself. If you were to open the class file in an editor, you won’t find it. This is
because each Game Object is responsible for its own factory function. Here
is the one for the Sprite:
GameObjectFactory.register("sprite", function (x, y, texture, frame) {
return this.displayList.add(new Sprite(this.scene, x, y, texture, frame));
});
This code can be found in the src/gameobjects/sprite/SpriteFactory.js
file within the Phaser repository. Nearly all Game Objects have similar
Factory.js files, which are responsible for registering themselves with the
Factory.
You can see the code is calling the static GameObjectFactory.register
function and passing it the name of its own factory function, sprite, and
a callback. The register function will take this callback and add it to the
Factory, under the sprite property.
And it is this callback that is invoked whenever you call this.add.sprite in
your game code. In this case, it’s responsible for creating the Sprite instance
and adding it to the display list, but any actual logic can take place here.
The callback is invoked using the Game Object Factory as the context, mean-
ing that this within the callback is a reference to the Factory itself. This

432
is why you can see it accessing the this.displayList property. This is a
property available in the Game Object Factory class, which is a reference to
the Scene Display List.
It’s important to understand that while each Scene has its own instance of
the Game Object Factory, registration of Game Objects with the Factory is
global. This means that once a Game Object has been registered, its factory
function is available to use from any Scene in your game.
At the end of the day, the Factory is all about convenience. It allows you to
create Game Objects without having to worry about the internal details of
how they are created. It also allows you to extend the Factory with your own
Game Objects, or even override the existing ones, allowing you to customize
the Factory to suit your own needs.

How to bypass the Game Object Factory


If you wish to create a Game Object without using the Factory, you can do
so by calling the Game Object constructor directly. For example, to create
a Sprite you would do this:
const sprite = new Phaser.GameObjects.Sprite(scene, x, y, key);

sprite.addToDisplayList();

Removing a Factory Function


If the Game Object Factory already has a function registered with a given
name, it will simply skip any further registations for the same name. There-
fore, if you wish to replace one of the internal Phaser Game Objects with your
own, you will need to remove the existing entry first before adding yours.
You can do this by calling the remove method:
Phaser.GameObjects.GameObjectFactory.remove("sprite");
This will remove the sprite method from the Factory, allowing you to then
add your own with the same name. This process is immediate.

433
Adding Custom Game Objects to the Game Object Fac-
tory
You can extend the Game Object Factory by adding your own Game Objects
to it. This is done by calling the static register method on the Factory
itself. This method takes two arguments: The name of the Game Object,
and a callback function that will create an instance of it.
Here is a simple class for our custom Game Object:
class Bomb extends Phaser.GameObjects.Sprite {
constructor(scene, x, y) {
super(scene, x, y, "bomb");

this.setScale(0.5);
}

preUpdate(time, delta) {
super.preUpdate(time, delta);

this.rotation += 0.01;
}
}
This is a very simple Game Object that extends the Sprite class. It’s a
bomb that spins around on the screen, as managed by the rotation in the
preUpdate. We will register this with the Game Object Factory using the
bomb key. We’ll do this in our Scene init method:
class Example extends Phaser.Scene {
init() {
Phaser.GameObjects.GameObjectFactory.register("bomb", function (x, y) {
return this.displayList.add(new Bomb(this.scene, x, y));
});
}
}
The init method is called first in a Scene. This means we can safely register
our custom Game Object here, and it will be available for use in the Scene
create method:

434
create();
{
this.add.bomb(200, 200);
this.add.bomb(400, 300);
this.add.bomb(600, 400);
}
You can see the full example here: [file: gameobjects/custom-factory.js]
When coding your register functions you have access to the following proper-
ties:
Property | Description |

435
Game Objects
All Game Objects in Phaser extend from a base class called Phaser.GameObjects.GameObject.
On its own, this class can’t do much. It cannot render, for example, or be
added to the display list. What it does do is provide all of the building
blocks and core functionality that Game Objects need.
In this section we will cover the properties and methods that the base Game
Object class has. This means, anything you read in this section is also
available in every other Game Object within Phaser.

Scene
A Game Object can only belong to one Scene. A reference to the Scene it
belongs to is available in the scene property:
const scene = sprite.scene;
Although it isn’t, for internal reasons, you should consider this property as
read-only. You cannot change the Scene that a Game Object belongs to once
it has been created. The scene property is passed in the constructor of the
Game Object and is set immediately.
When a Game Object is destroyed, the reference to the Scene is nulled-out.
If you get any errors in your code relating to an ‘undefined’ Scene, then make
sure you are not dealing with a destroyed Game Object.
Game Objects have two callbacks that are invoked when they are added to,
or removed from, a Scene:
class MySprite extends Phaser.GameObjects.Sprite {
constructor(scene, x, y, texture, frame) {
super(scene, x, y, texture, frame);
}

addedToScene() {
super.addedToScene();

// This Game Object has been added to a Scene


}

436
removedFromScene() {
super.removedFromScene();

// This Game Object has been removed from a Scene


}
}
You are free to use these callbacks in your custom Game Objects, in order to
set-up any Scene specific data, or to perform any tasks that need to happen
when the Game Object is added to, or removed from, a Scene. Be aware that
some Game Objects, such as Sprites, use these callbacks, so make sure you
always call super when overriding them, as in the example above.
Instead of using the callbacks, you can listen for the ADDED_TO_SCENE and
REMOVED_FROM_SCENE events instead:
sprite.on(Phaser.GameObjects.Events.ADDED_TO_SCENE, handler);
sprite.on(Phaser.GameObjects.Events.REMOVED_FROM_SCENE, handler);
Both event handlers are sent a reference to the Game Object as the first
parameter, and the Scene as the second.

Display List
If the Game Object resides on a Display List, which most do, then this is
available via the displayList property:
const list = sprite.displayList;
A Game Object can either be on a Display List that belongs to its parent
Scene, or it can be on a Layer that belongs to the Scene. This property can
also be null. As with the scene property, you should consider this property
as read-only and never change it directly.
The displayList property is set when the methods addToDisplayList and
removeFromDisplayList are called. This happens automatically when you
create a Game Object via the Game Object Factory, or add or remove it from
a Layer.
A Game Object can only exist on one Display List or Layer at any given
time, but may move freely between them. If the Game Object is already on

437
another Display List when this method is called, it will first be removed from
it, before being added to the new list.
If a Game Object isn’t on any Display List, it will not be rendered. If you just
wish to temporarly disable it from rendering, consider using the setVisible
method, instead of adding and removing it.
The act of adding and removing a Game Object will emit the ADDED_TO_SCENE
and REMOVED_FROM_SCENE events respectively.
It’s not common to need to call these methods directly, but they are exposed
should you require them.

State and Name


The state property is a number or string value that you can use to store
the current state of a Game Object. Use this property to track the state
of a Game Object during its lifetime. For example, it could change from
a state of ‘moving’, to ‘attacking’, to ‘dead’. The state value should be an
integer (ideally mapped to a constant in your game code), or a string. These
are recommended to keep it light and simple, with fast comparisons. If you
need to store complex data about your Game Object, look at using the Data
Component instead.
sprite.state = "ALIVE";
You can also call the chainable setState method:
sprite.setState("ALIVE");
The name property is a string-based name that you can use to identify a
Game Object. For example, you could use it to store the type of Game
Object, such as player or enemy.
sprite.name = "player";
You can also call the chainable setName method:
sprite.setName("player");
Neither of these properties are ever used by Phaser directly. They are made
available purely for you to take advantage of to help structure your games.

438
Update List and Active
Every Scene has an Update List. This is a special type of list that is respon-
sible for calling the preUpdate method on all Game Objects on the list, once
per game step. Some Game Objects need this, others don’t. For example,
a Sprite needs to have its Animation component updated every frame, so
it adds itself to the Update List. However, a Text object doesn’t have any
components that require updating, so it doesn’t add itself to the Update List.
If you create a customn class, then you can choose if it should be added to
the Update List, or not. You can do this by calling its addToUpdateList
method:
sprite.addToUpdateList();
As long as the Game Object has a preUpdate method, and doesn’t already
exist on the Scene Update List, it will be added. You can then use the
preUpdate method to run any customn logic that your Game Object requires,
i.e.:
class Bullet extends Phaser.GameObjects.Image {
constructor(scene, x, y) {
super(scene, x, y, "bullet");

this.addToUpdateList();
}

preUpdate(time, delta) {
this.x += 10;

if (this.x > 800) {


this.setActive(false);
this.setVisible(false);
}
}
}
Here we have a custom Game Object called Bullet. It extends from
Phaser.GameObjects.Image, which doesn’t use the Update List by itself
usually. This is why we call addToUpdateList in the constructor. It then
uses the preUpdate method to move itself across the screen, and if it goes

439
off the edge, it deactivates itself. This means it will no longer be updated by
the Update List, and will be skipped in future game steps.
When preUpdate is called, it is sent two parameters by the Update List. The
first is the current timestamp, as generated by the browser. The second is
the delta value, which is derived from the timestamp. This is the difference
between the current frame and the previous frame. It is a value expressed
in milliseconds and is the amount of time that elapsed between frames. This
is what you should use to update your Game Object, rather than relying on
setTimeout or other methods, because it handles pauses and slowdowns in
the browser.
Related to the Update List, the active property is a boolean that controls
if the Game Object is processed by the Update List, or not. A Game Object
that is active will have its preUpdate method called during the game step,
otherwise it will be skipped:
sprite.active = false;
You can also set the active state of a Game Object by calling the chainable
setActive method:
sprite.setActive(false);
As mentioned, not all Game Objects are added to the Update List. For ex-
ample, toggling this property on a basic Image Game Object won’t actually
change anything, because Images are not updated by the Update List. How-
ever, if you have a custom Game Object that is on the Update List, this is
how you toggle it being processed, or not, without needing to add and remove
it from the list.

Parent Containers
A Game Object can only have one parent Container. A reference to the
Container it belongs to is available in the parentContainer property:
const container = sprite.parentContainer;
You should consider this property as read-only. It is set automatically when
you add the Game Object to a Container, and nulled when it is removed, or
destroyed.

440
Related to this is the method getIndexList. This will return an array of all
the indexes of the Game Objects ancestors, going from its position up to the
root of the Display List, via any parent Containers:
const indexes = sprite.getIndexList();
Internally, this is used by the Input Plugin. But you can call it directly if
you need to know the depth of the Game Object within the Display List
hierarchy.

Additional Methods
Game Objects also have methods relating to their Data Component and
Input Component. Due to the size of these components, they are covered in
their own respective sections.

441
Game Objects
Mask Component

Figure 49: bitmapmask

The Mask Component allows you to set if a Game Object should be ‘masked’
during rendering. A mask controls which pixels of the Game Object are
visible during rendering. Anything outside of the mask is not rendered. In
Phaser there are two types of mask: a Bitmap Mask and a Geometry Mask.
The current mask of a Game Object is stored in its mask property:
const mask = sprite.mask;
You can set the mask of a Game Object using the chainable setMask method:
sprite.setMask(mask);

442
Or, you can set the mask property directly:
sprite.mask = mask;
To remove a mask, you can either call the chainable clearMask method:
sprite.clearMask();
Or, set the mask property to null:
sprite.mask = null;
When using the clearMask method you also have the option of destroying
the mask currently attached to the Gamne Object:
sprite.clearMask(true);

How Masks Work in Phaser


There are two types of mask in Phaser, which we will cover in the next two
sections. Although they offer different features they are both created and
applied in the same way.
Masks are global objects. They are not bound to, or belong to any one single
Game Object. You can, and often should, use the same mask on as many
different Game Objects as you like, at the same time.
Masks are created and positioned in world space only. They are not applied
relative to the Game Object they are masking. For example, if you create a
mask positioned at world coordinates 200x300, then it will be positioned at
200x300 regardless of where the Game Object it is masking is.
Masks themselves are not Game Objects, they do not live on the display
list and cannot be modified like a Game Object, i.e. you cannot set their
rotation or scale as you would a Sprite. That does not mean you cannot
modify a mask post-creation, it simply means that mask objects do not have
a Transform component.

Geometry Mask
A Geometry Mask is a special type of mask that uses the path information
from a Graphics Game Object in order to define its shape.

443
With the Canvas Renderer it uses the ‘clipping path’ feature of the Canvas
API. The WebGL Renderer uses a built-in WebGL feature called the Stencil
Buffer.
It’s called a Geometry Mask because it uses geometric data in order to create
itself. Graphics Game Objects have lots of features available for generating
these paths, including lineTo, arc, ellipse and more. Please see the Graph-
ics Game Object documentation for more details.
Because it uses path data for the mask it means you cannot do ‘per pixel’
masking with this type of mask. It’s not suitable for creating a mask from
a sprite with a gradient texture, for example. For that you should use a
Bitmap Mask instead.
Geometry Masks have the ability to set their invertAlpha boolean proper-
ties. This is a WebGL only feature and allows you to ‘invert’ which area of
the mask is applied, or not.

Bitmap Mask
A Bitmap Mask uses a texture in order to control which pixels will be ‘masked
out’ of the target Game Object during rendering. In order to achieve this it
uses a special internal pipeline called the BitmapMask Pipeline. Because of
this, it only works with the WebGL Renderer.
As it uses a texture for the shader input it means you can mask things on a
per-pixel level, something not possible with the Geometry Mask. The source
of the Bitmap Mask can be either a texture-based Game Object, such as a
Sprite, or a Dynamic Texture instance.
The Bitmap Mask shader works by taking the alpha level from the mask
texture and the alpha level of the masked Game Object and calculating the
final resulting alpha level from the two, per pixel. It does not matter what
color the mask texture is drawn in, all it looks at is the alpha value of each
pixel. For example, if the mask has an alpha value of 0.95 for a specific pixel,
and the Game Object texture has an alpha of 0.5 for the same pixel, the final
alpha value when rendered will be 0.45. Naturally, the lower the resulting
alpha value, the less the Game Object will be visible through it.
Bitmap Masks have the ability to set their invertAlpha boolean properties.
This allows you to invert the alpha comparison, so that a low alpha value in

444
the mask texture results in a high alpha value in the masked Game Object,
and vice versa.
Note that you cannot set a Bitmap Mask and a Blend Mode on a single
Game Object.

Performance Considerations
When using Geometry Masks you should keep in mind the complexity of
the path, i.e. how many points it has in it. The more complex the path,
the longer it will take both Canvas and WebGL to render the masked Game
Objects.
When using Bitmap Masks you should keep in mind the size of the masked
texture. The larger it is, the more pixels have to be passed through the mask
shader and the more GPU power will be required to render the masked Game
Objects.
With both types of mask, the renderer needs to perform a lot of additional
calculations to handle the masking. This includes breaking the batch in
WebGL, enabling the stencil functions or mask shader and then rendering
the masked Game Objects. For this reason you should never apply a mask
to a Game Object that doesn’t yet require it.
Masks are, however, batched. This means if you have a group of masked
Game Objects in sequence in the Display List, all sharing the same mask,
then you will only pay the cost of establishing that mask once.

445
Game Objects
Origin Component
By default most Game Objects are centered on their x and y coordinates.
This means that if you create a Sprite at the coordinates 300x200, then the
center of the Sprite will be placed at 300x200.
In some game frameworks the default origin is the top-left, and in others the
bottom-left. It is also sometimes known as the ‘anchor point’ or ‘pivot point’.
However, in Phaser it’s called the origin and it defaults to the center. You
can change this via the methods available from the Origin Component.
The current origin of a Game Object is stored in its originX and originY
numeric properties:
const originX = player.originX;
const originY = player.originY;
To set the origin of a Game Object you can use the chainable setOrigin
method:
player.setOrigin(x, y);
Or, you can set the originX and originY properties directly:
player.originX = 0.5;
player.originY = 0.5;
The values are given as a normalized value between 0 and 1. For example,
setting the origin to 0.5 means it will be placed exactly in the center of the
Game Object, no matter what its dimensions. A value of 0 would be the
top-left of the Game Object, and 1 would be the bottom-right.
The origin controls both the placement of the Game Object and also the point
around which it rotates. If you wanted to rotate a Game Object around its
top-left corner, you would set its origin to be 0x0.
Or, if you wanted to position a Game Object in the bottom-right of the
screen, and the screen was 800x600 in size, you could set the origin to be 1x1
and its position to be 800x600.
Game Objects can only have one origin. For example, they do not have a

446
unique origin for rotation and another for position, or scale. If you need to
emulate this behavior, you can create use a Container Game Object and then
add your other Game Objects to it.

The Display Origin


Phaser also offers what is known as the Display Origin. This is a way to set
the origin of a Game Object using pixel values instead of normalized ones.
The range of the values is between 0 and the base width or height of the
Game Object.
To set the display origin of a Game Object you can use the chainable
setDisplayOrigin method:
player.setDisplayOrigin(x, y);
Or, you can set the displayOriginX and displayOriginY properties di-
rectly:
player.displayOriginX = 256;
player.displayOriginY = 128;

Custom Frame Pivot


Some software, such as Texture Packer, allows you to define a specific ‘pivot
point’ for a texture frame. This is then exported in the JSON data that
Texture Packer creates. Phaser will look for these custom pivot points and
then set the origin of the Game Object to match it. This is done via the
method setOriginFromFrame:
player.setOriginFromFrame();
This is called automatically if you create a Sprite and provide it with a
texture frame that has a custom pivot point in the data. But you can also
call it directly, if you need to.

447
Game Objects
Pipeline Component
The Pipeline Component controls which rendering pipeline the Game Object
uses to render with. This is only set if the Phaser Game is using the WebGL
Renderer. The Canvas Renderer does not use custom pipelines.
A Pipeline is an internal term and class construct that Phaser uses to handle
rendering different types of Game Object. For example, there is the Multi
Pipeline, which Sprites use, a Rope Pipeline for the Rope Game Object,
and so on. You can also create your own custom pipelines, which can give
you a lot of flexibility and power when it comes to rendering. The Pipeline
Component is how you set a pipeline on a Game Object.
The current pipeline of a Game Object is stored in its pipeline property:
const pipeline = sprite.pipeline;
This will be null by default. It is not set until the Game Object is in-
stantiated. As part of that process, all Game Objects call the initPipeline
method, which is responsible for setting the default pipeline the Game Object
uses. This is an internal method and should not be called directly.
You can set the pipeline of a Game Object using the chainable setPipeline
method:
sprite.setPipeline(pipeline);
Or, you can set the pipeline property directly:
sprite.pipeline = pipeline;
When using the setPipeline method you can pass either a string, or an
instance of a WebGLPipeline to the method. Regardless of which you pass,
it will look-up the pipeline in the Pipeline Manager and if found it will be set
on the Game Object. If you pass a string that doesn’t match any pipeline,
it will be ignored. If you pass a pipeline that isn’t found in the Pipeline
Manager, it will be ignored.
To remove a pipeline, you can either call the chainable resetPipeline
method:

448
sprite.resetPipeline();
Or, set the pipeline property to match the defaultPipeline property:
sprite.pipeline = sprite.defaultPipeline;
The defaultPipeline property is set when the Game Object is first created
and should be treated as read-only.
If you wish to get the string-based name of the pipeline the Game Object is
using, you can call the getPipelineName method:
const name = sprite.getPipelineName();

Pipeline Data
The Pipeline Component also has a pipelineData property, which is an
object that contains data that the pipeline may need during rendering. You
can set a key-value object to be used as the pipeline data by passing it to
the setPipeline method:
sprite.setPipeline(pipeline, { foo: 1, bar: 2 });
Or, you can call the setPipelineData method:
sprite.setPipelineData("key", value);
Pipeline data is not used by any of the default pipelines in Phaser, but is
made available for your own custom pipelines. For example, if you wanted
to create a pipeline that colored Game Objects in a special way, you could
store the color of the Game Object in the pipeline data, ready for it to read
prior to rendering.
Creating custom pipelines is an advanced feature of Phaser and requires
a good understanding of WebGL and GLSL shaders. It will be covered
elsewhere in this guide.

449
Game Objects
Scroll Factor Component
The Scroll Factor Component allows you to control the scroll factor of a
Game Object. The “scroll factor” is how much influence a camera will exert
upon a Game Object as the camera scrolls around the game world.
As covered in the Transform section, Game Objects have a position within
the world. This position is combined with the Scene camera and used to
calculate where the Game Object should be rendered on-screen. If the camera
is moving around the world, the Game Object will appear to move with it,
even though its position hasn’t changed, simply by virtue of the fact that the
camera is now looking at another part of the world.
The scroll factor allows you to modify the relationship between the Game
Objects position and how the Camera projects it. Setting a scroll factor never
changes the position of the Game Object, or any related physics bodies, it
just changes where they are rendered by the camera.
The current scroll factor of a Game Object is stored in its scrollFactorX
and scrollFactorY numeric properties:
const scrollFactorX = player.scrollFactorX;
const scrollFactorY = player.scrollFactorY;
To set the scroll factor of a Game Object you can use the chainable
setScrollFactor method:
player.setScrollFactor(x, y);
Or, you can set the scrollFactorX and scrollFactorY properties directly:
player.scrollFactorX = 0.5;
player.scrollFactorY = 0.5;
The default value for each axis is 1. This means as the camera scrolls, the
Game Object will appear to move at the exact same rate.
A value of zero will stop the Game Object from being influenced by the
camera. This will effectively ‘lock’ it in place on the screen. This can be
useful if you wish to create a UI or other interface element that remains in
the same place regardless of where the camera is looking.

450
A value of 0.5 will make the Game Object move at half the rate of the camera.
The scroll factor can be any value from zero and above, although realistically
you would likely clamp it to a value between 0 and 1.

451
Game Objects
Sprites and Images

Figure 50: single image

Sprites are easily one of the most commonly used Game Objects in the whole
of Phaser. On a fundamental level a Sprite isn’t much more than a texture
mapped quad (a rectangle), but they have a lot of special features and func-
tionality that make them worth using, not least the ability to automatically
load and play animations.
The reason this section is covering both Sprite and Image Game Objects is
because they are almost identical. The only difference between them is that
the Image Game Object does not have the Animation Component as part
of it. So if you don’t need frame-based animation, then you can safely use
an Image in place of a Sprite. A common example of doing this would be a

452
game logo, or background, or other non-animated element.
Why does Phaser split them like this? It’s because the Animation Compo-
nent, while relatively compact, still takes up extra space in memory. Also,
Sprites have to be added to the Update List, so that their Animation Com-
ponents can be updated each game frame. If you don’t need animation, then
you don’t need to add the extra overhead of the Animation Component, or
the Update List.
Of course, there are lots of games where it will make no actual difference in
terms of performance and it will be safe to use Sprites for everything. But if
you’re making a game that has a lot of static images in it, or you’re at the
point where you are trying to optimize everything, then using Images instead
of Sprites will help.
The term Sprite has its roots back in the hardware of the computers and
arcades of the late 1970s, where it was used to describe a 2D bitmap that
was moved around the screen, over the top of a background. These days, use
of the term has become more generalized.

Creating an Image
Both images and sprites are created via the Game Object Factory. You access
this directly from within a Scene using the add property:
var image = this.add.image(x, y, key);

var sprite = this.add.sprite(x, y, key);


The first argument is the x coordinate, the second the y coordinate, and the
third is the key of the image to use. The key is a reference to an already
loaded image that is available in the Texture Manager.
Usually, you create an image or sprite in the create method of a Scene, but
you can do it anywhere you like, such as in response to a user input event.

453
Game Objects
Transform Component
The Transform Component is responsible for managing the position, scale
and rotation of a Game Object.
Most Game Objects have this component, but you can test for it progra-
matically by checking if the hasTransformComponent property exists and is
true:
if (player.hasTransformComponent) {
// This Game Object has a Transform Component
}

Position
The current local position of a Game Object is stored in its x and y properties.
const x = player.x;
const y = player.y;
You can set the position using the chainable setPosition, setX and setY
methods:
player.setPosition(x, y);
player.setX(x);
player.setY(y);
Or, you can set the x and y properties directly:
player.x = x;
player.y = y;
They can be either negative or positive values, and whole numbers or floats.
The position of a Game Object is always relative to its parent Container, if
it has one. If it doesn’t have a parent, then the position is its location within
the Game World.
For example:

454
container.setPosition(300, 200);
child.setPosition(100, 100);
In the code above, the Container is positioned at 300 x 200 in the game world.
The child of the Container is positioned at 100 x 100. This means that the
child will appear at 400 x 300 in the game world, because its position is
relative to the Container.
container.setPosition(300, 200);
child.setPosition(-100, -100);
In this code, the child will appear at 200 x 100 in the game world, because
it has a negative position, relative to its parent.
The position is always set and returned as a number. This allows you to use
the position directly in further calculations, or manipulate it as you would
any other number:
enemy.x = player.x;
enemy.y = player.y - 100;
See the Origin Component to learn how Phaser knows which point of the
Game Object to use as its x/y anchor.
Phaser also has two additional position related properties: z and w. You
can set these optional values when calling setPosition, or they have their
own chainable methods setZ and setW. These properties are not typically
used internally by Phaser, but are made available should you require them
for more advanced position, such as depth sorting.
The copyPosition method allows you to copy a Game Objects position
directly to another object:
enemy.copyPosition(player);
The target object can be any object that has public x and y properties, such
as another Game Object, or a Vector2.
You can also set the Game Object to have a random position with the
setRandomPosition method:
enemy.setRandomPosition();

455
By default, if you don’t provide any parameters, the Game Object will be
given a position anywhere without the size set by the Scale Manager. How-
ever, you can also pass in x, y, width and height parameters to the method,
to control a rectangle in which the random position will be set:
enemy.setRandomPosition(100, 100, 600, 400);
The Geometry classes have a variety of similar methods, for positioning ob-
jects within geometric shapes, however this method is handy if you just want
to quickly position an object anywhere on-screen.

Scale
The current local scale of a Game Object is stored in its scaleX and scaleY
properties.
const scaleX = player.scaleX;
const scaleY = player.scaleY;
You can set the scale using the chainable setScale method:
player.setScale(x, y);
Or, you can set the scaleX and scaleY properties directly:
player.scaleX = x;
player.scaleY = y;
There is also a special property called scale which allows you to set both
the x and y scale at the same time, to the same value:
player.scale = 2;
Scale values can be either negative or positive, and whole numbers or floats.
By default, Game Objects have a scale value of 1, meaning they will be
rendered at the same size as their texture frame. By adjusting the scale
properties you can make them appear bigger or smaller. The number you
give is multiplied by their base size. For example, a scale value of 0.5 would
halve the displayed size of the Game Object, where as a value of 2 would
double it.
Setting a scale does not change the actual underlying size of the Game Object.
If you were to read the width or height of a Game Object after adjusting its

456
scale, the returned values would be the un-scaled original sizes. You can read
more about this in the Size Component section.
The scale is always set and returned as a number. This allows you to use
the scale directly in further calculations, or manipulate it as you would any
other number.
Scaling always takes place around the center of the Game Object, regardless
of the Game Objects origin, and cannot be changed.
The scale of a Game Object is always relative to its parent Container, if it
has one.
For example:
container.setScale(2, 2);
In the code above, the Container is scaled by 2 on each axis, meaning and
all of its children will be doubled in size.
container.setScale(2, 2);
child.setScale(2, 2);
In this code, the child will appear at 4x the size of the container, because it
has been scaled twice itself and also inherits the double scale from its parent.
If you scale any axis of a Game Object to zero, it will be skipped for rendering.
This is because a Game Object with a scale of zero has no dimensions, so it
cannot be seen. Therefore, to optimize the rendering pass, Phaser will skip
those Game Objects entirely.
If you scale a Game Object negatively, an interesting effect happens. The
Game Object will appear flipped. For example:
player.scaleX = -1;
This will render the Game Object as if it was flipped horizontally. This
is handy for characters that need to face in two directions but you only
need to store the textures drawn in one direction, using the negative scale
them to render the opposites at run-time. Note that Phaser also has a ‘Flip
Component’ that can be used to flip a Game Object without adjusting its
scale.
When you scale a texture based Game Object it’s important to understand

457
that the renderer will need to ‘guess’ at any pixels that are now present
because of the increased size of the Game Object. For example, if you have a
16x16 texture and you scale it by 4, it will appear as 64x64 on screen. All of
those extra pixels that didn’t exist before in the original texture are created
by the GPU during the rendering process. A similar thing happens if you
scale a texture down. The GPU has to decide which pixels to not display
and tries to create an average that best represents the orignal image.
Lots of art software, like Photoshop, have the ability to apply special filters
and effects when resizing images to create more refined results. However,
WebGL and Canvas don’t have this feature and they tend to favor speed
over visual fidelity. After all, unlike Photoshop, they have to do this 60
times a second, or more. If you see a drop in visual quality worse than you
were expecting, then you should consider using a smaller, or larger, texture
that was pre-scaled in an art package instead.

Rotation
The current local rotation of a Game Object is stored in its rotation prop-
erty:
const rotation = player.rotation;
The rotation value is always in radians. If you prefer to work with degrees,
you can use the angle property instead:
const angle = player.angle;
To set the rotation, or angle, you can use the chainable setRotation and
setAngle methods:
player.setRotation(rotation);
player.setAngle(angle);
Or, you can set the rotation and angle properties directly:
player.rotation = rotation;
player.angle = angle;
Phaser uses a right-handed coordinate system, where 0 is East, to the right,
and 3.14 (or 180 degrees) is West, to the left. South is 1.57, or 90 degrees
and North is -1.57 (or -90 degrees). If you visualise the rotation as a circle,

458
the bottom half is positive and the top-half is negative. This is the same as
Adobe Flash, from which the first version of Phaser took its inspiration.
Rotation in Phaser always takes place around the origin of the Game Object.
Which means by default Game Objects typically rotate around their center.
As you’ve read, you can adjust the origin. This changes where both the
position and rotation occurs. You cannot change the rotation point of a
Game Object, only its origin.
The rotation of a Game Object is always relative to its parent Container, if
it has one.
For example:
container.setRotation(0.75);
In the code above, the Container is rotated by 0.75 radians, meaning all of
its children will be rotated by the same amount.
container.setRotation(0.75);
child.setRotation(0.75);
In this code, the child will be rotated by 1.5 radians in total, because it
inherits the rotation from its parent, then adds its own.
The rotation property only contains the local rotation value. If you wish
to get the sum rotation of the Game Object taking into account all of its
ancestors, you can use the getParentRotation method:
const rotation = player.getParentRotation();
This will return the total rotation of all parent Containers, in radians. If you
need the world rotation, then add the Game Objects rotation to the final
value:
const rotation = player.getParentRotation() + player.rotation;

Local and World Transforms


The Transform Component has a couple of methods that allow you to return
a Transform Matrix instance that has been set to be either the local or world
transform for the Game Object.

459
A Transform Matrix is a 3x3 identity matrix use for perform affine transfor-
mations. In Phaser, the operations are performed in the order of Translation,
Rotation and then Scale, always in that order.
The method getLocalTransformMatrix will return a purely local Transform
Matrix:
const matrix = player.getLocalTransformMatrix();
This matrix will not include any transforms from parent Containers. It will
only contain the transforms of the Game Object itself.
The method getWorldTransformMatrix will return a Transform Matrix that
contains the Game Objects local transforms, multiplied with those of all of
its parent Containers:
const matrix = player.getWorldTransformMatrix();
Both methods have the option to be passed Transform Matrix instances. If
given, the values will be set in those, instead of a new instance being created
and returned. If you are calling either of these methods a lot, i.e. in a constant
update loop, or en-masse, then you should create some temporary matrices
to pass to them, to avoid the constant creation of new objects:
const tempMatrix = new Phaser.GameObjects.Components.TransformMatrix();

player.getLocalTransformMatrix(tempMatrix);
Or:
const tempMatrix = new Phaser.GameObjects.Components.TransformMatrix();
const tempParentMatrix = new Phaser.GameObjects.Components.TransformMatrix();

player.getWorldTransformMatrix(tempMatrix, tempParentMatrix);

460
Game Objects
Visible Component
The Visible Component is responsible for setting the visible state of a Game
Object.
A Game Object with a visible state of true is rendered to the display, where-
as one with a visible state of false is not. By default, Game Objects have
a visible state of true.
The current local visible state of a Game Object is stored in its visible
boolean property:
const visible = player.visible;
To set the visible state you can use the chainable setVisible method:
player.setVisible(visible);
Or, you can set the visible boolean directly:
player.visible = false;
By default, Game Objects will have a visible state of true. This means they
will be rendered.
Being able to toggle the visibility of a Game Object is very useful for quickly
showing or hiding Game Objects, without impacting their positions or other
properties.
Hidden Game Objects are skipped by the renderer, saving cycle time, but
still retain their internal position and state. This means that you can hide a
Game Object, then make it visible again at a later stage, without having to
reposition it or set other properties again.
An invisible Game Object is still updated, however. For example, if you had
an animated Sprite that was playing through an animation sequence, then
setting it to be invisible would not cause the animation to pause as it would
still be updating. The same goes for other actions, such as tweens, or physics
collisions. The visible state is purely a rendering toggle.

461
Parent Visibility
If a Game Object has a parent Container, then the visible state of the parent
will control if any of its children are rendered, or not. An invisible parent
will skip rendering of all children, regardless of their own visible settings.
However, if the parent is visible, then the childs visibliity will be used instead.

462
11. Cookbook
Sometimes you just need examples of very specific use cases. This chapter
names some common cases and points you to implementations in games listed
at the end.

Same sound with variants


You can play the same sound applying some tweaks through the parameters
of the play function. This way the sound will be more natural.
Examples: Spooky, Marstranded, WallHammer

Actions on animation events


Sometimes you may need to do something in a specific moment of an an-
imation. There are many examples of this at the end of it, especially for
character deaths. But you can also detect a specific frame of an animation
to do something. Check out the avocado foe in the game Flatulent World,
who shoots his own seed.
Examples: Flatulent World

Mouse right and left click


The use of the mouse as input is shown in many games. You may also need
to see how to use the right click (disabling the default behavior) especially
considering that you may run your games on a browser. This is also possible
with PhaserJS.
Examples: Electron (right click), PushPull, StarShipped

Screen Transitions
Transitions from one screen to another are an art inside the art of games.
You should try to pay some attention to this to make your game look more
polished.
Examples: StarShipped, Marstranded, Raistlin

463
Lightning effect
If you need to add the effect of a storm with lightning, you can use this trick
with just rectangles, tweens and some thunder sounds.
Examples: Spooky, Camp Night, Like Tears in the Rain, Fate

Rain, Snow effect


You just need a sprite (or sprites) representing a raindrop or a snowflake and
start a particle emitter. The same can be applied as a trailing effect for any
game object.
Examples: Camp Night, Melt Down, Like Tears in the Rain.

Lights in the dark


Lights are just game objects that you can add to your game with different
radius and luminosity parameters. These lights can be applied on a dark
scene and they add a great effect. They can be randomized and they can
represent torches, shots, explosions, gold, etc. Also, lights can be a key part
of the game, like in terror games.
Examples: Greedy Willie, Johnny Depth, Get Rich or Die Trying, Camp
Night, Shotman, Starshake

Underwater swimming effect


Underwater swimming is really simple, it’s just a continuous jump on a screen
that lacks ground. To make this swimming more “realistic” you can generate
random bubbles and randomized bubble sounds.
Examples: U.F.I.S.H., Johnny Depth, Get Rich or Die Trying

Infinite scrolling background


Find a nice background image or pattern and move it as your character
moves.
Examples: Starshake, Make Way

464
Dynamic map
Instead of creating a predefined map, you can build and render the map as
the player moves. Or you can generate some elements randomly.
Examples: Starshipped, Melt Down, Rise Up

Adding/Removing tiles from a tiled map


On a tiled map, it is possible to add/destroy elements dynamically from the
code.
Examples: WallHammer, Like Tears in the Rain, Shotman

Map building
If tiled maps can be dynamic, you can let the player design his own level
placing/removing tiles.
Example: Platcraft

Composed game objects


Using containers, a player or any other game object can contain more than
one element. In the case of Need4Split, we have separated parts. Examples:
LetterChaos, TruckTrack, Need4Split

Find paths and move foes automatically


If you need foes that chase the player inside a dungeon, a labyrinth or in any
tiled space, you can apply an implementation of the A* algorithm.
Examples: Marstranded, Shotman, Starshipped, PowerGrid

Enemies shooting at player


How can foes shoot directly at the player? It’s easy, the game knows where
the player is. We just need the foe and the player position and create a
fireball moving in that trajectory. This is shown in many games. Examples:
Raistlin2, Starshipped, Atlantis, Starshake

465
Detect screen limit
In some cases, it may be interesting to detect when an object touches the
limit of the screen, so you can destroy that element and free your game of
managing it.
Examples: Starshipped.

Jump simulation on an isometric view


On a 2D platformer, it’s easy to simulate a jump but when the view is not
perpendicular to the ground (like Golden Axe or Double Dragon), you have
to manage the state of the jump. On the screen there is a jump, but basically,
during the jump you have to deactivate some collisions.
Example: Make Way

Parabolic shot
You can throw an element given an angle and speed, to simulate a cannon
or any kind of parabolic shot.
Examples: Chat Gasol, WarChat

Bullet hell
Creating these patterns can be achieved using basic functions or making good
use of Maths! My examples are not the best, but you can start from here.
Examples: Fate, Starshake

Ships in formation
In space shooters, it’s very common to show waves of foes that follow specific
paths. The technique for this is relatively easy, then it’s up to you to create
complex paths.
Examples: Starshake

466
Life bar
These are little bars that appear next to the player or enemies to tell us the
amount of life/energy or whatever they have left. You can change the color
of the bar as it goes down (or up).
Examples: TruckTrack, Melt Down, Marstranded

Typing effect
Showing letters one by one is a typical effect that you can use for game intros,
or to simulate a computer screen. In this examples the typing effect is done
with time-delayed functions.
Examples: Fate, Marstranded, Like Tears in the Rain

Sensors
If you need to trigger some action when a game object touches something you
can use overlaps instead of colliders. You can use this in items that the player
can pick up or use a sensor for some interesting effect: in the Marstranded
game, before you fall into a hole the player touches a sensor around it to play
a sound.
Examples: Marstranded

Adding video
Videos are just other assets of the game, very simple to use. They can be
interesting for presentations, transitions or even story-building.
Example: Fate

Valid Words
If you need a game where you have to deal with valid words, you need func-
tions to validate those words. Apart from a simple list or dictionary, you
could build a Trie to optimize the search. These games are simpler, in some
cases, they can deal with multiple languages. They also give points according
to letter value, as in the Scrabble game.

467
Examples: LetterChaos, Chatle, Chat Defense, Wordinary

Keep a scoreboard
Using Firebase free services you can create a DB and read and save score
data from your game. In these examples the implementation is not very safe
but it’s a starting point.
Examples: MakeWay, Goblin Bakery, Keep Rolling, Lucky Shot

Windows build
Do you want to convert your game into a Windows executable? You can do
it by installing the nw and nwjs-builder libraries and running some specific
build commands.
Examples: TruckTrack

Index of games
This list contains most of the games from my repository mentioned above,
with a link to the source code on github.com and another link to a playable
version on the itch.io site. Sometimes these games belong to a specific genre,
sometimes they are are mix of many things, and sometimes they are just
experiments. In your journey, as you build and play other games you will
probably grab ideas and mix them your way.

Alfabetica
Simple multiplayer Twitch game, similar to Numerica, where we just show a
letter of the alphabet and players must enter the next letter.
Source code: https://github.com/pxai/phasergames/tree/master/alfabetica
Play it here: https://pello.itch.io/alfabetica

Atlantis
A platformer game where the hero must reach the exit carefully because every
block he jumps on falls after a second. In the meantime, the sea level goes
up so time is limited on each stage.

468
Source code: https://github.com/pxai/phasergames/tree/master/atlantis
Play it here: https://pello.itch.io/pocket-atlantis

Ball Breaker
A game where we try to put a bouncing ball in a basket before the ball
destroys de stage borders and dies.
Source code: https://github.com/pxai/phasergames/tree/master/ballbreaker
Play it here: https://pello.itch.io/ballbreaker

BlastEmUp
Proof of concept of multiplayer space shooter using WebSockets built on
socket.io library.
Source code: https://github.com/pxai/phasergames/tree/master/blastemup

BloodHound
A very cheesy Cabal clone, with similar moves and power-ups. I sang the
music myself.
Source code: https://github.com/pxai/phasergames/tree/master/bloodhound
Play it here: https://pello.itch.io/bloodhound

Brick
A variation of Ball Breaker but with clouds instead of bricks, and enemies
flying around.
Source code: https://github.com/pxai/phasergames/tree/master/brick
Play it here: https://pello.itch.io/brick

Brushkkake
A multiplayer Twitch chat game where we present a canvas and players can
paint on it giving coordinates and color.
Source code: https://github.com/pxai/phasergames/tree/master/brushkkake

469
Play it here: https://pello.itch.io/brushkkake

Camp Night
A terror game where you try to find a lost child in a dark forest, with symbolic
sprites and an eerie atmosphere. As you get close to the child, he calls you
louder. A variation of Marstranded.
Source code: https://github.com/pxai/phasergames/tree/master/camping
Play it here: https://pello.itch.io/camp-night

Make Way
Car game, where you have to endure as much as possible, you can jump if
needed and pick missiles to shot at other cars.
Source code: https://github.com/pxai/phasergames/tree/master/cars
Play it here: https://pello.itch.io/make-way

Chancelord
A simple platformer where the player can set custom blocks with different
behaviors to reach the exit.
Source code: https://github.com/pxai/phasergames/tree/master/chancelord
Play it here: https://pello.itch.io/chancelord

Chatdefense
A multiplayer Twitch chat game where we have to defend a castle from
incoming letters. If players create valid words with the incoming letters,
those letters are cleared from the path. The points depend on the letters,
like in Scrabble.
Source code: https://github.com/pxai/phasergames/tree/master/chatdefense
Play it here: https://pello.itch.io/chatdefense

470
Chat Gasol
A multiplayer Twitch chat game where players give angle and speed to try
basket their ball.
Source code: https://github.com/pxai/phasergames/tree/master/chatgasol
Play it here: https://pello.itch.io/chatgasol

Chatle
A variant of Wordle for Twitch chat games.
Source code: https://github.com/pxai/phasergames/tree/master/chatle
Play it here: https://pello.itch.io/chatle

DrillBill
A dungeon crawler where dungeons are blocked by stones and the player must
clear them with a drill to find the exit. Stones have different resistances so
power-ups can be used to drill harder or move faster.
Source code: https://github.com/pxai/phasergames/tree/master/drill
Play it here: https://pello.itch.io/dril-lbill

Dungeon Booble
A roguelike with randomly generated rooms and Matter.js physics that plays
homage to Bubble Bobble.
Source code: https://github.com/pxai/phasergames/tree/master/dungeon
Play it here: https://pello.itch.io/dungeonbobble

Electron
This is an infinite runner where we manipulate an electron and move it ap-
plying attraction and repulsion by right-clicking or left-clicking the mouse on
the screen.
Source code: https://github.com/pxai/phasergames/tree/master/electron

471
Play it here: https://pello.itch.io/electron

Flatulent World
A platformer like Snow Bros or Bubble Booble where we must defeat or push
the enemies with farts! Jumping is also made farting, but we need to get
green or red beans to get better farting powers.
Source code: https://github.com/pxai/phasergames/tree/master/fartworld
Play it here: https://pello.itch.io/flatulent-world

Fate
A 3D bullet hell, explained in the 3D chapter.
Source code: https://github.com/pxai/phasergames/tree/master/fate
Play it here: https://pello.itch.io/fate

Puddle Escape
A simple puzzle game where we need to direct a frog out of a maze putting
lily plants on the water.
Source code: https://github.com/pxai/phasergames/tree/master/froggy
Play it here: https://pello.itch.io/puddle-escape

Goblin Bakery
An infinite runner where a Goblin must step on cakes to make them ready,
avoiding spikes.
Source code: https://github.com/pxai/phasergames/tree/master/goblin
Play it here: https://pello.itch.io/goblin-bakery

Get Rich or Die Trying


An aquatic adventure where a submarine goes down to get gold, but the
more gold it gets the slower it will go while oxygen depletes. Dropping gold
gives an extra boost.

472
Source code: https://github.com/pxai/phasergames/tree/master/goldload
Play it here: https://pello.itch.io/get-rich-or-die-trying

Greedy Willy
A roguelike in a mine where a greedy grandpa miner explodes his way through
using TNT and getting power-ups, while he gets as much gold as he can.
Source code: https://github.com/pxai/phasergames/tree/master/greedy
Play it here: https://pello.itch.io/greedy-willie

Holy Crab
A jumping crab that we move indirectly placing a platform below him. You
have to reach the end of each stage avoiding the seagulls.
Source code: https://github.com/pxai/phasergames/tree/master/holycrab
Play it here: https://pello.itch.io/holy-crab

Johhny Depth
Another submarine adventure where a jelly fish gets jewels while it avoids
volcanos, dangerous fishes and mines.
Source code: https://github.com/pxai/phasergames/tree/master/johnny_depth
Play it here: https://pello.itch.io/johnny-depth

Keep Rolling
A puzzle game where a rolling dice must move over numbered-tiles. The dice
must have a greater or equal number than the tile he wants to move to.
Source code: https://github.com/pxai/phasergames/tree/master/keeprolling
Play it here: https://pello.itch.io/keep-rolling

LetterChaos
Several letters are spawned on screen continuously and the player needs to
create words with them before there are too many.

473
Source code: https://github.com/pxai/phasergames/tree/master/letterchaos
Play it here: https://pello.itch.io/word-chaos

Lucky Shot
A slingshot that needs to hit a bell avoiding elements in the middle like bats,
spikes and spinning platforms. Made with Matter.js physics.
Source code: https://github.com/pxai/phasergames/tree/master/luckyshot
Play it here: https://pello.itch.io/lucky-shot

Marstranded
A story game already covered in its chapter. Inspired by Cold Scream.
Source code: https://github.com/pxai/phasergames/tree/master/mars
Play it here: https://pello.itch.io/marstranded

Metabolik
A circular Tetris-like game where we try to join blocks of the same color to
clear them.
Source code: https://github.com/pxai/phasergames/tree/master/metabolik
Play it here: https://pello.itch.io/metabolik

Moriarty
A game that uses Matter.js physics where we need to direct a guy up and
then down through a pipe full of deadly traps.
Source code: https://github.com/pxai/phasergames/tree/master/moriarty
Play it here: https://pello.itch.io/moriarty

Need 4 Split
A similar game to Geometry Dash where we also get coins. The player block
can be split into different distances to pick more coins or to avoid spikes.

474
Source code: https://github.com/pxai/phasergames/tree/master/need4split
Play it here: https://pello.itch.io/needforsplit

Nightmare
A card game that works like a dungeon crawler based on the Doom game
lore.
Source code: https://github.com/pxai/phasergames/tree/master/nightmare
Play it here: https://pello.itch.io/nightmare

Shogun Killer
A puzzle-like shooter where we need to freeze some ninjas to use them as
bouncing points to hit the Shogun with a shaken.
Source code: https://github.com/pxai/phasergames/tree/master/ninjagolf
Play it here: https://pello.itch.io/shogun-killer

Melt Down
An infinite runner where a penguin must jump up on dynamic blocks to
escape from the growing water level. All blocks are slippery and the penguin
can jump and fly a few flaps to reach higher.
Source code: https://github.com/pxai/phasergames/tree/master/penguin
Play it here: https://pello.itch.io/meltdown

Platcraft
A platformer where before you start the stage you get a budget and it lets
you customize the stage with blocks that have different costs depending on
their value to solve the stage.
Source code: https://github.com/pxai/phasergames/tree/master/platcraft
Play it here: https://pello.itch.io/platcraft

475
Powergrid
A puzzle game where you have to turn on and off switches to create circuits
and turn on all the bulbs of each stage. It uses the A* algorithm to check
that the circuits are correct.
Source code: https://github.com/pxai/phasergames/tree/master/powergrid
Play it here: https://pello.itch.io/power-grid

Spooky
A creepy dungeons-like little horror game where the player must get a key
and reach to door to get to the next room, avoiding ghosts and the devil
itself.
Source code: https://github.com/pxai/phasergames/tree/master/pumpkin
Play it here: https://pello.itch.io/spooky

Push Pull
Puzzle game of blocks similar to Rush Hour, where you need to make a way
out for a little block by moving other blocks.
Source code: https://github.com/pxai/phasergames/tree/master/pushpull
Play it here: https://pello.itch.io/pushpull

Raistlin
A game where a Wizard creates shields (painting with the mouse) to make
the fireballs bounce and send them out of the stage.
Source code: https://github.com/pxai/phasergames/tree/master/raistlin
Play it here: https://pello.itch.io/raistlin

Raistlin2
A platformer where a wizard has to reach the exit by creating platforms
(painting with mouse), creating shields against attacks or even throwing fire-

476
balls to enemies. The player has limited mana so he must choose wisely how
to use it.
Source code: https://github.com/pxai/phasergames/tree/master/raistlin2
Play it here: https://pello.itch.io/raistlin-2

Romanica
Another multiplayer Twitch game, similar to numerica, here with Roman
numerals.
Source code: https://github.com/pxai/phasergames/tree/master/romanica
Play it here: https://pello.itch.io/romanica

Runner
Very minimalistic infinite runner, already covered in the first chapter.
Source code: https://github.com/pxai/phasergames/tree/master/runner
Play it here: https://pello.itch.io/runner

Shotman
A Pacman-like game but with a shotgun. Shots can open ways through the
walls and they will kill ghosts for a few moments. To kill the ghosts for
good, you must shot at TNT barrels whem they are close to them. Shots are
limited in each stage.
Source code: https://github.com/pxai/phasergames/tree/master/shotman
Play it here: https://pello.itch.io/shotman

Slotgeon
Another multiplayer Twitch game. It’s a dungeon crawler where each room
elements are shown as a slot machine result. Players chose the action to do
(fight, run, …). Very experimental, it needs improvement.
Source code: https://github.com/pxai/phasergames/tree/master/slotgeon
Play it here: https://pello.itch.io/slotgeon

477
Sonsofbitches
A variant of Shotman but without walls, so instead of stages you just need
to survive as much as you can.
Source code: https://github.com/pxai/phasergames/tree/master/sonsofbitches
Play it here: https://pello.itch.io/sonsobitches

Squiz
A multiplayer Twitch game that offers a quiz game for chat users. You can
define the number of questions for the round, the topic and then player must
chose the right answer from A, B, C and D. Questions are taken from a
wonderful free API.
Source code: https://github.com/pxai/phasergames/tree/master/squiz
Play it here: https://pello.itch.io/squiz

Starhshake
A space shooter already covered in its chapter
Source code: https://github.com/pxai/phasergames/tree/master/starshake
Play it here: https://pello.itch.io/starshake

Starshipped
A space shooter where the player must fight against another ship. The enemy
ship hunts down the player automatically using the A* algorithm. The stage
is generated on the fly with random asteroids and ammo capsules. The
camera zooms in and if any ship gets out of the bounds of the screen it
gets destroyed. That mechanic and the general idea is based on Alva Majo’s
Shipped game.
Source code: https://github.com/pxai/phasergames/tree/master/starshipped
Play it here: https://pello.itch.io/starshipped

478
Like Tears in the Rain
A platformer where the player can place blocks on the stage just by typing.
The block position will depend on the relative position of the key on your
keyboard, and the blocks will be on the screen for a few seconds.
Source code: https://github.com/pxai/phasergames/tree/master/tears
Play it here: https://pello.itch.io/like-tears-in-the-rain

Tetris
An implementation of the Tetris game, with unit tests.
Source code: https://github.com/pxai/phasergames/tree/master/tetris

Tiny TODO
Source code: https://github.com/pxai/phasergames/tree/master/tiny
Play it here: https://pello.itch.io/tracktruck

TrackTruck
A space truck picks up containers while it prevents asteroids from hitting its
long growing body.
Source code: https://github.com/pxai/phasergames/tree/master/tracktruck
Play it here: https://pello.itch.io/truck-track

U.F.I.S.H.
A UFO falls to the sea and swims its way out while fighting hostile submarines
and fish. It can use a tracking beam to catch coins and shoot them.
Source code: https://github.com/pxai/phasergames/tree/master/ufish
Play it here: https://pello.itch.io/ufish

WallHammer
Platformer already covered in its chapter.

479
Source code: https://github.com/pxai/phasergames/tree/master/wallhammer
Play it here: https://pello.itch.io/wallhammer

WarChat
A Worms-like game for Twitch chats, but with fireball-throwing wizards in-
stead of worms.
Source code: https://github.com/pxai/phasergames/tree/master/warchat
Play it here: https://pello.itch.io/warchat

Weezard
A platformer where a wizard can pick different types of potions with different
effects to clear hist way through a single long stage. One of the potions turns
the screen inside up, Inception style.
Source code: https://github.com/pxai/phasergames/tree/master/weezard
Play it here: https://pello.itch.io/weezard

Wordinary
Another Twitch chat game where a word is shown and players must try to
suggest a word that can be chained to that. The points are given depending
on the words complexity, as in Scrabble.
Source code: https://github.com/pxai/phasergames/tree/master/wordinary
Play it here: https://pello.itch.io/wordinary

Wordle
An implementation of Wordle, but it allows to enter invalid words (which
can be easily changed).
Source code: https://github.com/pxai/phasergames/tree/master/wordle

480
Zenbaki
Yet another multiplayer Twitch game, similar to numerica, here with arith-
metic operations
Source code: https://github.com/pxai/phasergames/tree/master/zenbaki
Play it here: https://pello.itch.io/zenbaki

Zombies
And last but not least, another multiplayer Twitch game where players are
split between humans and zombies. The positions are invisible until some-
body uses a command (like the Marco Polo game) or random lightning hits
the screen. Everybody needs to enter coordinates to move, some to reach
the chopper, others to touch the humans. Touched humans become zombies
and keep playing.
Source code: https://github.com/pxai/phasergames/tree/master/zombies
Play it here: https://pello.itch.io/zombie-night

481
12. Assets
If you are not an artist, or a composer, or a sound designer and you need to
use art assets, you can find a lot of free assets on the internet. You can use
them for free, but you should always check the license of the asset.
Here we will talk about the different types of assets you can use in your
game. Just keep one thing in mind: whatever style you choose, you should
be consistent. This means that if you choose a pixel art style, you should use
pixel art for all the assets and 8-bit styler sounds. If you choose a realistic
style, you should use realistic assets for all the assets, and so on.

12.1 Fonts
Please, don’t use system default fonts in your game. Adding a nice font to
your game is a simple way to make it look way better, and it requires little
effort.
Showing text with Phaser is relatively easy, but if we want to show customized
text, we need to use a custom font. This is a simple process.
Practically you can choose any font you want from sources like:
• dafont.com
• fonts.google.com
• fontsquirrel.com
• 1001fonts.com
Then, you have to turn this font into a bitmap font. This type of font is used
in all the examples of this book. This is a process that is done with a tool
like: https://snowb.org/
You just need to upload the font there and then:
• You can name the font in the tab.
• You change the font color to white, so later you can tint to another
color.
• You can change the size of the font if you want to show it bigger or
smaller without losing quality.
• Finally, you can download it in xml format that Phaser will load per-
fectly.

482
Figure 51: SnowB font editor

12.2 Graphic asssets and Pixel Art


Well, unless you want to develop a text-based game (that is cool too), you
will need some graphics. You have two options, download assets or build
your own art. Or both.

Downloading assets
Not everybody is an artist, and not everybody has the time or skills to create
pixel art or nice SVG graphics. These are some of the best sources to find
free assets:
• Itch.io Apart from hosting games Itch.io is a great place to find all kind
of assets. Many of them are free.
• Kenney Probably one of the most famous asset creators. He has a lot of
free assets and also some paid ones. The only issue is that it’s already
well known, so you will find his assets in many games.
• OpenGameArt Another great place to find assets. You can find a lot
of free assets here.

483
Building your own pixel art
If you want to create your own pixel art, you can use tools like:
• Aseprite (license)
• Piskel (free)
Another option is to create scalar vector graphics instead of Pixel Art. You
can use tools like:
• Inkscape (free)
• Illustrator (license)
If you want to manipulate images, you can use tools like:
• Gimp (free)
• Photoshop (license)

Optimizing your visual assets


You should always optimize your assets. This means that you should try
to make them as small as possible without losing quality. This is important
because the smaller the assets, the faster the game will load. This is especially
important for web games.
Another obvious optimization is to use sprite sheets whenever possible. This
means that you should put all the images in a single file and then use them
as frames of an animation.
On top of that, you should definitely use texture packers. Texture packers
are tools that take all the images and create a single file with all the images.
This is important because on a browser it reduces the number of requests to
the server, and it also reduces the size of the images.
You can download texture packers or just use online tools like:
• Free Text Packer
• Leshy SpriteSheet Tool
Ideally, you should include this packing inside the automated building process
of your game.

484
12.3 Audio assets
You have read this many times, but I must insist: add sounds to your game.
The effort investment/result relation is very high. It’s the most basic form
of feedback and it’s very important for the player to feel the game.
As it happens with graphics, you also can find many audio assets out there.
These are some of the best sources to find free sounds:
• itch.io Itch.io also contains a lot of free sounds and music
• OpenGameArt Also contains a lot of free sounds and music.
• Freesound A great place to find all kind of sounds, not just for games.
• Zapsplat Another great place to find all kind of sounds, not just for
games.
• Youtube Why not? You can find a lot of music here, including 8-bit
versions of any song.

Generating your own sounds


If you want to create your own sounds, you can use tools like:
• https://sfxr.me/ A simple tool to create 8bit-like sounds.

Converting/Editing your audio assets


Probably the best command line tool to convert and transform sounds is
ffmpeg. It’s a very powerful tool that can do a lot of things with sounds.
The most basic one is to change file formats. For example, the command to
convert a file from wav to mp3 would be:
ffmpeg -i input.wav myoutput.mp3

Audacity
How can you edit your sounds or convert them in a more visual way? For
this case I would go for Audacity. You can use it to edit sounds, to convert
them, to add effects, etc.

485
Figure 52: SnowB font editor

486
Optimizing your audio assets
You should optimize your audio assets in the same way you optimize your
visual assets. Obviously, you should use the right format for the right sound.
For example, you should use ogg/mp3 for music and mp3 for sound effects.
As well as you can use texture packers for images, you can also use audio
packers for sounds. This is important because it reduces the number of
requests to the server, and it also reduces the size of the sounds.
You can download audio packers or just use online tools like:
• Audiosprite it is a ffmpeg wrapper that will take a folder of sounds and
create a single file with all the sounds.

12.4 Maps
Maps are assets that define the layout of the levels. Usually, maps are created
with a map editor that build scenes with different tiles, and then they are
loaded into the game. By adding layers to the maps, you can define the
background, the solid parts, the enemies’ position, the items, etc.
Using tiled maps is a great way to create levels, for several reasons:
• It simplifies the process of creating levels.
• It separates the logic from the design. This means that you can create
the levels without having to write code.
• It allows you to program one generic scene and then you can just load
different levels.
• With a simple group of assets and some savoir faire, you can create
a lot of good-looking different levels.

Tiled
You can use Tiled to create your maps. Tiled is a free and open-source
map editor. It supports orthogonal, isometric and hexagonal maps. It also
supports multiple layers, and it can export to JSON, XML, and CSV.
All the games in this book use Tiled to create the maps. You can download
it from: https://www.mapeditor.org/

487
Figure 53: Tiled map editor

Steps to create a map with Tiled The first thing once you open Tiled
is in the menu File > New > New map… There you will choose the type of
map, the size of tiles andsize of the map, the tile size:
Then you add the tileset (New Tileset… in the editor) this is an image that
contains all the tiles you want to use, and obviously the size of each tile must
match the size of the tiles you have chosen before.
Then you can start drawing the map. But be careful. You should go to the
layers section and set proper layers like:
• Scene layer: a layer that contains the solid parts of the map.
• Background layer: a layer that contains the background of the map.
• Object layer: a layer that may contains enemies, items or any other
object that you can place when you load the scene.
Then you can start drawing the map. You can use the tileset that comes
with the examples of this book. You can also create your own tileset.
Ideally, you should name each map and the scene layer with a sequential
name (scene0, scene1,…) so you simplify the loading as the game progresses.

488
Figure 54: Tiled map editor

489
Figure 55: Tiled map editor

Setting custom properties to tiles In some games like WallHammer,


there are bricks that can be destroyed but others are solid. To do this, you
can set custom properties to tiles. You just need to select the tile (or tiles)
and click on the little wrench icon below. You will then see the properties
of the tiles, and there you can add custom properties. As you can see in the
image, the tile has a custom property called element that is set to break.
Anything you add to the properties of the tile will be available when you
load the map in Phaser. In the scene code you can then add the behavior
you want to the tiles.

Setting custom properties to objects On the object layer you can place
anything and then you need to set a name to it. This name will be used to
identify the object when you load the map in Phaser. You can also set the
type property or add custom properties to the objects, and then you can use
these properties in the scene code.

490
That way you could, for example, set an enemy type and also some property
like speed, level, initial direction or whatever you need.

Loading the map The simplest way to work with Phaser is to generate a
JSON file and load it. We will need to load the game as well as the tileset
assets. This is something that is shown in the examples of this several times.

491
13. Build & Delivery
There are several setups available to run and build PhaserJS-based games.
Being a JavaScript framework, most of them are just the same as any other
web project, including tools like Gulp, Webpack, Vite, etc. We can also use
online environments so we don’t need to install anything locally. In this
chapter, we’ll see some of them, starting from the simplest setup.

Static HTML
PhaserJS runs on the browser, so we can just open an HTML file, include
the Phaser library and start coding right there.

index.html
This is how the static HTML file would look like.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="author" content="Pello Xabier Altadill Izura">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Phaser Basic template</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/3.60.0/phaser.min.j
</head>
<body>
<div id="container"></div>
<script src="./GameScene.js"></script>
<script src="./init.js"></script>
</body>
</html>
List: index.html
Once we include the PhaserJS library, we also include our own JavaScript
files. We could directly write JavaScript code in the HTML file, but that
would end up being too messy.

492
init.js
This is the file that creates the game with a basic config.
const config = {
width: 400,
height: 300,
parent: "container",
type: Phaser.CANVAS,
scene: [GameScene]
};

new Phaser.Game(config);
List: init.js
This configuration holds a reference to a game scene that we can put in
another file.

GameScene.js
This is just a simple Game Scene:
class GameScene extends Phaser.Scene {
constructor () {
super({ key: "GameScene"});
}

preload () {
console.log("Preload");
}

create () {
console.log("Create");
}

update (time, delta) {


//console.log("Update", time, delta);
}
}

493
List: GameScene.js

Running it
To Run this, we can just open the HTML file on the browser and reload
on each change. If you use tools like Visual Studio code, you can install
extensions to automate that simple task.

NodeJS + Local phaser library


If you’re familiar with the NodeJS environment, then you should try start-
ing the project with NPM. NodeJS provides a local environment to run
JavaScript code and combined with the npm package manager, we can deal
with project setup and package dependencies.

Setup
With npm, it’s very easy to start a NodeJS project. We just need to run this
inside the project directory:
npm init
That will create the package.json file, that contains the basic configuration
of the project and it will hold the list of dependencies or libraries that we
install using npm itself.
Then we install the phaser package:
npm i --save phaser
This command will download the Phaser library and it will put it inside the
node_modules directory.

index.html
This would be the HTML file, where we will change the reference to the
PhaserJS library. We will use the file inside the local node_modules/phaser
directory.
<!DOCTYPE html>
<html lang="en">
<head>

494
<meta charset="UTF-8">
<meta name="author" content="Pello Xabier Altadill Izura">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Phaser NPM template</title>
</head>
<body>
<div id="container"></div>
<script src="./node_modules/phaser/dist/phaser.js"></script>
<script src="./src/GameScene.js"></script>
<script src="./src/init.js"></script>
</body>
</html>
List: index.html

src/init.js
The init file does not change:
const config = {
width: 400,
height: 300,
parent: "container",
type: Phaser.CANVAS,
scene: [GameScene]
};

new Phaser.Game(config);
List: init.js

src/GameScene.js
Same as before.

NodeJS + Local Phaser with modules


This is just the same setup as before, but it only changes the way we import
the source files.

495
Setup
The setup is the same as before:
npm init
Then we install phaser:
npm i --save phaser

index.html
Now pay attention. This is how we can change the way we refer to source
code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="keywords" content="game, phaser, platform, Pello">
<meta name="description" content="game built with phaser">
<meta name="author" content="Pello Xabier Altadill Izura">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Phaser NPM template</title>
</head>
<body>
<div id="container"></div>
<script src="./node_modules/phaser/dist/phaser.js"></script>
<script src="./src/init.js" type="module"></script>
</body>
</html>
List: index.html

src/init.js
This is how the init looks like in this case:
import GameScene from "./GameScene.js";

const config = {
width: 400,

496
height: 300,
parent: "container",
type: Phaser.CANVAS,
scene: [GameScene]
};

new Phaser.Game(config);
List: init.js
Next is the Scene class, but it will look the same as before.

Gulp
Gulp is a project management tool that lets us run and build web-based
projects: https://gulpjs.com/

Setup
We must install Gulp as part of our NodeJS project
npm init
Then we install the Gulp command globally, which will allow us to run the
gulp command and run gulp scripts:
npm install --global gulp-cli
After that, we need to add the gulp package as a dev dependency. That
means that this will be used just during the development and build process,
but it won’t go into the final build code of our game.
npm install --save-dev gulp
Then we install PhaserJS as before:
npm i --save phaser

gulpfile.js
Now, here comes the gulpfile. It contains a list of tasks that we can chain
to build the game and include the assets (images, sounds, etc) in the build
directory.

497
const { src, dest, watch, pipe, series, parallel, lastRun } = require('gulp');
const del = require('del');
const babel = require('gulp-babel');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const browsersync = require('browser-sync').create();
const open = require('gulp-open');
const browserify = require("browserify");
const source = require("vinyl-source-stream");
const sourcemaps = require('gulp-sourcemaps');
const terser = require('gulp-terser-js');
const buffer = require('vinyl-buffer');

const PHASERLIB = "node_modules/phaser/dist/phaser.min.js";

function clean () {
return del(["dist"]);
}

function html(param) {
return src("./assets/html/*
.html")
.pipe(dest("./dist"))
.pipe(browsersync.stream());
}

function assets () {
return src(["./assets/*

```JavaScript*","!./assets/html/*
.html"])
.pipe(dest("./dist/assets", {force:true}))
.pipe(browsersync.stream());
}

function vendor() {
return src([`${PHASERLIB}`])
.pipe(dest("./dist"))

498
}

function build() {
return browserify({
entries: ["src/init.js"],
debug: true,
})
.transform('babelify', {
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-transform-runtime']
})
.bundle()
.pipe(source('index.min.js'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(terser())
.pipe(sourcemaps.write('.'))
.pipe(dest("dist"))
.pipe(browsersync.stream());
}

function buildProd() {
return browserify({
entries: ["src/init.js"],
debug: false,
})
.transform('babelify', {
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-transform-runtime']
})
.bundle()
.pipe(source('index.min.js'))
.pipe(buffer())
.pipe(terser())
.pipe(dest("dist"));
}

499
function browserSync(done) {
browsersync.init({
server: {
baseDir: "dist"
},
port: 3000
});
done();
}

function watchIt(done) {
watch(["./assets/*

```JavaScript*.*","./src/*

```JavaScript*.js","gulpfile.js"], parallel(html, vendor, assets, build));


done();
}

exports.build = build;
exports.production = series(clean, html, vendor, assets, buildProd);
exports.default = series(clean, parallel(html, vendor, assets, build), parallel(
List: gulpfile.js
With this Gulp file, we can just run the project or create a build. While we
run the project, it will detect any change in source code or the assets and it
will rebuild and reload the game on the browser.

assets/html/index.html
Our index will be placed inside the assets/html directory:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Phaser Game template</title>
<meta name="keywords" content="game, phaser, platform, Pello">

500
<meta name="description" content="game built with phaser">
<meta name="author" content="Pello Xabier Altadill Izura">
<script src="phaser.min.js"></script>
<script src="index.min.js"></script>
<link rel="stylesheet" href="assets/css/styles.css" />
</head>
<body>
</body>
</html>
List: index.html
This will just contain a reference to the init.js file. Gulp will take care of
putting all the code together.

src/init.js
The init just contains references to the scene and that imported code will be
available to it thanks to gulp.
import Game from "./game";

const config = {
type: Phaser.AUTO,
scale: {
mode: Phaser.Scale.FIT,
parent: "phaser-example",
autoCenter: Phaser.Scale.CENTER_BOTH,
width: 800,
height: 600
},
physics: {
default: "arcade",
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: [Game]

501
};

new Phaser.Game(config);
List: init.js

src/game.js
Same as before.

Webpack
Same as Gulp, Webpack is another project management system for building
and running web-based projects.

Setup
npm init
We can install both the Webpack command line interface and Webpack li-
brary as dev dependencies:
npm install webpack webpack-cli --save-dev
Then, we have to install Phaser as we did before.
npm i --save phaser

webpack.common.js
Webpack looks more like a configuration rather than code. It allows us to
group some functions in a file and then add others in other files. This is what
we do here. Some common building operations go to this file:
const webpack = require("webpack");
const path = require("path");
const htmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");

module.exports = {
entry: {

502
bundle: path.join(__dirname, "src/init.js")
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].[chunkhash].js"
},
module: {
rules: [
{
use: "babel-loader",
test: /\.js$/,
exclude: /node_modules/
}
]
},
plugins: [
new htmlWebpackPlugin({
template: "assets/html/index.html",
filename: "index.html"
}),
new CleanWebpackPlugin({options: "dist/*.*"}),
new CopyWebpackPlugin({ patterns: [{ from: './assets', to: './assets' }] }),
],
stats: {
colors: true
}
}
List: webpack.common.js
Now, depending on the type of task we need (dev run or production build),
we add other features in different files.

webpack.dev.js
This is the Webpack configuration for development. It will include the com-
mon part and also it will open a browser to show the project with hot reload-
ing on changes.

503
const { merge } = require('webpack-merge');
const path = require("path");
const common = require('./webpack.common.js');

module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
contentBase: path.join(__dirname, 'dist'),
port: 8080,
open: true,
writeToDisk: true
}
});
List: webpack.dev.js
To run this mode, we just need to run:
npm start

webpack.prod.js
If we want to run a build for production, we use this file. It reuses common
config but instead of opening the browser, it just optimizes the code.
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
mode: 'production',
});
List: webpack.prod.js
To create the build, we run this and it will leave the production build inside
the dist directory.
npm run build
We can zip that directory to publish it on itch.io.

504
assets/html/index.html
The HTML is also located in the assets directory.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Phaser Game template</title>
<meta name="keywords" content="game, phaser, platform, Pello">
<meta name="description" content="game built with phaser">
<meta name="author" content="Pello Xabier Altadill Izura">
<link rel="stylesheet" href="assets/css/styles.css" />
</head>
<body>
</body>
</html>
List: index.html

src/init.js
The source code does not change. Webpack will get this file and include any
other source code referenced here (including PhaserJS itself and the scene
files).
import Phaser from "phaser";
import Game from "./game";

const config = {
type: Phaser.AUTO,
scale: {
mode: Phaser.Scale.FIT,
parent: "phaser-example",
autoCenter: Phaser.Scale.CENTER_BOTH,
width: 800,
height: 600
},
physics: {
default: "arcade",

505
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: [Game]
};

new Phaser.Game(config);
List: init.js

src/game.js
Same as before

Parcel
Parcel is another more modern project management tool that lets us run and
build web-based projects: https://parceljs.org/

Setup
As with the others, we must install Parcel as part of our NodeJS project
npm init
Then we install the Parcel command: it’s just one development dependency:
npm install --save-dev parcel
With that, we are ready to use Parcel in our project. Then we install
PhaserJS as before:
npm i --save phaser

package.json
For Parcel, we can set the whole configuration in the package.json file
{
"name": "phaser_parcel_template",

506
"version": "1.0.0",
"description": "Project template for phaser using parcel",
"main": "index.js",
"scripts": {
"start": "parcel src/index.html -p 8000",
"build": "parcel build src/index.html --out-dir dist",
"test": "echo \"Error: no test specified\" && exit 1"
},
"parcelCleanPaths": [
"dist"
],
"staticFiles": {
"staticPath": "assets",
"watcherGlob": "**"
},
"devDependencies": {
"@babel/core": "^7.10.5",
"@babel/plugin-proposal-class-properties": "^7.10.4",
"babel-eslint": "^10.1.0",
"eslint": "^6.8.0",
"minimist": ">=1.2.2",
"parcel-plugin-clean-easy": "^1.0.2",
"parcel-plugin-static-files-copy": "^2.4.3"
},
"author": "Pello Xabier Altadill Izura",
"license": "ISC",
"dependencies": {
"phaser": "^3.60.0"
}
}
List: package.json
Parcel will take care of the rest automatically.

jsconfig.json
This is a config file that we need for this project.

507
{
"compilerOptions": {
"target": "es6",
"moduleResolution": "node",
"checkJs": true,
"esModuleInterop": true
}
}
List: jsconfig.json

assets/html/index.html
Our index will be placed inside the assets/html directory:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Phaser Game template</title>
<meta name="keywords" content="game, phaser, platform, Pello">
<meta name="description" content="game built with phaser">
<meta name="author" content="Pello Xabier Altadill Izura">
<link rel="stylesheet" href="css/styles.css" />
</head>
<body>
</body>
</html>
List: index.html
The rest will remain the same.

Vite
Vite is another project management, well-known for its speed https://vitejs.dev/

Setup
We must install Vite as part of our NodeJS project

508
npm init
And then we just install Vite as a dev dependency:
npm install --save-dev vite
In the case of Vite, it has its way of creating projects. You can check them
out on Vite’s website.
Then we install PhaserJS as before:
npm i --save phaser

vite.config.js
This is the basic Vite config file that we use for this project.
import { defineConfig } from 'vite'

export default defineConfig({


plugins: [],
server: { host: '0.0.0.0', port: 8000 },
clearScreen: false,
build: {
assetsDir: 'assets',
},
})
List: vite.config.js
Just with those few lines, we get the same result that we got with many lines
of gulpfile.js.

assets/html/index.html
Our index will be placed inside the assets/html directory:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Phaser Game template</title>
<meta name="keywords" content="game, phaser, platform, Pello">

509
<meta name="description" content="game built with phaser">
<meta name="author" content="Pello Xabier Altadill Izura">
<link rel="stylesheet" href="assets/css/styles.css" />
</head>
<body>
</body>
</html>
List: index.html
The rest of them will work the same way.

Online: phasereditor2d
Another way to run and build PhaserJS-based games is by using online en-
vironments. This one was created specifically for PhaserJS.
https://www.phasereditor2d.com/

Online: repl.it
Replit is a great site where we can run almost any kind of project. Web-based
projects are no exception, so it’s pretty easy to have an environment ready
to run Phaser games.
You can use this one as an example.
https://replit.com/@pello/Phaserjs-3-template?v=1
The Replit community is huge and you may find many other templates by
others. Anyway, it’s relatively easy to create your own.

Online: codesandbox
Codesandbox is another powerful environment. It’s almost like owning a
development laptop on your browser.
As it happens with Replit, Codesandbox is full of templates built by the
community. This is one example using vite:
https://codesandbox.io/p/sandbox/phaser-js-3-vite-template-ntz4xr

510
Converting to Windows app
It is possible to turn our PhaserJS game into a Windows executable. We just
need to install some dependencies:
npm i --save-dev nw nwjs-builder nwjs-builder-phoenix
We will also need to add some config in package.json. Check out the Truck-
Track project as an example.

Automating itch.io upload


Another interesting tool for fast publishing and updating our game in itch.io
is Butler. https://itch.io/docs/butler/
This is a command line tool that will allow us to automatically update the
published game.
So once installed, we can just build and upload the game from the command
line:
cd dist && rm -f assets/html/index.html
&& butler push . pello/zenbaki:html --userversion 0.0.1
&& cd .. && butler status pello/zenbaki:html

Netlify publish
https://netlify.com
Another simple and fast option to publish our game is using a service like
Netlify. The most convenient is first managing our code in a repository like
GitHub.
Every time we push changes, we can fire an update in Netlify and run a build.
Then we can just tell Netlify to publish the build directory.
import Phaser from "phaser";
import Game from "./game";
import GameOver from "./gameover";
This is the main configuration file for the game.

511
const config = {
width: 600,
height: 300,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH,
},
autoRound: false,
parent: "contenedor",
physics: {
default: "arcade",
arcade: {
gravity: { y: 350 },
debug: true,
},
},
scene: [Game, GameOver],
};

const game = new Phaser.Game(config);


List: init.js

512
14. Juice
Juice is all the polishing work that you do to make your game look and feel
nice. Juice does not add anything to the mechanics or the core of the game,
it’s all about the presentation and the feedback of the game in all aspects:
graphics, sound, music, transitions, and general effects.
The most basic juice is the feedback that you get when you press a button.
If you press a button and nothing happens, you don’t get any feedback. But
if you press a button and you get a sound, a visual effect, a vibration, etc.
you get feedback and you feel that you are doing something. And that’s the
most basic juice. But there are many other things that you can add that will
turn feedback into dopamine shots.
The possibilities are endless and you can add as much juice as you want. But
you should be careful because too much juice can be overwhelming and it
can make the game feel slow. So you should add juice to the point where
it feels nice but not too much. When it’s too much? It can be a matter of
personal taste, but as long as it does not interfere with the gameplay and
allows you to know what is going on, it’s fine to add as much as possible.

Ideas
So… what kind of feedback can you add to your game? Well, there are many
things that you can add. Let’s see some of them.

Sound effects
Sound effects have the best cost/benefit ratio. They are easy to add and
they can make a huge difference. Sounds are a great way to give feedback to
the player and they should be almost mandatory in any game, and the bare
minimum that you should add to your game.
You can add sound effects to almost everything: when you press a button,
when you move, when you jump, shoot, hit an enemy, die, win, lose, get a
power-up, get a coin, get a bonus, get a new weapon, get a new level, new
life, get a new enemy, get a new boss, when you get a new world or when
you get a new anything!

513
Visual feedback
The cheapest way to add visual effects is tweens and we have seen a great deal
of them in the examples. You can tween positions to simulate shakes, you
can tween alpha to simulate flashes,… You can tween scale up/down an object
to make it funnier. Also, you should add ease properties to your tweens for
better effects.
Blinking is another great effect that you can add to any object. You can
make it blink when it’s hit, when it’s destroyed, when it’s picked up, etc.
Sometimes, a blinking player means that it is invulnerable.
Trailing is quite easy to add to any moving object of the game. You can add
a particle generator or just create simple sprites or squares in the position
of the object and make them fade out. This will give the impression of
movement and speed.
When a character jumps you can add some smoke on the ground and the
same on landing. The smoke can be just squares or circles with a fading
alpha, or sprites with a simple animation.
When something shoots, you can add a shooting explosion, an animated or
tweened bullet with a trail, an explosion when the bullet hits something, etc.
Whenever you pick something up you can add an effect (along with a sound).
Also, if it’s something that alters a player’s life, score or coin count, there
you can add an extra effect.
Points! When you kill an enemy or you get a coin, you can add a points
counter that goes up and vanishes. That will give you a nice feedback of
what you are doing. Points can also move from the player to the scoreboard
to visualize how they are added.

Move feedback
This refers to effects that you can add to elements for more realistic and
satisfying feedback. If you hit or get hit, you can move the character a bit
in the opposite direction. When you shoot a big weapon you can add some
recoil to the player or ship. Also, when you shoot something big you can
shake before you do it.

514
Furthermore, you can alter the physics so an overlap can be a soft collide
and create objects that feel more resistant.

Light
Even in simple 2D games, you can add great light effects. It can add a nice
effect on shots, explosions, deaths, etc. Also, in any game where you want to
add some atmosphere, you can add a light source and make it flicker, change
color, change intensity, change position, etc. In some cases, it can even be
part of the mechanics of the game itself.

Screen effects
You can also make good use of the whole screen for feedback. The most
common screen effect is the shake. You can shake the screen when you get
hit or when you destroy a lot of enemies in one go. Shaking the screen is just
one line of code and the effect is great and recognizable by all players.
Shining and blinking is another common effect. You can make the screen
shine when you get a power-up or when you get a new weapon. It can be
also a lightning effect to simulate storms. But use it carefully or show a
warning because it can be annoying or damaging for sensible audiences.
Not all games must show a clear conventional view of the game. You can
give some retro style by adding tv-like lines, a combed effect, a pixelated
effect, a sepia effect, a black and white effect, or a negative effect. There’s
even a genre of games that exploits the “found footage” concept where you
show scenes as if they were video recordings.

References
I recommend you to watch the following videos about juice. The first one is
great, it shows you how to add juice to a game like Arkanoid or Breakout.
The game looks very simple and dull, and as they move forward adding juice,
the game becomes more and more fun. The second one is a talk about the
juice in general and it’s also very interesting.
Juice it or lose it - a talk by Martin Jonasson & Petri Purho:
https://www.youtube.com/watch?v=Fy0aCDmgnxg

515
How Game Juice Made My Game Come to Life: https://www.youtube.com/watch?v=OsFc1f5ghRU
Screen shake: https://www.youtube.com/watch?v=AJdEqssNZ-U

516
15. Jams
Game Jams are game development competitions where you have to build
a game in a limited amount of time. The time can range from hours to
months, and normally there’s a theme and/or limitation that you have to
follow. Once the game is completed, people can play and rate the games in
different categories: fun, graphics, sound, etc.
In these jams they normally let you use any tool you want, but some jams
are more restrictive and force you to use a specific tool or framework. They
also let you develop your project with other people or do it solo. Anyway…
why should you care?

Why you should participate in a jam


The best way to learn is by doing. This is a great truth also in programming.
And the best way to learn game development is by building games. So, if
you want to learn game development, you should build games. And that’s
what jams are good for.
Game Jams add an extra layer of difficulty to the game development process.
You have to build a game in a limited amount of time, so you have to focus
on the core of the game and leave the rest aside. You have to be creative and
find solutions to problems that you wouldn’t have in a normal development
process. As you are running against the clock, you’ll spend a few days (or
hours) in a very intense and focused process. And at the end, you’ll have
a completed game. Maybe it’s not perfect, maybe it does not have all the
features that you dreamed of, but it’s a completed project. And that’s a
great feeling. Would you be able to finish a game if you didn’t have time
constraints? How many side-projects have you abandoned?
As you take part in different jams, you will learn new techniques and you’ll
improve your skills: you will add what you learn from previous jams and you
will avoid the mistakes you made. Besides, you will have to take care of all
the aspects of building a game, not just graphics, art or programming, but
also logos, game page design, demo videos, etc.
Winning? Forget about it. It’s really hard to get everything right: the theme,
the idea, the execution, the art, the music, the sound, the gameplay, the fun,

517
the polish… Don’t worry about being the winner. Quite often what you think
is a great idea won’t be understood or considered fun by others. But also,
ideas that you may consider simple or even stupid may have great success.
In the end, what matters is what you learn by taking part in several jams.
And by the way, you’ll be building a portfolio of games that you can show
to others.

Feedback
Trying other games in jams is not just polite, it’s necessary to improve your-
self. You’ll have to review other projects and believe me, you will learn a
lot in that process: discovering ideas, art, effects, transitions, etc. that you
didn’t know before. And you’ll also learn what not to do. You’ll see many
games that are not fun, that have a bad design, that are not polished. And
you’ll learn from that too.
Besides, in a Jam you can present your idea and see if it’s good or not. You
can ask other people to play it and see what they think. Depending on the
reviews you can decide to continue with the project or not. And if you decide
to continue, you’ll have a lot of feedback to improve it. Worst case scenario,
you’ll have a prototype that you can use in the future but you won’t waste
more time on it.

The game idea


Believe me, developing a good idea is as hard as building the game itself.
First, it must be something that fits the limitation. Second, it must be fun,
and ideally, it must be something new. And there are so many games out
there that it’s becoming harder and harder to bring something different to
the table.
It is often said that you should automatically discard your first idea because
probably it’s the most obvious one. An indirect approach or twisting an
apparently unrelated concept may turn into something original and it will
be highly appreciated.
But whatever it is, it must be something that you can quickly generate a
prototype of. That will give you the assurance that the idea may work well.

518
You should definitely not get into something too complicated, especially for
weekend jams.

519
Jam Types
Nowadays there are many jams, but the most popular are the online ones.
They are normally hosted on a website like www.itch.io or www.gamejolt.com.
Next, we’ll see some of the most popular jams. And you should consider
participating in one of them. It’s a great way to learn and meet people.

Little short jams


There are several types of jams, but the most common are the short ones.
They are normally online and last from 48 to 72 hours.

TriJam
https://trijam.itch.io/
Trijam is the three-hour game jam that takes place every weekend. The jam
is not very restrictive with the time and it has a weekend schedule from
Friday afternoon to Sunday afternoon. The theme/limitation is announced
on Friday and you have to submit your game before Sunday evening. So in
theory you have to build something in three hours.
It takes place in itch.io and it comes with an extra. Every Wednesday, before
the winner is announced you can join a Twitch stream to see some of the
games and even ask for yours to be tested. The streamers are patient and
nice, and they will play your game if you ask them to.
Games developed for Trijam are not super polished but it’s a good chance
to build a quick prototype and test an idea.

Minijam
https://minijamofficial.com/
Minijam is a 72-hour game jam that takes place every two weeks on itch.io.
The limitation is announced on Friday and you have to submit your game
before Sunday midnight. Apart from the limitation, every Minijam has a
theme that you can follow or not because it is just for inspiration.
Minijam is quite popular and it’s a perfect jam to build something playable
and nice looking. Sometimes the limitations are really hard but it’s amazing

520
Figure 56: Trijam logo

521
Figure 57: Minijam logos

522
to see the ideas that people come up with. If you can implement a good
idea and you have enough time to polish it, you can get a very nice game.
Compared to Trijam, the games are more polished and complete and you can
go deeper.

Big Jams
Big jams are longer and they have massive participation. They are normally
online and last from one week to one month. Again, you should not aim to
win, but to be part of them, to build something and to learn from others.
Here are some of them:

Ludum Dare
https://ludumdare.com/

Figure 58: Ludum Dare site

Ludum Dare is one of the oldest and most popular jams. It takes place twice
a year: the Compo and the Jam. The Compo is the solo modality and you
have to build everything from scratch. The Jam is the team modality and
you can use any asset that you want. The theme is announced on Friday and
you have to submit your game before Monday midnight.
Ludum Dare is a massive jam with thousands of participants. It’s a great
chance to build a game and get feedback from other developers. The games
are normally quite polished and complete. Some of the games developed for
this jam are quite popular and have been published on Steam.

GMTK Jam
https://gmtk.itch.io/

523
Figure 59: GMTK logo

This is not as old as Ludum Dare but it is one of the biggest on itch.io. It
is held once per year and participants must complete a game in 48 hours.
The theme is announced on Friday and you have to submit your game before
Sunday midnight.
It’s organized by the Game Maker’s Toolkit YouTube channel and being so
popular and massive it’s a good chance to get a lot of feedback and learn
from others.

Technical jams
Apart from the previous jams, some jams are more focused on the technical
side of game development. These jams can be interesting if you want to learn
a new framework or tool, or if you want to improve your skills in a specific
area.
The best place to find these jams is itch.io: https://itch.io/jams. You can
search for jams and filter them by type.
You can also search for jams on other sites like www.gamejolt.com or even
on Google.

524
Frameworks
General Jams are not restrictive about the tools you use. However, some of
them are focused on a specific framework or tool. For example, there are
jams for Unity, Unreal, Godot, Pico8, and even PyGame.
From Pico8 jams you can learn a lot about pixel art, how to optimize your
code and assets and a lot of juicy pixel art tricks. Check them out!

Art jams
There is a whole branch of jams focused on art. In these jams you don’t have
to build a game but just create art. It can be pixel art, or 3D art, or music,
or sound effects, or anything related to art.

Juicy jams
Oh my! Juicy jams are the best! They are focused on the juice of the game.
Even if you don’t take part in them you should check the entries: it’s a great
way to learn how to make your games look and feel nice.

Rule of thumb
Probably the most important rule of thumb when you build a game for a
Jam is to keep it simple. You have a limited amount of time, so you have to
focus on the core of the game and leave the rest aside. Don’t try to add too
many features, don’t try to make it perfect, and don’t try to make it too big.
Just focus on the core and make it as fun and polished as possible. We’ll
cover this in more detail in the next chapter.

525
16. 4:44 Rule
This rule is especially good for solo developers, who must try to maximize
the effort to create a good game. Many casual and simple games are based
on a simple mechanic, so once you have that working it’s time to put all your
efforts into making it look and feel good. That is what the 4:44 rule is all
about.
The name of 4:44 rule comes from the supposition that you have 48 hours to
make a game. And 4:44 means 4 hours and 44 hours. So you have 4 hours to
make a game and 44 hours to polish it. And that’s the rule that you should
keep in mind.

How is it applied?
The first 4 hours
Even if you had 48 hours to make a game, if you follow this rule you should
be able to make your game in 4 hours! So, how is it possible? Well, the idea
is that you should focus on the core of the game and leave the rest aside.
You should focus on the core mechanic and make it as fun and polished as
possible later. And that’s what you should do in the first 4 hours. At the end
of those 4 hours, you need to figure out whether it’s good or whether you’re
happy with it. Ask yourself, is really it a good game? Is it worth spending
more time on it? If the answer is no, then you should stop and start a new
game.
If the answer is yes, then you should keep going and spend the rest of the time
polishing it. How do you really know if what you have is good? Probably if
you feel it’s good, it’s good. But you can also ask other people to play it and
see what they think. If they like it, then it’s good. If they don’t like it, or
they don’t understand it easily, then it’s not good. But you should be able
to tell if it’s good or not. If you are not sure, probably it’s not good enough.
You could also start asking yourself and compare with other ideas: What is
the interesting thing? What’s the thing that made you continue the game?
This is good, is it the movement? Is it the jump? Is the interaction? Is it a
new type of mechanic? Is it something you’ve never seen before?
A good idea and design isn’t when you can’t add things anymore. A good

526
design is when you can’t take anything away anymore without breaking the
idea. Also, adding more stuff to a game doesn’t make it better. It’s the other
way around! We’ll go deeper into design in the next chapter.
Once you decide to go on, it is important that you just DON’T ADD
anything new, any feature, any mechanic,… just don’t introduce new stuff.
Commit to the idea and move forward to the next step.

The next 44 hours


So you already have a good idea in a working game but it doesn’t look and
feel nice. No worries, because now you have 44 hours ahead of polishing,
polishing and re-polishing. And believe me, it feels super good to see a game
that you like and that you can polish. It’s like a diamond that you can polish
and make it shine.
Polish makes:
• Make it look better.
• Make it sound nice.
• Feel nicer when you play it.
In other words: improve the game feel and MAKE IT JUICY!!
The good news is that you can rely on a multidisciplinary team to help you
with the polishing. You can ask for help to a designer, an artist, a musician,
a sound designer, etc. And you can also ask for help from other developers.
But you should be able to do it yourself. And that’s why you should keep it
simple. Even if you don’t have people helping you, you can probably use all
types of assets from the internet.
You should be at a point where adding things to your game is just to make
it better, without changing the core. But remember that you should not add
new features. You should not add new mechanics, levels, enemies or new
weapons. You should not add anything new. You should just add polishing
stuff.
There are several elements that you can add to your game to make it more
complete as a product:
• A set of characters, a story, a little universe.
• A nice splash.

527
• Settings or menu screen.
• Scoreboards.
• Tutorial screen.
But never work on them unless you already have a good idea ready. When
you are constrained by time, these secondary items should go to a nice-to-
have list of things.

Just for jams?


Where do you apply the 4:44 rule? In Game jams obviously. Obviously, it is
also a good rule to follow when you are building a game as a solo developer,
as you don’t have the resources to build a full game. But it’s also a good
rule to follow when you are building a game with a team. Meaning that
a game should have a core mechanic that is fun and that you can build a
game around it. And that’s what you should focus on. Think of a classic
like SuperMario. The mechanic is that you run and jump. That’s it. But
with those mechanics, you move forward, you jump over enemies, you jump
over holes, you jump over blocks, etc… The rest is a world built around that
mechanic. And that’s what you should do. Build a game around a core
mechanic. Because that is one of the main rules that we will cover next:
good level design.

528
17 Level design
Well, this book just pretends to introduce game development using Phaser,
but I would like to add something about design. I don’t pretend to say
anything revolutionary just some principles that are well-known and you
should take into account when you develop a game. You may be proficient
in programming and putting together assets and code, but there are other
important aspects to take into account. Ok, let’s say that you are perfectly
able to load a scene with a platform using Phaser and tiled maps. But… can
you create a level that is actually right? The next ideas explain what is right
and what is not.
Level design is a huge topic and there are many books and resources about
it. But it is not easy to just choose one because this is not exactly a science.
This humble book is intended to be a mere introduction to a framework and
game building in general. So I can’t and I won’t go deep into level design.
However, I’ll try to summarize the key points in this chapter that I think
you could consider even if you are building your little games.

Some tips
Most of this tips are taken from GDC. I don’t like to call them rules, but
tips. Most of them are common sense, some of them seem to overlap and
some of them should not be applied in specific genres… but it’s always good
to keep them in mind.

Levels should look good


Without being an expert in art or design, let me say that you should try to
make your levels look good. Yeah right, but how? Well, that’s not just about
the art, it’s also about the layout, the colors, the transitions, the effects, the
music, the sound, etc. Everything should be in HARMONY and should be
appealing to the player. And that’s not easy. But you should try to make it
look good.
If you suck at art and mixing, just try not to mix styles. Don’t put a realistic
player in a pixel art world or vice versa. Don’t use default fonts. Don’t mix
colors that don’t match. Don’t add music that sounds out of place. Don’t
mix realistic sound effects with chiptune effects.

529
• Use assets from somebody else and try to get the whole bundle of assets
so all elements share the same style.
• Create or use a color palette. You can try to base it on your assets.
• Use a font that matches the style of the game, there are infinite ones
on sites like dafont.com.
• Use music that matches the style of the game. You can find free music
on sites like freemusicarchive.org.
• Create or use sounds that match the style of the game. You can find
free sounds on sites like freesound.org or create them with generators
like sfxr.me.
Pico8 games look great because they are constrained to a limited palette of
colors a limited resolution, and sound effects. But they are also great because
they are consistent. Everything looks like it belongs to the same world.

Modular levels
This is another basic tip, that should be applied to any game. Building
games is a hard task to do. Building levels is even harder. So you should
try to make your levels modular. That means that you should be able to
reuse elements of the levels in other levels, and also combine them to create
new elements in your game. Even the simplest level building tools like tiled
allow to reuse of elements. It’s part of the tile artists to create a set of
assets that can be combined in different ways to create different elements.
In platform games, tiles can be like our Lego pieces. Also if we can add
some variations to these elements (like color to simulate dark ambiance or
underwater stages), the efficiency will be even higher. Variation it’s also
necessary to avoid repetition and make every new level look different. But
not too different, as we need to keep the harmony of the game and the certain
familiarity of the player; like blocks that are unbreakable and other elements
that are breakable.
You can even make the level reusable by making the player go through it
several times (as you would do in a racing game) or making him go back and
forth (as you would do in climbing a mountain and going back down).

530
Fun above all
Wow! Captain Obvious to the rescue! Well, this is what games are all about
right? But who decides what is fun? Well this could be a very subjective
topic.
There are some things that you can do to make your levels fun, but… there
are some pitfalls that you should avoid that anybody could agree on.
The first thing that you should do is to make your levels playable. Unless
you want to create an ultrahard game for hardcore players, you should make
your levels beatable, ideally in different levels. That means that you should
be able to complete them. If you can’t complete your own levels, then you
are doing it wrong. You should be able to complete them without dying, or
at least you should be able to complete them. If you can’t, then you should
make them easier. You can make them harder later, but you should be able
to complete them.
You can also let the player learn that by using certain skills he can reach or
get special places and rewards. So you don’t just create an intuitive level,
but also a chance to explore different ways to complete it and try it again to
get more rewards. That’s good replayability!
There is something deeper than simple fun that is harder to get right: game
feel. As happens with any feeling, it’s hard to give a definition, but it could
be how good the interactive experience is for the player’s senses: audio and
visual experience and more specifically control response. This is a topic that
anybody interested in being a good game developer should invest some time
in. There are specific books about this but you can read a nice introduction
to this topic in this document: https://puccjogos.github.io/balanceamento-
2017-1s/materiais/GameFeel_Chap1.pdf

Don’t make them too opened


This is probably the most common mistake in a level design, especially in
platformers. When you show the layout of a level to a player, it should be
obvious the way he must follow. If you show a level with many paths, the
player will get lost and he will probably get frustrated. If you don’t add
certain boundaries the player may end up in a place where there’s no way
out or it’s just a dead-end. If you make the player go back and forth too

531
many times, he will get bored. Walking your way back is not fun.
What about open worlds? Well, open worlds are not exactly open. They
are just big and they give you the impression that you can go anywhere.
But in fact, you can’t. You can only go where the designer wants you to
go. And that’s the key. You should give the player the impression that he
can go anywhere, but you should guide him to where you want him to go.
Even open worlds have special places that you can only access when you have
certain skills or items. And that’s the way to go.
Another key point is to make your levels clear. Players should be able to
recognize immediately what to do or where to go. Somehow you have to
guide the player through the level but keeping the illusion that he is free
to go anywhere. For example, you can disable going back. You can disable
some paths until some condition is true.

Levels designed for the mechanics


This was the conclusion of 4:44 rule chapter. This should be obvious too,
and as crucial as fun. Games, normally, offer the player some mechanics to
play with, so your levels should be built in a way that you can apply the
mechanics of your game. So if your game is about jumping, you should build
levels where you can jump. If your game is about shooting, you should build
levels where you can shoot. If your game is about going fast, don’t slow the
player down.
You can get creative and add levels where the player has to use the same
mechanics to achieve a different effect. But your levels have to require the
player to use the mechanics of the game. Otherwise, you are not building
a game, you are building a movie where the player just walks through and
watches.

Show don’t tell


One of the first rules in literature is “Show, don’t Tell”. It means that instead
of using words to describe something, you should show it. And that’s the
same in level design. You should not use words to tell the player what to do,
you should show it and make it obvious.
The first place where you should apply this rule is in the tutorial. You should

532
not explain the player what to do, you should show it using a really simple
and straightforward level. The player should be able to play the tutorial
without reading anything. If the first thing that you do in your game is to
show a wall of text, you are, again, doing it wrong.
It’s not easy to give instructions without words, but you can use the layout
of the level to guide the player. You can use blinking arrows, signs, color
patterns, or anything that makes it obvious like carrot and stick motivation:
showing prizes or dangers to guide the player.
You can also build the story by just showing elements in the environment in
the game. This is also used in movies, where you can show a clock, a sunset,
a newspaper or other less obvious clues.
But don’t get it wrong. There are genres, games and situations where text
is part of the game if needed, like in RPGs, adventure games, or puzzle
games. You may use an introduction, as sometimes they do in movies, to set
the scene. But even in those cases, you should try to make it as simple as
possible.

Tell What but not How


This is similar to the previous tips or it is a consequence of them. Any
game should have an objective. Even a sandbox-like open-world game like
Minecraft can be played with a final objective. So players should know what
the objective of the stage or level is, but you should never tell them how
to do it. On top of that, players should have different choices to complete
the level. They should be able to choose different paths, different weapons,
different skills, different strategies, etc.
Players can get also creative and use the elements of the game in a way that it
was not designed. Instead of punishing the player for “cheating” that should
be rewarded. A classic example was in Golden Axe, where you could hit
enemies close to the cliffs and they would fall. Maybe that wasn’t the way
the game was designed, but it was fun to clear the path of annoying thralls.
Your game can also offer secondary missions or objectives that can lead to
power-ups or make completion easier. But you should never force the player
to complete them. They should be optional. Once again you give some free
will in a constrained environment.

533
Figure 60: Golden Axe cliff trick

534

You might also like