Author Archives: admin

Pixel Memory Trailer & Updates

This is an announcement post concerning the puzzle game “Pixel Memory” (Phaser 3):

  1. YouTube Trailer
  2. Game Update: Bonus Guesses

1. Pixel Memory Trailer

We now have a little trailer for Pixel Memory on YouTube!

I’ve tried to keep the trailer as short as possible and make it highlight the most important features:

  • Classic Puzzle Game
  • Unlockable Cards
  • Profile Levels
  • Player Stats

2. Pixel Memory Update: Bonus Guesses

After the amazing suggestion on Twitter from @photonstorm I’ve added a new feature to the game: Bonus Guesses!

And this is exactly how it works: If you manage to find a matching pair on the cards’ very first flip, you receive +3 Bonus Guesses!

I think this will definitely help on the harder difficulty levels.

Click Here to Play: Pixel Memory

My first Phaser 3 Game!

First Phaser 3 Game – Lessons & Code Pt. 3

This dev blog posts series is about my first Phaser 3 game “Pixel Memory“.

The previous posts in the series can be found here:
First Phaser 3 Game – Lessons & Code Pt. 1
First Phaser 3 Game – Lessons & Code Pt. 2

Phaser 3 was officially released today
and is thus out of beta! Please keep in mind that my first Phaser 3 game was built with Phaser 3 Beta 20 and thus some of the things I’ve mentioned in this series might have been fixed or changed by now. I did however try to cover mostly things that should stay true even after the release.

Overview

  1. No Tweens in Preload
  2. Graphics’ Object Peculiarities
  3. Re-Starting the Same Scene
  4. Playing Sound

1. No Tweens in Preload

This first paragraph is more of a discovery than lesson. I wanted to create a custom loading animation for Pixel Memory that doesn’t use the standard loading bar filling from left to right.

I wanted to have cards slowly flipping over while the game is loading. The tweens were working fine but unfortunately not while the assets where loading. The reason for this is that no tween will ever be run before the scene has completed the preload method.

The thing is that all assets are being loaded in the scene’s preload method, which is before the scene’s create method. So by the time the scene reaches the create method, it is already too late and the whole loading animation is pointless.

Even if I created the tweens in the preload method, they would not be triggered until the scene reached the create method. Manually forcing the tween to start in the preload method didn’t work either.

So I was wondering, how come the preload bar can change the width during the preload method? That’s because it is not a tween! In fact, the preload bar image changes width on every load callback – which triggers every time a file (image, audio, font, etc.) is loaded into your Phaser game.

this.load.on('progress', function(value)
{
	txt_percent.text	= Math.round(value * 100) + ' %';
});

So what that means is that you can create a custom loading animation, as long as you can make it work with this progress callback function above. The value argument is a float between 0 and 1. If you multiply it by 100 it represents how many percent of the game assets have been loaded so far.

So if you can think of a different animation that you can base off the value argument, then it will work. Like the preload bar, it only needs the value argument to change its displayWidth property. Tweens however will not work; they will start only after everything has been loaded already.

Back to overview

2. Graphic Objects’ Peculiarities

I was so used to working with the Phaser 2 Graphics Object that I ran into some surprising differences in Phaser 3.

Graphic X,Y-Coordinates

Let’s start by creating a graphics object. Most of my graphics objects are backgrounds for UI or similar things. I made the habit to create the graphics objects at its x, y position, and not at 0, 0 like so many examples show.

Here’s why: If you create the graphic at 0,0 and draw the object later at x,y then the position of that object will actually be at 0,0. If you want to write text inside this graphics object and base the text’s position off the graphic’s position, it won’t work if it’s set to 0,0 – that’s the same as the origin of the whole canvas.

When you create a graphics object in Phaser 3, you cannot pass the x,y values as separate arguments anymore. You have to pass an object now with the x and y properties.

If you create your graphics objects like this, then the x and y properties will correspond to where you’ve actually drawn it:

// We want our rectangle to be at 25, 100.
var x  = 25;
var y  = 100;
var bg = this.add.graphics({ x: x, y: y });

// We make it solid black
bg.beginFill(0x000000, 1);

// When you draw the rectangle, you have to start drawing at 0,0 now because
// this position is relative to what you have set in the create method above
var width  = 350;
var height = 200;
bg.drawRect(0, 0, width, height);

// We are done!
bg.endFill();

Graphic Width & Height

Now you can create other objects in a relative position to the graphics x,y-coordinates. Unfortunately, we cannot base anything off the graphic’s width and height properties anymore.

For some reason, in Phaser 3 Beta 20 the graphic objects do not have a width and height value. So if you need this for relative positioning, you have to set them yourself.

But I would be careful to not overwrite any properties that might be added in a future Phaser 3 release. So I would probably not use bg.width; something like bg.my_width is probably safe to use and prevents future conflicts.

// I wouldn't set these properties
bg.width    = 350;

// This is probably never going to be needed by the Phaser 3 framework
bg.my_width = 350;

Tweening Graphic Alpha

A final thing that popped up was the fact that you cannot tween or change the alpha of an existing graphic object.

I don’t know if this is a bug or something that’s just missing in Beta 20. However, it would be really great if it gets added soon.

If you need to change the alpha value of a graphics object, you have to clear it, re-set the fillStyle and draw it again.

// We create the graphics object
var bg = this.add.graphics({ x: 25, y: 100 });
bg.fillStyle(0x000000, 1);
bg.drawRect(0, 0, 350, 200);
bg.endFill();

// Neither of these will work
bg.setAlpha(0.5);
bg.alpha = 0.5;

// You have to clear & re-draw
bg.clear();
bg.fillStyle(0x000000, 0.5);
bg.drawRect(0, 0, 350, 200);
bg.endFill();

This makes it unsuitable for tweens. Maybe a possible workaround could be to have a tween with a number of repeats and then use the onRepeat callback function to manually clear & re-draw every time.

Back to overview

3. Re-Starting the Same Scene

In Phaser 2 you could start a state from inside the same state, which would cause the state to re-start with the init method. It might sound confusing but it’s really just this: re-starting the same scene (or state previously).

In Phaser 3 it will not actually re-start the scene if you are currently in it:

// If you are currently in the PlayScene, this will not work
this.scene.start('Play');

So as a workaround I created a simple re-direct scene like this:

var RedirectScene = new Phaser.Scene('Redirect');

RedirectScene.init = function()
{
	'use strict';
	
	// ...
};

RedirectScene.create = function()
{
	'use strict';
	
	this.bg		= this.add.image(0, 0, 'bg-main').setOrigin(0);
	
	this.scene.start('Play');
};

If passing data between scenes were possible we could simply pass the name and have the RedirectScene be more flexible. Right now you have to set a global variable if you want the RedirectScene to re-start different scenes.

Fortunately for Pixel Memory I only needed to restart the PlayScene; hence, I’ve hard coded it into my RedirectScene.

You also must set a background. Because the RedirectScene will actually show for 1 frame and that causes a short but still noticeable “flashing” every time you re-start the scene.

I know this looks like an ugly workaround but it’s the only thing I got working and there were no examples on Phaser Labs to give any insight.

Back to overview

4. Playing Sound

To round up this series I just want to point out how amazing playing sound is in Phaser 3!

Once the audio files are loaded into the game, you can play them anytime. No need to create a sound object anymore like in Phaser 2.

It’s a small thing that makes working with sound files so much more fun!

// PreloadScene
this.load.audio('level_won', [ 'levelwin.ogg', 'levelwin.m4a' ]);

// PlayScene
this.sound.play('level_won');

Back to overview

 
And that’s it for this series. Thank you so much for reading! If you find any typos, mistakes, or have suggestions, please feel free to do so in the comments below or contact me on Twitter @thejamespierce.

If you want to try some of my other games, here are a few titles:

First Phaser 3 Game – Lessons & Code Pt. 2

This dev blog posts series is about my first Phaser 3 game “Pixel Memory“.

The previous post in the series can be found here: First Phaser 3 Game – Lessons & Code Pt. 1

Overview

  1. Workaround: Passing Data Between Scenes
  2. Changing Width / Height of Phaser 3 Objects
  3. Tween Config
  4. Sprite Children: Buttons With Labels

1. Workaround: Passing Data Between Scenes

As mentioned last time, there is a bug in Phaser 3 Beta 20 that prevents you from passing data between scenes.

For completion’s sake, here is how you would normally pass data between two scenes (Phaser 3 Lab Link):

// Here we are in the "Level" scene
// We start the "play" scene and send some data
this.scene.start('Play', { level: 3, difficulty: Medium });

// In the init or create method of the "Play" scene you receive the data as follows
PlayScene.init = function(data)
{
	this._LEVEL = data.level;
	this._DIFF  = data.difficulty;
};

Unfortunately, the data object that you will receive in the PlayScene is empty (Phaser 3 Beta 20).

In Pixel Memory, players can select the difficulty and also choose the color of their card decks. Since I couldn’t pass this data to the PlayScene, I decided to use global variables as a workaround.

Selecting a deck color in the DecksScene:

DecksScene.clickBlue = function()
{
	'use strict';
	
	if(this.flagClick() === false)
	{
		return;
	}
	
	this.sys.game._DECK	= 0;
	
	this.hideUnselected();
	
	this.startTransitionOut(this.goPlay);
};

Selecting a difficulty in the DifficultyScene:

DifficultyScene.clickEasy = function()
{
	'use strict';
	
	if(this.flagClick() === false)
	{
		return;
	}
	
	this.sys.game._COLS	= 4;
	this.sys.game._ROWS	= 7;
	
	this.startTransitionOut(this.goDecks);
};

Saving all data when initializing the PlayScene:

PlayScene.init = function()
{
	'use strict';

	// ...

	this._COLS		= this.sys.game._COLS;
	this._ROWS		= this.sys.game._ROWS;
	this._DECK		= this.sys.game._DECK;

	// ...

	this.sys.game._COLS	= undefined;
	this.sys.game._ROWS	= undefined;
	this.sys.game._DECK	= undefined;
};

The concept is very easy and as long as you unset these values properly, it works perfectly fine.

Important: Notice that to save a variable in the global game space, you have to save it in this.sys.game.

Back to overview

2. Changing Width / Height of Phaser 3 Objects

In Phaser 2 you could directly set the width & height of a game object and it will take these values in the game.

Not so anymore in Phaser 3. In Phaser 3, you have to differentiate between sprite.width and sprite.displayWidth.

For example, I wanted to dynamically change the width of the XP bar on a player’s profile. It only works if you set the displayWidth property.

The width property is reserved for the width of the image, as it was loaded into the game. If it comes from a sprite sheet, it will show the width value of one frame in the sprite sheet.

You can also change the width of a sprite by setting its scale. However, remember that this scales the whole image! Since my XP bar has different edges, I cannot scale the whole image down. I needed to crop it dynamically, which means changing the displayWidth value.

// This does nothing
this.ui.profile.xpbar.width		= Math.round(this.ui.profile.xpbar.width * ratio);

// This works
this.ui.profile.xpbar.displayWidth	= Math.round(this.ui.profile.xpbar.width * ratio);

// This also changes the width, but it scales the full width of the image!!
this.ui.profile.xpbar.setScale(ratio, 1);

Back to overview

3. Tween Config

Tweening in Phaser 3 is absolutely amazing.

We now simply pass an object with all the tween config properties, such as duration, ease, but even callback & callbackScope.

I want to list this example because some properties are extremely useful to know about, such as callbackScope. Try it out!

var scope = this;

var tween = this.tweens.add({
        targets		: [ myImage, myGraphic, mySprite ],
        x		: 600,
        ease		: 'Linear',
        duration	: 3000,
        yoyo		: true,
        repeat		: 1, // -1 for infinite repeats
        onStart		: function () { console.log('onStart'); console.log(arguments); },
        onComplete	: function () { console.log('onComplete'); console.log(arguments); },
        onYoyo		: function () { console.log('onYoyo'); console.log(arguments); },
        onRepeat	: function () { console.log('onRepeat'); console.log(arguments); },
        callbackScope	: scope
    });

Sometimes you have tweens that are very similar and only slightly different. In that case, you can set up a method to return the tween config object for you:

function getTweenConfig(ctx, delay, col, row, pos)
{
	return {
		targets			: ctx.decks[col][row],
		delay			: delay,
		duration		: 500,
		x			: pos.x,
		y			: pos.y,
		angle			: -720,
		ease			: 'Linear',
		// play sfx
		onStart			: function() { ctx.time.delayedCall(delay, ctx.helper.playSfx, [ctx, 'tap_card'], ctx); },
		// normal callback
		onComplete		: function() { completeIntro.call(ctx, col, row); },
		callbackScope		: ctx
	}
}

Back to overview

4. Sprite Children: Buttons With Labels

I like to create helper methods for objects that I have to create many times in a game.

Such an object is a button with label. While the button sprite can be the same many times, the label on it will always be different.

In Phaser 2, you had the ability to create the button object and then add a text object as its child. Whatever property you changed on the button object thereafter, it also applied it to the child object (the text).

Unfortunately in Phaser 3 Beta 20, you cannot add children to an object. I hope this is something that will be added in a later release.

You still have the possibility to create Phaser Groups, though. However, the group object didn’t offer all the functionality I needed for my buttons.

So instead, I have added the text to the data object of my buttons.

I am pasting the full helper method for you below. Feel free to use it in your own Phaser 3 games & improve it further:

Helper.prototype.createBtnWithLabel = function(ctx, x, y, img, callback, label_config, frames, data)
{
	'use strict';
	
	var btn;
	var text;
	
	var label_config	= label_config || { string: '[n/a]', size: 64, color: '0xFFFFFF', x: 0, y: 0 };
	
	// Label position
	if(!label_config.x)
	{
		label_config.x	= 0;
	}
	if(!label_config.y)
	{
		label_config.y	= 0;
	}
	
	// Create...
	// ...sprite
	btn			= ctx.add.sprite(x, y, img);
	// ...label
	text			= this.createText(ctx, x + label_config.x, y + label_config.y, label_config.string, label_config.size, label_config.color);
	// ...data
	btn.data		= data || {};
	btn.data.label_obj	= text;
	
	// Inputs...
	// ...activate
	btn.setInteractive();
	// ...callback
	btn.on('pointerup', function(e)
	{
		ctx.helper.playClickSfx(ctx);
		callback.call(ctx);
	});
	
	// Frames...
	// ...hover
	if(frames && frames.over)
	{
		btn.on('pointerover', function(e)
		{
			this.setFrame(frames.over);
		});
		
		btn.on('pointerout', function(e)
		{
			this.setFrame(0);
		});
	}
	// ...click
	if(frames && frames.down)
	{
		btn.on('pointerdown', function(e)
		{
			this.setFrame(frames.down);
		});
	}
	
	// Return group
	return btn;
};

As you can see, a beautiful thing about such helper methods is that you can easily add /change the “click” sounds for all buttons.

You could also add the callback for mobile players, where a touch input will not trigger the “out” state after clicking a button. For example when registering the “pointerdown” input, you run a callback method that resets the button’s frame back to the “out” frame after a short delay (maybe 250 ms).

Anything that you need all (or most) of your buttons to do, I hope that this helper method provides a good template for it.

Back to overview

 
Thank you so much for reading this! If you find any typos, mistakes, or have suggestions, please feel free to do so in the comments below or contact me on Twitter @thejamespierce.

If you want to try some of my other games, here are a few titles:

Pixel Memory – First Phaser 3 Game

“Pixel Memory” is officially released as our first Phaser 3 Game – Classic Puzzles & More!

Click Here to Play: Pixel Memory

Summary

Find all pairs, level your profile & unlock new cards in this “Memory” classic optimized for mobile!

Game Features

  • Play the “Memory” classic in this mobile game.
  • 3 Difficulties: Easy, Medium & Hard.
  • Level up your profile & unlock more cards.
  • Browse your collection to see which cards you’ve already unlocked.
  • 4 card deck skins: Choose the one you like best!
  • View your profile for your game stats & best scores in all difficulties.

Gameplay

  • Find all the matching card pairs on the table.
  • Find them before you run out of guesses.
  • Unlock all the card packages in the game.

Controls

The whole game requires only click inputs and is perfectly optimized for mobile!

Link

Click Here to Play: Pixel Memory

Chase the Shadow – Week 1 in Review!

Chase the Shadow has been released exactly 1 week ago and a lot has happened!

Player Numbers

At the point of writing this, there has been the incredible number of 187 logins! Half of all the logins happened today (more about that in Mentions below.)

All players have been very friendly and I only had to delete one offensive chat entry (it was a swear-word in Russian). Even some “ggwp”-messages have started popping up!

Game Updates

I updated the game in a few ways:

  • Added a bouncing pixel-arrow to the “Guide” button to show new players they should click it.
  • Changed the chat color from black to white; much better on the eyes now.
  • The “Toggle Audio” button now also turns off the piano music from the intro, if it’s still running.
  • Added a message to the intro screen to contact me for a match if you are alone in the lobby.

Mentions & Listings

The game has been listed as “Staff Pick” in today’s Phaser Newsletter, which is just incredible! A lot of traffic has surged in thanks to that.

The game is now also listed on Indie Game Launchpad & Yunoia.

Future Updates

Right now I have no future updates planned for the game.

A good friend suggested adding a leaderboard or ranking system. Right now, there are no reasons to come back and play again. So I agree there should be a system like that.

However, adding leaderboards or rankings would require a registration & login system. So I think I could create a new game with more depth & polish instead of expanding Chase the Shadow.

It was a test-project to see how well a PHP online multiplayer game works and I think it was a success.

Click Here to Play: Chase The Shadow

First Phaser 3 Game- Lessons & Code Pt. 1

Update Feb 09 2018:
The game is fully released and can be played here: Pixel Memory.


As already announced previously, Chase the Shadow was my last Phaser 2 game.

With the release of Phaser 3 around the corner (at the point of writing the release date is set to 12th February), I want to build all games with Phaser 3 going forward.

So I have started with a new project using Phaser 3 (Beta 20 version). Progress has been very slow in the first day because there is currently no documentation for Phaser 3.

I am using the Phaser 3 lab examples & reading the source code to figure things out. The fact that there are similarities to Phaser 2 greatly helps, of course.

Gif of an animated loading screen built in Phaser 3. First lessons learned are summarized in this post.

Project Introduction

This project will purposely be as small as possible so I don’t overwhelm myself trying to do too much while learning Phaser 3.

I want this to be a casual puzzle game playable through touch-input (or clicks for desktops). It will be a memory game with cards – something most of us know from childhood. The name is currently set to Pixel Memory.

Overview: Phaser 3 Challenges

The point of this series is to show what worked for me in Phaser 3 and share snippets of my code.

In my first day, I have come across the following challenges using Phaser3 which I want to explain in this post.

You can click on a link to scroll directly to its paragraph:

  1. Phaser 3 Config
  2. Setting Global Variables
  3. Adding Scenes
  4. Enclosing the Whole Game Object
  5. Separate Files for Scenes & Prefabs
  6. Centering & Resizing the Canvas
  7. Going Fullscreen
  8. Bitmap Text Center Origin

1. Phaser 3 Config

The first challenge I came across was booting up the app with my preferred configuration.

In Phaser 3 we pas an object to the game constructor with all the configuration properties. The most important ones are self-explanatory as you brows the lab examples.

var config		= {
	// ...
};
var game		= new Phaser.Game(config);

However, there are a great deal of new properties that I find really cool. One of them is the name for the game.

The parent property is the ID of the div inside which the canvas will reside in.

Here is my full config object that I passed to the game constructor:

var config		= {
	type	: Phaser.AUTO,
	width	: 9  * 64,		// 576
	height	: 15 * 64,		// 960
	parent	: 'phaser-app',
	scene	: scenes,
	title	: 'PixelMemory'
};

var game		= new Phaser.Game(config);

Back to overview

2. Setting Global Variables

One thing I did a lot in Phaser 2 is setting global variables, accessible from every scene (previously “state”).

If I need access to a property from many scenes, I opt for setting a global variable instead of passing them between scenes.

Moreover, passing data between states is currently bugged (see the open GitHub issue here).

Here is how I set my global variables:

game._URL	= 'http://localhost/PhaserGames/PixelMemory/'
game._USER_ID	= 0;

And here is how you can then access them from inside any scene later on:

var url		= this.sys.game._URL;
var u_id	= this.sys.game._USER_ID;

Back to overview

3. Adding Scenes

In Phaser 3 we add an array of scenes to the scenes property of the config object.

While I love the fact that we can pass an array, I found it confusing at first because I wasn’t sure if the order I’m adding them is relevant or not.

Moreover, it’s not very readable if you have a lot of scenes to add.

To remedy this, I am adding scenes like this:

var scenes		= [];

scenes.push(BootScene);
scenes.push(PreloadScene);
scenes.push(IntroScene);

var config		= {
	// ...
	scene	: scenes,
	// ...
};

The order doesn’t matter besides the first scene you add.

By default, the app will automatically start with the first scene you have added to this array. However, you can also manually start the app from any scene you want.

After the first one it doesn’t matter in which order you add the scenes.

Back to overview

4. Enclosing the Whole Game Object

Unlike native apps, browser games are heavily exposed to the client.

I like to hide as much as possible in enclosed functions and make it at least harder for anyone trying to change the game at run-time (aka “hack” it).

For this reason, I have always enclosed the whole game object. I don’t know how much protection it really brings but from what I’ve read about the topic it’s better than nothing.

I believe making efforts here shows the players you care about your app. (I always try to see how easily I can hack a HTML5 game at runtime – and I feel like I can’t be the only one. Not all of them are devs but some are.)

Anyways, enclosing it was easy as I can do it pretty much the same way I did in Phaser 2:

var App = function() {};

App.prototype.start = function()
{
	// Scenes
	var scenes		= [];
	
	scenes.push(BootScene);
	scenes.push(PreloadScene);
	scenes.push(IntroScene);
	
	// Game config
	var config		= {
		type	: Phaser.AUTO,
		width	: 9  * 64,		// 576
		height	: 15 * 64,		// 960
		parent	: 'phaser-app',
		scene	: scenes,
		title	: 'PixelMemory'
	};
	
	// Create game app
	var game		= new Phaser.Game(config);
	
	// Globals
	game._URL		= 'http://localhost/PhaserGames/PixelMemory/';	// this.sys.game._URL
	game._USER_ID	= 0;
	
	game._CONFIG	= config;
};

window.onload = function()
{
	'use strict';
	
	var app = new App();

	app.start();
}

Back to overview

5. Separate Files for Scenes & Prefabs

For organizational reasons (and personal preference I guess), I like to have separate files for each scene & prefab.

Closure & prototyping help me keep a clean namespace. Furthermore, I focus better on the task in front of me if my code is neatly organized in files like that.

From what I understood in the lab examples, it is better to use static methods in a scene instead of prototyping them.

The string that you pass to the scene constructor is the scene’s name that you will reference when starting it (or switching to it, which is now possible in Phaser 3).

This is how I organize my scenes now:

var PreloadScene= new Phaser.Scene('Preload');

PreloadScene.preload = function()
{
	'use strict';
	
	// ...
};

PreloadScene.create= function()
{
	'use strict';
	
	// ...
};

PreloadScene.update= function()
{
	'use strict';
	
	// ...
};

And this is how I organize my prefabs:

var Helper = function() {};

Helper.prototype.createText = function(ctx, x, y, string, size, anchor)
{
	'use strict';
};

This is how you start a new scene (from within your current scene):

this.scene.start('Preload');

Back to overview

6. Centering & Resizing the Canvas

In Phaser 2 we had handy methods available to configure the position & resizing of the canvas element.

In Phaser 3 these don’t seem to be available, yet. So I had to do it old-school with CSS & native JS inside my index.html file.

For this game I want the canvas to be centered on the screen at all times and re-size together with the browser window. And it must work on mobile, as well.

Here is my CSS code (notice the ID “phaser-app” is the divfrom the parent property in the config object above):

body {
	margin				: 0;
	overflow			: hidden;
	background-color	: black;
}
		
canvas {
	height		: 100%;
}
		
#phaser-app {
	margin		: 0 auto;
}

And here is my JS code:

// Resize
function resizeApp()
{
	var div				= document.getElementById('phaser-app');
			
	div.style.width		= window.innerHeight * 0.6;
	div.style.height	= window.innerHeight;
}
		
window.addEventListener('resize', function(e)
{
	resizeApp();
});
		
resizeApp();

Back to overview

7. Going Fullscreen

In Phaser 2 we also had a handy method available to launch the app in fullscreen.

This also doesn’t appear to be part of Phaser 3 Beta 20 (at least I couldn’t find it) so I had to use the Fullscreen API manually.

This code also resides in my index.html file:

// Fullscreen
function fs_status()
{
	if(document.fullscreenElement)
	{
		return true;
	}
	else if(document.webkitFullscreenElement)
	{
		return true;
	}
	else if(document.mozFullScreenElement)
	{
		return true;
	}
	else
	{
		return false;
	}
}
		
function goFullscreen()
{
	if(fs_status())
	{
		return;
	}
			
	var el			= document.getElementsByTagName('canvas')[0];
	var requestFullScreen	= el.requestFullscreen || el.msRequestFullscreen || el.mozRequestFullScreen || el.webkitRequestFullscreen;
			
	if(requestFullScreen)
	{
		requestFullScreen.call(el);
	}
}
		
document.getElementsByTagName('div')[0].addEventListener('click', goFullscreen);

Back to overview

8. Bitmap Text Center Origin

Currently, it is not possible to change the origin of a bitmap text object.

It works fine for images, though (I haven’t tried other objects).

In Phaser 2, it was called “anchor”. In Phaser 3 this term seems to have been dropped completely and is replaced by “origin”.

The default origin for images is now set to 0.5 (previously 0); but for bitmap texts it is still set to 0.

Here is how you set the origin for an image:

// You can chain it directly
this.add.image(0, 0, 'bg-main').setOrigin(0);

// Or you can add it later to an image object
this.bg_main.setOrigin(0);

To have bitmap texts anchored to their center, I have written up this simple helper method:

// My helper prefab
var Helper = function() {};

// Method to create a bitmap text
// I am still calling it "ancho"r instead of "origin"; old habit that will change going forward
Helper.prototype.createText = function(ctx, x, y, string, size, anchor)
{
	'use strict';
	
	var text;
	
	var font	= 'supermercado';
	var size	= size || 64;
	
	// Text
	text		= ctx.add.bitmapText(x, y, font, string, 64);
	
	// Anchor...
	// ...center
	if(!anchor || anchor === 0.5)
	{
		text.x	   -= (text.width * 0.5);
		text.y	   -= (text.height * 0.5);
	}
	// ...1
	if(anchor === 1)
	{
		text.x	   -= text.width;
		text.y	   -= text.height;
	}
	// ...x & y different
	else if(typeof anchor == 'object')
	{
		if(anchor.x === 0.5)
		{
			text.x	   -= (text.width * 0.5);
		}
		if(anchor.y === 0.5)
		{
			text.y	   -= (text.height * 0.5);
		}
		
		if(anchor.x === 1)
		{
			text.x	   -= text.width;
		}
		if(anchor.y === 1)
		{
			text.y	   -= text.height;
		}
	}
	
	// Return
	return text;
};

Back to overview

 
Thank you so much for reading this! If you find any typos, mistakes, or have suggestions, please feel free to do so in the comments below or contact me on Twitter @thejamespierce.

If you want to try some of my other games, here are a few titles:

Chase the Shadow Released

Chase the Shadow

“Chase the Shadow” is now officially released!

Game Link

Click Here to Play: Chase The Shadow

Summary

A casual, lighthearted 1vs1 Arena Game! Play online against a friend or any person waiting in the lobby.

Game Features

  • Play online 1vs1 against a friend or any person waiting in the lobby. No registration/login required!
  • Control a wizard & defeat the enemy wizard.
  • You have 3 spells at your disposal: Fireball, Lightning & Blizzard.

Gameplay

  • You can see the enemy’s shadow. Predict his movement and hit him with your spells!
  • Select the right spell for the situation.
  • Move into the right position to aim your spells.
  • Trick your enemy with unpredictable movements.
  • Win by defeating the enemy before he kills you!

Controls

  • Click your wizard to move.
  • Click on the spell scrolls to activate a spell.
  • Plan your next move during your enemy’s turn & pay attention to his shadow!

Link

Click Here to Play: Chase The Shadow