My First Game – Part 7: Pong – The Ball

Now that we have two paddles that can be moved, we will need a ball. Here’s what the ball needs to do:

  • The ball always starts at the middle of the screen.
  • The ball automatically moves when the round starts.
  • If ball touches the top or bottom of the screen, bounce it
  • If ball touches the paddle, bounce it
  • If the ball touches the left or right of the screen, restart the round.

Note that we will not handle player scoring (when ball touches left/right side of the screen) yet, because that would be defined under game rules rather than the ball’s characteristics. Okay so let’s begin!

First, we create a new Haxe file, Ball.hx, in the source folder. Again, we copy the template FlxSprite  code from the cheat sheet page into Ball.hx , and rename the class to “Ball” to match the file name:

Similar to Paddle.hx , we add a piece of code to set the image of the ball — in this case, a circle instead of square:

In the code above, we use makeGraphic  to create a white square that is sized 30×30. Then we use FlxSpriteUtil  to draw a green circle at (X=15, Y=15) position within the square, at 15-pixel radius.

Note the  0xFF00FF00 . It’s hex code for the color — the first two digits being the opacity (00 being complete transparent, FF being completely opaque), and the last 6 digits represent the RGB (Red, Green, Blue) values.

Note that FlxSpriteUtil  only draws shapes rather than create shape objects, thus the need to draw a square before drawing a circle.

Now that we have the Ball class, we have to add it into the game, similar to the paddles. Go back to MenuState.hx  and add the following code into create() :

If you test the game now, you’ll have a green circle (with a white box behind it), but it doesn’t move. Let’s give it some movement by setting its velocity:

Now the ball moves, but it disappears off the screen. We need to bounce the ball when it hits the screen bounds. Let’s add some code to do that in update() :

In the code above, if the ball hits the upper or lower bounds of the screen, we invert the y-velocity to simulate bouncing. Then, it checks if the ball hits the left or right bounds of the screen — if it does, we reload the screen by using switchState() .

If you test the game now, you will notice the ball bouncing correctly — but it goes through the paddle. We need the ball to bounce when it hits the paddle too.

To do that, we add a new function and variable in Ball.hx  — which we will access from  MenuState.hx  later:

In the code above, we have a class variable hitPaddle  to store a reference to the paddle that the ball has bounced against. Why do we need to store a reference of the paddle? We’ll get back to this in a bit.

Back in MenuState.hx , we add two lines of code into update() , to check for collision between the ball and the paddles:

Note the third parameter, onHitPaddle  is a callback — when a ball overlaps a paddle, the callback function will be executed. Let’s write the callback code into MenuState.hx  as well:

If you’re wondering how the callback function is written, you can check out the HaxeFlixel API for overlap() :

http://api.haxeflixel.com/flixel/FlxG.html#overlap

Note the thisBall.bounce(thisPaddle) — Remember we talked about storing a reference of the paddle when the ball bounces of it? Logically, the ball would invert x-velocity once it touches the paddle. Unfortunately, the ball may overlap the paddle for more than once (e.g. it overlaps for 2 or 3 frames). This would make the ball invert its x-velocity indefinitely because its body is still overlapping the paddle.

If you want to see this “bug” in action, you can just remove the following highlighted code from Ball.hx and test the game:

As such, to prevent the bug, we store a reference to the paddle, which is like saying “I’ve bounced off this paddle before. If I’m bouncing off it again, I don’t need to invert my x-velocity“. It’s not a fool-proof way, but it works for Pong.

Now, if you test your game, it should bounce back and forth between the paddles correctly, and reset the stage of it goes beyond the left or right side of the screen.

ss6

Yes, it’s a little rough on the edges, but right now we’re only concerned with making a playable game. We can always polish the graphics or handle the ball-bouncing code more elegantly later on.

In the next post, we shall handle player scoring. It’s not going to be overly fancy — so it’ll be fairly quick. 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *