Are you building an RTS game where you can select multiple units by dragging a selection box over them?
Have you seen an example for Arcade Physics Sprites but are using a different physics engine or no engine at all?
Did your initial attempt result in a box that only works when it is created by dragging from the top left to the bottom right but not in reverse?
In this article, we'll go over how to multi-select Arcade Physics Sprites and regular Sprites with a selection box.
And have it work no matter what direction it was created in! Something like this:
Creating a Selection Box
First, we need a selection box. We'll use a blue
Rectangle at 50% opacity for this and store it as a class property of the Scene.
The comments above the
selection property declaration are JSDoc annotations to help denote type.
Notice that we set the
Rectangle position and size to be
We will adjust where it is and how big it should be in the
We add event listeners for
POINTER_UP on lines 7 - 9.
Then we add the corresponding handler methods to the Scene class.
Similar to the
selection property declaration above, the comments above each handler method are JSDoc annotations to help denote the type of parameters.
Let's implement each handler method in turn. The
handlePointerDown method is the simplest:
This will position our selection box to where the mouse was first pressed.
handlePointerMove, we will set the width and height based on how far the mouse was moved.
First, we only update the selection box if the mouse pointer is down as checked on line 3.
Then on lines 8 and 9, we calculate how much the mouse has moved since the last time the
POINTER_MOVE event was fired.
We add this change in movement to the
height of the selection box to update its size.
Lastly, we use
this.physics.overlapRect() with the dimensions of the selection box to determine the physics Sprites that are selected.
This does not account for creating a selection box by dragging from the bottom right to the top left. We will handle that next.
But before that, here's what
handlePointerUp looks like:
We simply set the
height to 0 to hide it.
Handling a Reversed Selection Box
You can try creating a selection box in reverse with the implementation we have now to see what happens.
selected variable will be an empty list.
This is because the
height of the selection box is negative!
The fix is actually pretty simple. We just need to check if
height is negative and then adjust.
But we should do this adjustment on a new
Phaser.Geom.Rectangle and not
We create a new
Phaser.Geom.Rectangle on line 15 as a data representation of the selection box.
this.selection because they are used for proper rendering.
Don't just take my word for it! Try it for yourself and see what happens. 😜
Then on lines 24 and 29, we check if
height is negative. If so, we adjust the
Rectangle by adding the width to
x or height to
y and then turn the negative value into a positive one.
This will create an equivalent
Rectangle with the
y at the top left.
Finally, we use the values from the
Rectangle on lines 37 - 40 where we previously used the selection box.
Now we can handle a selection box no matter how it is created!
What about regular Sprites?
To handle non-physics Sprites we'll have to store each sprite in a list or set.
If you are using a
Group then just get the list of children with
The code will be mostly the same as what we already have except we exchange
this.physics.overlapRect() with this:
Assume that we have a class property called
tanks with different Sprites in it.
We iterate over
this.tanks and check for the ones where the bounds overlap the
selectionRect created earlier.
The bounds is retrieved on line 9 using
getBounds() and then the overlap check is on line 11 with
Now you have a robust selection box that will work for any Sprite and can be created from left to right, bottom to top, right to left, or top to bottom!
What you do with these selected Sprites is up to you!
Be sure to sign up for our newsletter so you don't miss any future Phaser 3 game development tips and techniques!
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.