Ui Blocks-A lightweight alternate to containers

Phaser Containers Alternative

As a developer for a gaming company that has a lot of feedback from its users I understand that people can get very passionate about the features that they’re used to having. I’m afraid I was a victim of that passion about a week ago when I saw this notice from Richard Davey(creator of Phaser).

This is just a heads-up for those who track issues that support for nested Containers will be removed from a forthcoming version of Phaser (not 3.12, but probably 3.13).

The ability to create and use Containers will remain, but you will no longer be able to add a Container as a child of another. Source

I understand and support this decision, but it did leave me with a problem to solve.

Groups and Containers in Phaser 3

Coming from a background of flash I was used to creating MovieClips and adding other objects inside those clips.  I especially use this for user interface components. In Phaser 2 I use groups quite a bit to create UI.

To understand the problem, we need to understand a bit about groups and containers. Lately, I’ve been seeing a lot of confusion about groups and containers. It is especially confusing for those of us that are coming from Phaser 2. Groups in Phaser 3 do not work the same as in Phaser 2.

A common question I’ve seen is ” why can I not add a group to a group?”. Let’s have a look at what happens when you add a child to a container or group.

How Groups Work

Here is some simple code that adds 4 images to a scene. We then add 2 images to each of the group and the container.

Now if we log out the scene to the console this is the result

As you can see even though we have added the images, icon3 and 4 to the group, they are still on the display list of the scene. The group isn’t anywhere to be seen on the list at all! In Phaser 3 groups are used to organize game objects. You may group objects together for physics collisions, or simply to have an easy way to iterate through the children.  In Phaser 3  Sprites, images, texts are always children of the scene.  That is except for containers.

How Containers Work

Containers have their own display list. If you add a game object to a container it goes on the container’s list. Here is the output of the container.

As you can see, icon1 and icon2 are on the list of the container. So when you change something on the container, those changes will affect all the children on the list.

So what’s the problem?

Because we can add a container to a container and then that container can contain an infinite number of containers it begins to affect the performance of the code.  In the words of Richard Davey:

Containers can be nested. This means you can insert one Container inside another and branch children off of that. We do not recommend this as the deeper the chain goes, the more expensive every single look-up becomes, as each child traverses the tree back to the root every time it renders.

This is what apparently has caused enough problems to eliminate container nesting.

My Workaround

 I do not intend this to serve as a replacement for containers everywhere in every situation. However, a lot of developers I’ve talked to are using containers to build UI, and it is the only way that I am currently using containers.

As you can see from the output above phaser containers have bodies this means that physics can be applied to a container. They also have a lot of other things in there such as transform, angle and blend mode that I don’t need for my UI.  All I need to do is to find a set of elements that can be positioned relative to another set of coordinates. I’ve also added the functionality to set visibility or not. These features can be expanded but for now, these basics will suffice.

For example to create a text button I combine a text field and an image inside a container. say that I want to make a message box, that would require making another container. Then I would have to put the first container(the button) inside the second container. 

This solution solves that problem. It does have its limitations but it’s what I need and I hope that you find it helpful. 

The UIBlock Class

The UIBlock class leaves the children on the stage the same way that groups do. I also used a linked list instead of for next Loops to speed up the iteration through the children to update their positions. Everything else is just basic maths. 

Usage

My preferred way of using this is to extend a class

However, you can also use it this way

Result:

Limitations

These are the main features missing from the UIBlock:

  • physics
  • alpha
  • scaling
  • rotation

Alpha can easily be added by copying and editing the functions associated with visibility. I suggest scaling the children individually. It is possible that scaling can be implemented at a later time. Since this is being primarily used for UI, physics isn’t really needed. I  am happy to say that tweening will work as long as you stick to the properties that are in UIBlock, such as x and y.  I’ll most likely keep tweaking this to my needs and I feel that there is a lot to be added, but I wanted to release this for any other developers who find themselves in need of it.

 

 

 

 

Leave a Reply