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 0
.
We will adjust where it is and how big it should be in the POINTER_DOWN
and POINTER_MOVE
events.
|
|
We add event listeners for POINTER_DOWN
, POINTER_MOVE
, and 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.
Then in 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 width
and 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 width
and 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.
The selected
variable will be an empty list.
This is because the width
and height
of the selection box is negative!
The fix is actually pretty simple. We just need to check if width
or height
is negative and then adjust.
But we should do this adjustment on a new Phaser.Geom.Rectangle
and not this.selection
.
|
|
We create a new Phaser.Geom.Rectangle
on line 15 as a data representation of the selection box.
You can also use a plain JavaScript object but the key is to not modify properties on 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 width
or 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 x
and 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 getChildren()
.
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 Phaser.Geom.Rectangle.Overlaps()
.
Next Steps
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.