Creating an Isometric View in Phaser 3

Edit: Phaser 3.50 now supports isometric tilemaps. You should probably use that.

Full Repo:

I’ve been working on a casual flower genetics game, in the Phaser 3 engine. I’d always imagined it having a psuedo 3D effect, and after building it to this point, I wanted to try to finally get the visuals in a workable place.

First we’ll make sure we have some assets that work in the isometric perspective. I’m a Patreon backer and big fan of SpriteStack. So that’ll be my tool of choice. If you’re interested in how this art technique works, I recommend reading this blog post by like100Bears. Basically we draw layers as 2D images. When we move in the z direction, we create a new layer and offset that in the y direction by one pixel. All of those layers stacked on top of each other, offset by one pixel give the illusion of depth.

Programmer art

I exported 3 objects from my project, a grass tile, a flower stem, and a flower head. Each has a png and a json file that we’ll be using. The grass tiles will be used to fill in the world, and I separate the stem from the flower so I can paint the flower any color I want, without affecting the stem’s color. I’m doing camera angle 60 (For the typical 120 ° isometric angle), 16 angles, 2x pixels.

Now we need to figure out how to include these images into the game world in a way that preserves the isometric view shown in SpriteStack, and behaves as expected in that view. The actual math for changing from Cartesian (standard 2D) coordinates to isometric coordinates is relatively simple, but I’ll be using a plugin to speed things along. Here’s a primer for those interested in the how this works.

Phaser 3 is still a little new to have a well documented fully featured isometric plugin, but luckily we have what we need. sebashwa forked the Phaser 2 isometric plugin and has a number of those features working for a Phaser 3 version. The interaction example on their github page, is close to what I’m looking for.

The interaction demo for the isometric plugin


Now to code! First step is to install the plugin

npm i phaser3-plugin-isometric --save

I’m adding this into my already existing project, so I’ve already got an index.js that kicks off the whole app. That calls my scene file, which is where our first change occurs. We’re creating a configuration object, that’s just telling Phaser that we’ll be using the isometric plugin.

Next we’ll jump over to the preload function. We’re importing the plugin, and loading it with the same sceneKey as the one used in scene.js. For the images, I’m importing the json file to use as information to help slice my sprite sheet, and start with the correct frame.

At this point we have our isometric assets ready to use, so lets add them in the scene. My create.js immediately calls an init function which provides the intial calls to setting up the scene. I pass in this as the parameter to retain context to the game. I’m grouping the grass tiles so I can create and refer to their behavior easily. I also make the first call to the iso plugin and place the camera, setting it center horizontal and slightly above center vertical.

Now I add the tiles with my addTiles function, passing in the game context again. I import the data about the grass tile to get the size of the tiles, then I adjust to get the fit right so that the tiles are spaced closely together. I create a nested loop which spaces each tile by that defined height.

I’m adding the tile as an isoSprite, which is the plugin’s extension for a regular sprite. Then I set it as interactive so I can provide some mouse over events. Here we can see our first interaction with the z axis. We raise the sprite up a bit when the mouse is over it. Additionally, if it has a flowerSprite, raise that too.

Isometric grass tiles with mouse over events

Where did that flowerSprite come from? We gotta make it. Back in our init, there’s another function that creates our flowers, add3dFlower.js. The first difference between adding an isosprite and regular sprite is in determining the position. I’m grabbing a random tile from the tile group we created in the previous step, and using that tile’s isometric position to place my flowers on top. The z position is 2 for the flowerhead, so that it can stay on top of the stem, which has a z position of 1, which stays on top of the grass with a z position of 0.

For whatever reason, I get an error when trying to use the 5th argument for creating an isoSprite. It should refer to setting the initial frame, but I get an error that h.add is not a function, despite this behavior being described in the docs. I just do it immediately after creating the sprite with setFrame(0). The process is repeated for the stem, and then I associate this sprite with the tile it was created on, so that the flower sprite is lifted up on mouse hover as well.

The finished product of the tutorial. An isometric view of a voxel flower on a grass field.

And with that we’ve got a little isometric scene started. Certainly a couple places to refactor and smooth out, but it’s looking much better that what I had previously. Let me know if you have any comments or suggestions or can sort out that bug above. Thanks for reading!

Before and after

Full Repo:



Developer. Musician. Naturalist. Traveler. In any order. @tayloredtotaylor

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Taylor Nodell

Developer. Musician. Naturalist. Traveler. In any order. @tayloredtotaylor