Are you having image distortion problems when using
displayWidth to make a button or panel graphic bigger?
You could have multiple versions of the same button asset at different sizes but that doesn't seem very efficient in terms of download size for players or your own time.
Imagine having to update every button size each time a new change is made! 😱
There's a solution for this and it is called 9-slice scaling or Scale 9 Grid.
This technique was first introduced in graphics editing software but has since become commonly used in games as well.
9-slice scaling is a better way to scale images that preserves the visual integrity of edges and corners.
In this article, we'll show you how to use it with the phaser3-nineslice plugin.
We are going to keep the code here pretty generic so it should work with your specific project set up.
But just in case you run into problems, we are using the phaser3-snowpack-template, and importing the plugin might be a little bit different. We'll make note of it when we get there.
The example button asset that we'll be using is from Kenney's UI Pack where you'll find many assets that can be used with 9-slice scaling.
Scaling without 9-Slice
Some assets scale better than others when simply using
displayWidth. Anything with interesting edges or corners are going to scale poorly with this approach.
You'll end up with something that looks like this 👇
You'll certainly see the glaring distortion of the edge outline on the left and right sides. They are scaled proportionately to the change in
scaleX while the top edges are left alone since setting
displayWidth does not change
This is quite undesirable and we can fix it with the phaser3-nineslice plugin.
Installing the Plugin
There are a few ways to install the plugin as the Github repository notes and we are going to use the
npm approach with this command:
npm install phaser3-nineslice
Next, we need to add the plugin to the
main.js like this:
The first thing to note is the
import statement for the plugin. There are named exports like
Plugin but the bundled output from
phaser3-nineslice doesn't play nicely with Snowpack.
Therefore, we can use the default export instead and then reference the
Plugin named export from there.
If your project uses Parcel or Webpack then you should be fine to do this:
Scaling with 9-Slice
Next, let's use this plugin to create a distortion-free version of our scaled button.
We create a button with a
200 and a
50 using the
'button-bg' asset from Kenney.
The last argument of
16 designates the width and height of the corner piece.
9-slice scaling works by splitting an image into 9 pieces:
- 4 corner pieces
- 4 edge pieces between the corners (top, left, bottom, right)
- 1 middle piece
The single middle piece gets scaled in both
y directions. The top and bottom edge pieces are only scaled in the
x direction while the left and right edge pieces are only scaled in the
The 4 corner pieces are not scaled. They are just placed in the appropriate places depending on the desired width and height.
The result is a scaled image that is distortion-free 👇
One final note, the size of the corner piece will vary depending on your image asset.
This particular asset has a raised bottom which means the corner size needs to account for the worst-case scenario. Compare the top left corner with the bottom left corner and you'll notice that the corner values for the bottom left would need to be bigger than the values needed for the top left.
In practice, you can just change the corner value until you find something that looks like it works. A more precise approach would be to measure the largest corner in a graphics program and then use that value. Either way will work. 😎
9-slice scaling should help you create a more space-efficient game by reusing the same assets for different sized in-game elements.
For more information on using 9-slice scaling with modal dialogs and other beginner-friendly introductions to features like gamepad support, sound effects, music, preloading assets, custom fonts, and more check out the Memory Match Extras course.
You'll also learn some coding best practices and how to organize code to help you become a better developer.
Not yet ready for a course? No problem! We are regularly publishing content to help you make games so join our newsletter to keep learning.
Drop your email into the box below 👇
Don't miss any Phaser 3 game development content
Subscribers get exclusive tips & techniques not found on the blog!
Join our newsletter. It's free. We don't spam. Spamming is for jerks.