#PowerApps: Simple Object Proximity and Collision Detection
As of late, I have been very interested in all things "Motion" as it relates to developing PowerApps applications - see #PowerApps: Motion Patterns with Parametric Equations. Although, most of the apps you will see tend to be around solving business problems, you cannot really dismiss the capabilities of PowerApps as a gaming platform.
The Basics
In this article, I explore a simple object proximity and collision detection approach, based on some simple logic. The world of gaming uses more sophisticated algorithms based on the laws of physics and what's not, but keep in mind that PowerApps is designed to be a low code/no code environment, hence access to user driven programmatic methods is extremely limited.
The following is a representation of the actual canvas apps I created for this example. It consists of 4 directional arrows to provide motion to smiley, a simple character added from the icons gallery. In addition, we have a rectangular obstacle added as well using the icons gallery. Finally, a slider which controls the steps of the smiley character in any direction.
Canvas app |
There are also two hidden button controls, which we will use to do branch logic. I have found that having code in hidden buttons act as a way to encapsulate logic that you can execute as if it were a method, as you can use PowerApps' Select function to run the On Select code behind the button.
For ease of setting control properties, I have grouped both the directional arrows in one group called Arrows, and the hidden buttons in another group called BusinessLogic, as shown on the left pane of design surface.
Adding Code
Screen On Visible
For the On Visible event, we are simply initializing the position of our smiley character. Smiley will be placed at roughly the center of the screen. The (X,Y) coordinates are stored in two context variables called xPos and yPos, which are then assigned to the X and Y property of the Smiley character.
You can set the obstacle icon away from Smiley, anywhere you want to.
Directional Arrows Group
The directional arrows will control Smiley's motion up, down, left, or right, according to the arrow pressed. The up arrow will simple reduce the position on the Y axis, the down arrow will increase it. Conversely, the left arrow will decrease Smiley's position on the X axis, and the right arrow will increase it. All these movements are done in incremental steps dictated by the slide control value, setting the pace of the movement, if you will.
Note that I have chosen to define a directional variable, SmileyDirection, which tracks whether the motion is decreasing (up, left) or increasing (down, right).
Up Arrow
Left Arrow
Down Arrow
Right Arrow
Business Logic Group
Each time Smiley's motion is affected by the directional arrows, we need to evaluate whether its next step in that direction will put it in proximity with the obstacle, hence leaving it in danger of colliding on the next move.
The first logic branch says:
If Smiley's next step in the current direction (top, bottom) is within the horizontal boundaries of the obstacle - dictated by the value pair Rc1.X and Rc1.X + Rc1.Width - it will only be in the clear if it's outside of the vertical boundaries (the obstacle's height). Otherwise, Smiley would be in imminent danger of colliding on the next move in the current direction of motion - and this is where it gets interesting!
We also need to factor Smiley's own height when the motion is in the direction of the obstacle from the top as the value pair (Smiley.X, Smiley.Y) only represents the upper left corner of Smiley's position. In complex gaming design, this is done from the center of gravity of the object, but remember, we are not that fancy here.
EvalLogic1
If Smiley is not within the horizontal boundaries of the obstacle, then we need to similarly evaluate if Smiley it's within the vertical boundaries of the obstacle, while traveling left or right - dictated by the value pair Rc1.Y and Rc1.Y + Rc1.Height. Then, it stands to reason, that Smiley will only be in the clear, if it's outside the horizontal boundaries in the direction of travel.
Again, we want to factor in Smiley's width to ensure that if we are traveling towards the object from the right, we detect its proximity more accurately.
EvalLogic2
The Warning Label
Each EvalLogic button updates the CollisionWarning context variable, which is then assigned to the Text property of the label (place within the directional arrows pane).
The Final Results
When all the pieces are in place, the following is the final results:
Until next post,
MG.-
Mariano Gomez, MVP
Comments