Pong ~Part 5~ Collisions!

This is it. The tutorial you’ve all been waiting for. The tutorial that will bring everything together. The tutorial which will make you cry out in joy– OK, maybe not, I’m getting a little too excited… but seriously this is a good one.

If you haven’t read the whole series yet, I recommend starting at the beginning.

Part 1: Setting up the Project

Part 2: Programming the Ball

Part 3: The Player’s Paddle

Part 4: The CPU’s Paddle

Let’s get started.

So far, we’ve got the ball to move and bounce off walls. We’ve made the playerPaddle be controllable by the mouse. And we’ve told the cpuPaddle to move up or down depending upon the position of the ball. It’s time to turn this into a “real” game by letting the ball be blocked by the paddles.

Hit Testing

The way Flash handles collisions between two objects on the stage is called hit testing. The way it works is that Flash keeps track of invisible bounding boxes around every object on the screen. These bounding boxes are the smallest possible rectangle that your object can fit inside. So for our paddles, the bounding box is exactly the same shape. But for the ball, instead of using the circular 30px by 30px shape we drew, Flash uses a 30px by 30px square.

(This doesn’t really matter too much in our game because it is so simple but in more complex games where you have objects of complex shapes it can be a problem. There are a couple more complex ways to do perfect collision detection, but we aren’t going to worry about that yet!)

In order to check for collisions, we need to specify two objects in our game. First off let’s check between the ball and the playerPaddle.

Here is the code which will handle the collisions between the ball and the playerPaddle:

(add this into the top of the main game loop)

	if( playerPaddle.hitTestObject(ball) == true ){
		if(ballSpeedX < 0){
			ballSpeedX *= -1;
		}
	}

What this code does is it accesses the playerPaddle’s hitTestObject method inside of an “if” statement. We passed in whatever object we wanted it to check for — the ball. HitTestObject is a built-in method in Flash which will check whether 2 objects’ bounding boxes are overlapping at all. If they are, it will return “true”, and your following code will execute. If they aren’t colliding, the conditional will return “false” and nothing will happen.

Notice we added in the extra line so that it only bounces the ball back if the ballSpeedX is a negative number. This is because the playerPaddle is on the left, so we only need to bounce the ball back if it is moving in the negative direction. This little extra bit of actionscript will prevent any potential bugs in the game where the ball might get stuck repeatedly bouncing behind the far side of the paddle.

If you compile your code… voila! The ball bounces off your paddle! Congratulations, your project is gradually starting to resemble a real game.

If we duplicate that code, but substitute in the cpuPaddle for the playerPaddle, and a ballSpeedX of greater than 0 instead of less than 0, we can get the cpuPaddle to handle its own collisions too.

Add to the first set of code, so that it includes the following “else” statement:

	if( playerPaddle.hitTestObject(ball) == true ){
		if(ballSpeedX < 0){
			ballSpeedX *= -1;
		}

	} else if(cpuPaddle.hitTestObject(ball) == true ){ //add this
		if(ballSpeedX > 0){
			ballSpeedX *= -1;
		}

	}

Let’s test this out.

Awesome!

Alright, so that’s all fine and dandy, but let’s take this to the next level. In order to add some level of skill to this game — and make it possible for the cpuPaddle to lose, we are going to program a set of instructions so that the angle of the ball will change depending on what spot it collides with the paddle. If the ball hits the top of the paddle it will angle upwards; if it hits the bottom it will angle downwards; if it hits the middle it will go somewhere in between.

How do we accomplish this? By adding this code… I’ll explain afterwards.

First create a new function called “calculateBallAngle”. You can place it anywhere in the code window as long as it isn’t inside any other function. I put mine right above the loop function.

function calculateBallAngle(paddleY:Number, ballY:Number):Number
{
	var ySpeed:Number = 5 * ( (ballY-paddleY) / 25 );
	// (ballY-paddleY) / 25 will be between -1 and 1 depending on where the ball hits

	return ySpeed;
}

Note: This function doesn’t return “void” like all of those we have worked with in the past. When this function runs it calculates a Number value, which it sends back to wherever the function was called from. This Number is going to be the y speed of the ball, which we are setting to a value between -5 and 5.

In our case this will be the hitTestObject code we added earlier, so let’s go back to the main game loop and add a couple new lines to that section.

	if( playerPaddle.hitTestObject(ball) == true ){
		if(ballSpeedX < 0){
			ballSpeedX *= -1;
			ballSpeedY = calculateBallAngle(playerPaddle.y, ball.y); //add this
		}

	} else if(cpuPaddle.hitTestObject(ball) == true ){
		if(ballSpeedX > 0){
			ballSpeedX *= -1;
			ballSpeedY = calculateBallAngle(cpuPaddle.y, ball.y); //add this
		}

	}

If this looks unfamiliar to you, don’t worry. What we’re doing is every time the ball collides with one of the paddles, in addition to changing the x velocity of the ball, we are setting the y velocity of the ball to the results of our calculateBallAngle function that we just added. When we are checking for collisions between the playerPaddle and the ball, we pass in the y values of the playerPaddle and the ball to the calculations. When we are checking with the cpuPaddle, we use that y value instead.

Run your code one last time.

Beautiful.

Well, there you have your basic Pong game. We accomplished our 3 main goals we set in Part 2: programming the mouse-controlled playerPaddle, the AI-controlled cpuPaddle, and programming the ball and its collisions.

Grab your copy of the source code HERE.

But don’t stop now, there is still so much we can do to make this game better! In future tutorials we are going to at least look at adding a scoring system, a main menu, and a win/lose capability.

Please, please, please, leave me a comment! This is my first series I’ve done and I greatly appreciate any feedback. Is there anything I can do better? Am I easy to understand? Am I going too slow or too fast? Also, if you have any suggestions for future tutorials, whether it be adding on to our Pong game, or a suggestion for another series, let me know in the comments, or email me at: AS3GameTuts@Gmail.com.

Thanks for sticking with me for the bulk of this tutorial series, I hope you’ve enjoyed it and found it useful! Continue to Part 6.

Ben

64 comments on “Pong ~Part 5~ Collisions!

  1. Devon says:

    Thank you, Ben. This was a very informative method, I’ve been working on my recreation of Pong for a few days now and all other tutorials get into packages and public functions, which I unfortunately don’t understand how to setup just yet. So thanks for leaving those out :P

    For the most part it’s all easy to understand, the only issue I’m having would be to create the scripts myself (reading and writing are two very different things). So I don’t think you’re doing anything wrong.

    I’ll be waiting for the Scoreboard tutorial! (No idea how to do that one without public functions). Keep it up.

    • Ben Reynolds says:

      Thanks for the comment, I’m so happy it helped! I try specifically not to get caught up in “packages and public functions” and just write code that’s easy to understand, so I’m glad you like that style. The scoreboard tutorial will be finished soon. Cheers!

  2. Hi, even though I did not read most of the information on your site, but I think your site is really impressive and highly technical. I think, if the game ideas are your original invention you must expect some great returns. Good job !!!

  3. Michael says:

    Thanks man I’ve been really wanting to understand and begin coding with actionscript, you just made my journey a hell of a lot more simple. GREAT GUIDE! Keep going! This is great and easy to understand and you cover everything with enough detail to understand easier. And the pictures help alot as well :) You should contact me I have some questions about making a Tower Defense game that’s really my goal to do in ActionScript 3.0, Thanks and again GREAT TUTORIAL!

  4. Colin says:

    Awesome tutorial! I am a decent programmer but new to flash and this was neither too fast nor slow.

  5. ashwin says:

    Hi Ben

    Your tutorials are really really helpful and great. The pong game series is very easy to understand and the maths is very clear too. I just have a silly doubt . How did you arrive at the math behind the calculateBallAngle function?? What i mean is the value returned by Yspeed to be between -1 and 1,is it intuition or any trial and error way to know the values??

    Your tutorials are too good, waiting for your platformer series.
    For any tutorial suggestions, could you teach more AI in flash Games??

    • Ben Reynolds says:

      I have to admit that the basis for the math behind the calculateBallAngle came from a tutorial I read years ago on FlashGameTuts.com (my inspiration for this site).

      If you want to know the thought process behind the equation…
      5 * ( (ballY-paddleY) / 25 )

      Well, we want the ySpeed to be greater if there is a greater difference between the y positions of the ball and paddle, so I started with (ballY-paddleY). To convert this difference into a number between -1 and 1, I divided this number by 25, which is half the height of the paddle. Finally, I wanted the ySpeed to be more powerful than just -1 to 1, and after a bit of trial and error I decided to multiply by 5 at the end to modify the total magnitude of the new ySpeed.

      As for the AI request, yes, I can try to include some AI tutorials in the future. I’m not completely an expert on the subject myself, but I can at least go through some basics.

      • ashwin says:

        Hi Ben thanks for the explanation understood the maths behind it. If the AI tutorials would seem advanced then could you help us with math and physics used in Games like concepts of trigonometry and such.

        thanks for your wonderful tutorials. I hope you continue in this kind endeavor of yours.. As always wishing you the best.

        Cheers

  6. Hi Ben. Tnx for the tutorial but I have a doubt. In your calculations you devided the value by 25 and then multiply it by 5. Why not directly devide it by 5?

    • Ben Reynolds says:

      You are definitely right, I could have just divided by 5. I left it the way I did because it’s easier for me to read later and understand why it works. Sometimes when you code you need to decide between efficiency and readability.

      If you are wondering why that line does what it does, here is what I wrote to another commented who asked:


      If you want to know the thought process behind the equation…
      5 * ( (ballY-paddleY) / 25 )

      Well, we want the ySpeed to be greater if there is a greater difference between the y positions of the ball and paddle, so I started with (ballY-paddleY). To convert this difference into a number between -1 and 1, I divided this number by 25, which is half the height of the paddle. Finally, I wanted the ySpeed to be more powerful than just -1 to 1, and after a bit of trial and error I decided to multiply by 5 at the end to modify the total magnitude of the new ySpeed.

      Hopefully this clears things up! :-)

  7. Lars says:

    This is a great site and a good torturial it helped me alot. Thanks!

    How abot adding 2 players?
    Make the CPU an arrow keys controld player?

  8. Ananth says:

    You are a gifted instructor. There was so much clarity in the explanations. Enjoyed going through the tutorial. Learnt it at one go and learnt quite a few concepts as well.
    Thanks

  9. Max says:

    Thank you sooo much Ben!
    Your tutorial has finally given me some inspiration to learn Flash, something I wanted to do a long time ago!
    Your way of explaining is very good and I have no problems understanding the tutorial!
    The code is a bit comlicated, but it is not your fault.
    Please keep making tutorials like this, because I seriousley am learning a lot from you :)
    Thanks again,
    Max

  10. Matt says:

    Hey, thanks a lot for this tut Ben!

    I used to mess around with Flash back when I was 13 or 14 but stopped after being unable to grasp the coding language. Now that I am in my last year of high school and am looking at a future in game design, I am seeking to eventually handle AS proficiently. Logic and syntax is somewhat carried over from my experience with Python and GML, but AS is still a whole different language. This tutorial has been really helpful in sliding into the syntax of Flash and I am looking forward to future stuff you will release.

    Again, thanks a lot.

  11. David says:

    Amazing thank you fur de tuts

  12. Betsy MacDonald says:

    Hi Ben,

    This is exactly what I’ve been looking for. I teach basic animation in Flash to MS/HS kids and wanted something with a bit more bit for those that wanted more of a challenge. This is challenging enough with a great pace to keep them from getting frustrated. I will continue to use it with them next year. Thanks a lot.
    Betsy

  13. Pong says:

    Thank you Ben. I’ve just started my Flash journey after months of working with Multimedia Fusion and Game maker only to discover they weren’t flexible (or supported) enough for my needs. I’ve looked up countless tutorials on YouTube and on Google search, but none of them have been able to teach me what I need until I saw your. Once again Thank You!

  14. Sahl says:

    Thank you so much Ben. This was easy to follow in addition to being clear. Pictures helped alot and it was going at a great pace. I have a background in java and that made it easier. However, the math part in the calculateBallAngle method had me thinking for a while lol. Great tutorial I hope you would include more explanation about AI.

  15. Shanmuga Sundar says:

    thanks man!! this was a great !!

  16. G13 says:

    You’re Genius!! Thanks man!

  17. Plamski says:

    Ben, your tutorials are better than the video tutorials in YouTube. Well done! Best! Thank you!

  18. FlashNewb says:

    Really nice tutorial Ben. Helped a complete Flash newb understand ActionScript 3 basics. 10/10

  19. Bitstream says:

    I really appreciate these tutorials. They’ve been a great help to me so far, and I can’t wait to move to on to the platformer tutorials.

  20. Bruno Montibeller says:

    Man, you’re awesome! Thank you sooo so much to teach us how to create games like this. I’m really excited about this!

  21. xtian says:

    Hi , can you make tutorials on how to create a angry birds like game thanks ,
    this is an awesome tutorial for beginners like me :) i need to learn a lt more specially in Game with Physics engine , TIA!

  22. Jesper Christoffersen says:

    Hi Ben,
    Thanks for a great tutorial! :) I got one question for part 5, though. I see this calculateBallAngle function works fine for me and I seem to understand the principle behind the math – but not entirely the coding. (ballY-paddleY) has a value between -25 and +25, right, but how does the program actually find this value instead of crashing by refering to “paddleY”?? I mean, we have no such instance name (“paddle”) – only “playerPaddle” and “cpuPaddle”?

    Thanks in advance and keep up the good work :)
    Jesper

    • Kevin says:

      I’m also curious about this. And also, thank you for the otherwise incredibly useful and easy-to-follow tutorial.

      • Ben Reynolds says:

        You’re welcome for the tutorial :-)

        The variables paddleY and ballY are defined in the function header:

        function calculateBallAngle(paddleY:Number, ballY:Number):Number

        Basically, this means that we can pass in 2 parameters when we call this function. These parameters will automatically get assigned to the paddleY and ballY variables.

        So if I write: calculateBallAngle( 200, 100 );
        it will set paddleY to 200 and ballY to 100.

        We never formally declared these two variables, because they only need to be accessed from within this one function.

    • Ben Reynolds says:

      You’re welcome for the tutorial :-)

      The variables paddleY and ballY are defined in the function header:

      function calculateBallAngle(paddleY:Number, ballY:Number):Number

      Basically, this means that we can pass in 2 parameters when we call this function. These parameters will automatically get assigned to the paddleY and ballY variables.

      So if I write: calculateBallAngle( 200, 100 );
      it will set paddleY to 200 and ballY to 100.

      We never formally declared these two variables, because they only need to be accessed from within this one function.

  23. Les says:

    Great tutorial

    This is my first attempt at action script and found it very easy to follow. Great Job. Gonna go read all your other stuff now!

  24. anbumani says:

    its informative ……n I m new to acion script n all……..it s very easy to learn …………..thank u for this info tutorial…..

  25. raco says:

    Awesome tutoral. You have just give me a brake of those stinking AS3 classes. I realy enjoyed to do things like in AS2. Tutorial is easy to understand and you describe everything so there rly is no answers left.

    I have a problem just at the end of this tutoria, with who am am not familiar. Do you have any clue? (im using CS5). if u need i can send u the whole file.

    98 function updateText():void{
    99 playerScoreText = (“player: ” + playerScore);
    100 cpuScoreText = (“cpu: ” + cpuScore);
    101 }

    Line 99 1067: Implicit coercion of a value of type String to an unrelated type fl.text:TLFTextField.
    Line 100 1067: Implicit coercion of a value of type String to an unrelated type fl.text:TLFTextField.

  26. haris says:

    dats realllyy nice thanks alot

  27. Advery says:

    I LOVE it! So much help for me, i’m a beginner and it’s so nice to learn it step by step :)

  28. Fer Raviola says:

    Great! awesome tutorial!. You’re not going too fast, you’re not going too slow.. it’s just perfect. I love it. Thanks.

    One request though: could you make a quick tutorial on how to port this into andoird?. that’d be great.

    Keep on the good work. :)

  29. ribbs23 says:

    Hi, just started with your tutorials and am very impressed with the content, I have done a little programming before but your tuts are very well done and easy to understand. I am looking forward to going through all of them. Keep up the good work, will come back with suggestions when I’ve gone through more.

    Thanks

  30. filmon2 says:

    wow I feel like a late replier but just finished this tutorial. As everyone has already mentioned great site, great tutorial and keep it up. I encourage everyone following the tutorials to really do what Ben mentioned, that is, plot out what it is you want to do conceptually and then actually try it out yourself and fail miserably. I can’t stress how much that’s helped me. I’m sure Ben your knowledge is deep due to multiple times of scratching your head and wondering “why”. Curiosity and questions is the mother of knowledge so it’s not necessarily good enough to just follow the tutorials but rather proceed them a little, make mistakes and have fun, customize the game and share our experiences. I made my version increase the x speed every time the user returned the ball successfully so it got harder and faster as you returned the ball :)…you should stop at a certain speed though or it gets way too fast but mostly by that point the AI can’t keep up anyways. Thanks again for the tutorials Ben, great work.

    • Ben Reynolds says:

      Thanks for the feedback and the encouragement! I love your thoughts about curiosity and experimentation — that is exactly what I have done, and I definitely recommend it to my readers.

  31. Ratzyy says:

    Amazing tutorial!
    This is the first tutorial i understand completly! I love your declarations for nearly everything.
    But i do not understand the following code:

    function calculateBallAngle(paddleY:Number, ballY:Number):Number
    {
    var ySpeed:Number = 5 * ( (ballY – paddleY) / 25); // ballY – paddleY)
    return ySpeed;
    }

    paddleY = any Number and ballY = any number?
    But how does the program knows what paddleY and ballY is?
    Can you explain it for me? :)

  32. Hassan says:

    Brother Ben , I want to know what is the relation between ySpeed with the angle , didn’t get it well. :)

  33. Bijay Mishra says:

    Nice tutorial indeed!

    it would have been more nice if the mathematics of this — 5 * ( (ballY-paddleY) / 25 )—- would have been explained

  34. Johanna says:

    Excelente tutorial !!!
    Tenes otros ??

  35. Mark B. says:

    Ben, absolutely fantastic. Thanks for a great tutorial. This tutorial is two years old. Do you have newer tutorials for the latest versions of Flash/AS3 (and frameworks like Stage3D)? It seems like the preferred way to go now is to use Flash Builder. Your thoughts?

  36. Carlos says:

    All i Can say is You save My Time. Money and Power =)) Thankyou very much

  37. chema says:

    Excelent tutorial Ben. This has more than three years and still be very useful.
    My congratulations and I am very eager to see the other tutorials

  38. Eric Feldberg says:

    Awesome tutorial. Very clear and simplistic. Great job!

  39. Alexander says:

    Incredible man!!! I made my game in 20 mins) without any MC on the stage) using custom class) it’s very cool, please continue write new lessons, it’s very interesting for me and for all users i guess! Thank you!

  40. Be Marym says:

    hi ben , thank u so much you r such a great teacher ,, keep it up

  41. Troy says:

    Hey Ben,

    What if I want to make the left paddle as a user paddle and the right paddle as the cpu paddle? I tried it at my own by exchanging the instances name,i.e.of the user paddle and the cpu paddle. But what actually happened is that the ball only gets hit when it collides the paddle from the bottom side instead of the front side.

  42. SiCong says:

    I have little prior programming experience and I am new to AS3 but the syntax of this scripting language looks very friendly and simple. What makes it even better is your tutorials. They are amazing! I really appreciate your work and I’m glad to have found this website.

  43. LarsOlsen says:

    Hi Ben
    Great torturial! This torturial has really helped a lot! I’m completely new to programming and i’ve still managed to create a game, all with your help… this is AMAZING!
    I can see that the activity on this site might have gone down a bit before i found it, but i hope that you will keep up this page, because its extremly helpfull to us who want to start progamming :D
    Two things i would’ve liked to see is a distance game with upgrades and stuff, and a torturial whar you give codes where you have deliberatly made errors for us to fix… almost like a test… i believe that it would be extremely helpful to be able to identify errors faster.

    Thank you for helping me into the world of gamecreation, a place i have wanted to be a part of for more or less a decade now :D

  44. Moses says:

    Hey there, thank you very much Ben for this great tutorial :)
    There’s one point that I’m not sure of though, I’ve seen a few people wonder about it. It’s about the line:

    function calculateBallAngle(paddleY:Number, ballY:Number):Number

    Some have been wondering about how the program doesn’t crash and how it knows what “paddleY” is, even though “paddle” was never mentioned in the program, just “playerPaddle” and “cpuPaddle”.
    I was able to understand your explanation after a while, but at the beginning I felt a little confused.
    I would just like to clarify what you said, so it’s more easily understandable.

    Now, I’m an absolute beginner, so I’m not at all sure about what I’m saying, but; it seems that in the line, it’s saying: “Whenever the calculateBallAngle function is activated, I’m expecting to see 2 numbers; the first number will be in paddleY’s place, and the second number will be in ballY’s place” as in, “paddleY” and “ballY” are names just for clarification; if you renamed them, the program still wouldn’t crash.
    And so, when we run the function, we’re taking paddleY’s place:which is a number, and putting playerPaddle.y or cpuPaddle.y in its place, just as we replace ballY with ball.y .

    When you type in the line “function calculateBallAngle(paddleY:Number, ballY:Number):Number”, it’s as Ben said, you’re starting a variable called paddleY and ballY. And so, when replacing them by running the function, it’s like you’re telling the program: “var paddleY=playerPaddle.y” and “var ballY=ball.y” (Just for example, I’m not saying that literally typing those lines would get you any joy-inducing results).

    I hope this helped, and I very much hope that what I said wasn’t a plain wrong mess :s

  45. Thanks for the excellent tutorial series. I had tried one of these pong tutorials some time ago, but the final result was full of glitches (in the author’s code AND my own). Now that I’ve had enough AS3 experience, I’ve looked at this again with fresh eyes, and have found many ways to expand on it to give it my own personal touch. Thanks again!

  46. this is best tutorial i’ll ever seen , and trust me i have many tutorials watched

Leave a reply to Moses Cancel reply