Not Pong is a Pong-style game that I developed for Fundamentals of Game Technology, using Photoshop for art assets and Stencyl for developing the game. You can play the game at Stencyl Arcade: http://www.stencyl.com/game/play/41774
Not Pong is different from the original Pong because the player can move in 8 directions (horizontal, vertical and diagonal) instead of just 2 directions(vertical). Other than that, powerups also regularly spawn (every 10 seconds, in fact) to give players an advantage. The first player to score 10 goals wins.
Making the art assets
The first step of making Not Pong was to make a replica of the original Pong game. And the first step of making the original Pong Game was to draw the assets, including the map, the Ball, and the Paddles (aka the players).
First, I needed to decide on the art direction. Because I wanted the game to feel like the classic Pong game, I decided to go for an art style that symbolizes the colors on a GameBoy screen, which are different shades of green. (However, it was only after I finished the assets did I realize that Pong was not originally played on a GameBoy but rather on arcade machines. Oops.)
With the art direction settled, I started to work on the assets. As I only knew how to use Photoshop to make simple pixel art, I decided to stick with Photoshop to make the assets.
Assets for the Paddle and Ball, made using Photoshop
Making basic gameplay
With art assets completed, it was time to plug them into Stencyl and add code to them. First, I placed all the actors (objects in the games) on the scene.
Before we talk about how the actors move, let’s talk about how the game is set up. One thing I immediately realised was that the paddles were a bit too small with this current setup. Another thing was that each player’s region felt a bit too narrow.
Also, making the paddle and the line in the middle the same shade of green? Not a great idea.
These were not things I considered when I was drawing the assets. So, I had to go back to Photoshop to resize the assets and plug them into Stencyl again.
New game setup with reworked assets
You might notice there is also an extra line at the left and right side of the map to represent the goals. It’s something I added to help players know see where their goal is (instead of just being outside the screen).
The lines and the left and right were originally supposed to actors that worked as tiles, which prevented players to move across them. Somehow, that didn’t work out the way I wanted to (I still don’t exactly know why).
So instead, I drew the lines onto the map itself and just made it so that the player paddles could not move over the x-coordinates of where the lines were.
Now onto the player’s movement, which was quite easy with Stencyl’s built-in 8-way movement behaviour. In fact, the only reason I gave the players 8-way-movement was because I knew I could do it easily in Stencyl.
All I needed to do was to pick a control key from a drop-down list for each of the directions they can move towards. (Players can press two directions keys at the same time to move diagonally.)
But the real problem was how the Ball’s movement works. See, unlike the paddle, the Ball doesn’t move because there is a player controlling it and telling it to move to wherever they wanted. It moves because it collides with other stuff and there is a force pushing it.
So, let’s start with that. A force is pushing it.
With one of the blocks in Stencyl, I can easily get the ball rolling (pun intended). The block basically pushes the Ball towards the left at a random angle, because that’s how the angle values work in Stencyl for some reason.
Angles in Stencyl
The purple ‘Ballspeed’ block is a Game Attribute. It’s basically a constant that I defined inside Stencyl to ensure that the Ball always moves at a speed of ‘BallSpeed’, which I set to be 40 units.
Next, we need to define what happens when the Ball reaches a goal.
Before that, it is important to note that I used a behaviour in Stencyl known as ‘Cannot Exit Scene’ on the Ball. This is so that when the Ball reaches the top and bottom edge, it does not continue going into the void of the unknown. Instead, its y-speed (vertical speed) is set to 0.
However, this causes the Ball to glide across the edge once it touches it. Thus, I modified the behaviour such that when it touches to top edge, its y-speed is set to ‘Ballspeed’ (again, Ballspeed is a Game Attribute that equals to 40), so it moves down after it touches the top edge to resemble it bouncing off the edge.
Likewise, the y-speed is set to ‘negate Ballspeed’, which is just -40. This causes the Ball to bounce off the bottom edge and move upwards.
The ‘Cannot Exit Scene’ behaviour also prevents the Ball from moving out of the left and right edge, which is not something we want in a Pong game. So, I just deleted that part of the code.
How the original ‘Cannot Leave Scene’ code looks like
How my modified ‘Cannot Leave Scene’ code looks like
Now, the Ball will bounce off the top and bottom edge and will exit through the left and right edge. What happens when the Ball leaves the left and right edge?
Well, in a Pong game, a new ball spawns in the middle towards the winning player. But let’s talk about before a new Ball is spawned. What happens to the ball that left the scene? Well, it actually stays in the game, even if we can’t see it. This causes the computer to process unnecessary data and cause it to waste resources.
We can remove the Ball in Stencyl by ‘killing’ it. Don’t worry, the Ball’s nothing more than ones and zeroes, so show no remorse.
You’re probably wondering what ‘Region 3’ is. Regions are something I added to the level that resemble the goal. As seen below, Region 2 is Player 1’s goal, while Region 3 is Player 2’s goal. Regardless, the Ball is always removed once they reach any goal.
Great, so now the Ball gets removed when it reaches a goal. Let’s talk about scoring.
When the Ball reaches Region 2, Player 2 should be given 1 point. Likewise, when the Ball reaches Region 3, Player 1 should be given 1 point. Because this score is always changing, and we also need to display it later on, let’s make each players’ score a different attribute, and increase it by 1 every time they score.
Player 1 scoring
Player 2 scoring
And that’s everything for the Ball that exited the scene. Now let’s spawn a new Ball.
For the first Ball, it is always pushed towards Player 1. But for Balls after that, they needed to be pushed towards the winning player. So let’s add code to keep track of who won each round.
I did this using a Boolean, which are true or false statements. I declared a Boolean called ‘player1Win’ which is false by default, and is set to true if, well, Player 1 won the last round. Since Player 1 loses when Player 2 wins, we can just set ‘player1Win’ to false if Player 2 wins, instead of creating another Boolean called ‘player2Win’ and setting it to true.
After that, we can use ‘player1Win’ to determine the direction where the newly spawned Ball will be pushed towards. If ‘player1Win’is true, it will be pushed towards Player 1. Otherwise, it will be pushed towards Player 2.
It is worth noting that although ‘player1Win’ is false by default, it does not become false on its own after Player 1 has scored and the Ball is pushed towards Player 1. ‘player1Win’ does not change unless we ask it to. Thus, we need to set ‘player1Win’ to false when Player 2 scores.
Note that we haven't made a condition for a new Ball to spawn yet. I used a Boolean called ‘isBallActive’, which is true by default, to track whether the Ball is still in the scene. So, when a Ball has reached a goal, 'isBallActive' will be set to false.
With that Boolean, I can make the game to spawn new Balls whenever the previous one has exited the scene. Also, because the game ends when a player scores 10 goals, I made it so that Balls only spawn when both players have a score of less than 10 ( in other words, both players have not won yet).
Final code to check for when to spawn Balls
And with all of that, I created a basic Pong Game that has 8-way-movement, prevents players from moving out of their region, prevents Balls from going off the top and bottom edge but scores a goal if it touches the left and right edge, spawns Balls after each goal, keeps track of each players’ score, and ends when any player has a score of 10. In the next part, I will talk about my steps to create powerups. Thanks for reading!
Comments