I finally got to making my 1st game in Power Apps, and what better than choosing my favorite sport - tennis! With all the games these days focusing so much on graphics, I wanted to pay tribute to the video games we played during our childhood (man I sound old!). Hence, the idea of a retro style tennis video game!
All of this started at 10 on one random night. The basic idea was simple: have a ball machine on one side of the court throwing balls at the player in random directions and the player has to hit as many as possible! Somehow managing to not get distracted with things like home screen, background image (of course of Roger Federer!), tennis court image and other similar aspects of the game, I laid out the challenges that were ahead of me:
How to ensure that the transition of the ball from one side of the court to the other is smooth?
How do I control the difficulty level of the game?
If I have a ball machine on one side of the court, how do I randomize the direction of the ball?
How do I classify a hit as a successful one?
I knew that once I figured out how to get past these challenges the rest of the tweaks would be easy. Here's the design approach I took to tackle each of the points mentioned above:
To transition the ball from one end of the screen to the other, I knew I had to play with the X and Y positions of the ball (which was an image). Let's say the starting position of the ball at the center of the screen is X=100, Y=0. Also, let's say the height of the screen is 300. So, the 3 positions I needed the ball to get to were: (X=0, Y=300), (X=100, Y=300), & (X=200, Y=300). Taking one of these as an example, it would have looked really bad if we simply changed the position of the ball from (X=100, Y=0) to (X=0, Y=300). To ensure a smooth transition, I added a timer and set its duration to 1000 ms. Then I set the X and Y positions of the ball to: X = 100 - 100*(Timer.Value/Timer.Duration) and Y = 0 + 300*(Timer.Value/Timer.Duration) This ensured that when the timer gets started, and its value changes from 0 to 1000, the Timer.Value/Timer.Duration ratio would change from 0 to 1 in very small increments making the transition very smooth for a human eye! Challenge 1 tackled!
Having taking care of the 1st challenge, this one turned out to be pretty straightforward. The difficulty level of the game could be controlled by simply controlling the speed at which the ball traveled to the player. For this, all that was needed was an adjustment to the duration of the timer described in the point above. I played with a few values and decided to use 1500 ms for Amateur, 1000 ms for Pro, and 500 ms for Legend skill levels! I also used the same timer to control the length of the game. A variable defined the number of times this timer would repeat.
I was going through the entire list of Power Apps formula (found here) but for some reason I did not start my search with the word random (I have no idea why!). Anyways, once I got to the Rand() function, I figured that I could generate a random number every time I called it. Also, the random numbers were generated in the range of 0 to 1. Referencing point #1, the X positions of the ball had to change from 100 to 0 or 200, or stay at 100. I divided the range of Rand() function's output into 3 equal sections: 0-0.33, 0.33-0.66, 0.66-0.99. Based on the range to which the random number belonged, all I had to do was either subtract 100, add 100, or do nothing to the original X value of the ball. That's it, randomness achieved!
A slider was my default selection for the control needed to represent a tennis racket. The logic to figure out a successful hit was as simple as checking if the X position of the ball was the same as the slider position when the Y position of the ball was 300 (the same end as the player). I started off with the slider range from 0 to 100 (with a default value of 50). Although this allowed completely smooth movement of the slider, checking the condition for a successful hit was a bit difficult. To illustrate this challenge, consider the situation in which the ball comes straight down from the ball machine. The X position of the ball is 100 when it is at the same Y as the player. With a slider that moves from 0 to 100, a hit would be successful only when the slider is at 50. Any value other than 50 would result in this being counted as an unsuccessful hit. Sure, I would add some padding to the value or range that would define a successful hit. I could say, that if the slider is between 45 to 55 and the ball comes straight down, its a successful hit but then the players of the game could figure out that the conditions are a bit relaxed and then fun goes away. So to keep it simple, I changed the values of the slider range from 0 to 2, which gives only 3 possible values - 0, 1, or 2. And the conditions for a successful hit become simple - when the ball's Y=300, the following conditions would result in a successful hit:
Ball X=0 and Slider value=0
Ball X=100 and Slider value=1
Ball X=200 and Slider value=2
With these challenges now a thing of the past, it was all fun to make minor tweaks to the app to get the exact behavior. A few additional features that were added are:
A home screen that automatically switches to the settings page
List of rules and buttons to select skill level and match duration
Ability to store and view scores using LoadData and SaveData
A countdown before a game starts
Live scores during a game
Final scores at the end of a game
Music during the game that can be turned on or off
So that's how the entire app was made by 2 am, all in 4 hours! Here is a collage of all the screens within the app (they are all on the same screen behind the scenes!):
Here is a small demo of the app (some of the screens in the video are not the latest and there is no music):