In this tutorial series you will learn how to make a simple single-player Pong-like game for the Sega Mega Drive using SGDK! If you just want to see the full source code, you can get it from Github.

Megapong 7 - Collisions

Posted September 30, 2019

It’s physics time! We got two moving parts, now it’s time to smash them together. SGDK has built-in collision stuff, but we won’t need that for this simple project. The method we’re using to handle collisions is called AABB collision detection. It uses axis-aligned bounding boxes, which sounds really fancy, doesn’t it? Basically that just means we’ll be using rectangles to check for collisions, instead of the actual sprite graphics. It’s a very simple and efficient method of handling collisions. You can check out an interactive demo here.


We will stick our collision code in moveBall(), as it makes the most sense there. Put it after checking for the screen bounds, but before applying the ball’s velocity. Let’s start by checking the x positions:

if(ball_pos_x < player_pos_x + player_width && ball_pos_x + ball_width > player_pos_x){
	// do things

It might seem a bit tricky at first glance, but it’s actually very simple once you get it. What we’re doing here is

  1. checking whether the left edge of the ball is to the left of the right edge of the paddle.
  2. checking whether the right edge of the ball is to the right of the left edge of the paddle.

There can only be a collision if those two conditions are true! Otherwise the ball wouldn’t be in range of the paddle, but would fly past it left or right.

That takes care of the horizontal check. Now we need to check the vertical coordinates. We’ll end up with the following:

if(ball_pos_x < player_pos_x + player_width && ball_pos_x + ball_width > player_pos_x){
	if(ball_pos_y < player_pos_y + player_height && ball_pos_y + ball_height >= player_pos_y){
		// do things

The logic is the same as with the horizontal check.

If both of these if-statements are true, then we definitely have a collision on our hands! Now we just need to code what should happen in that case, which is the same as when the ball hits the bounds of the screen. The entire collision code now looks like this:

/*Check for collisions with the player paddle*/
if(ball_pos_x < player_pos_x + player_width && ball_pos_x + ball_width > player_pos_x){
	if(ball_pos_y < player_pos_y + player_height && ball_pos_y + ball_height >= player_pos_y){
		//On collision, invert the velocity
		ball_pos_y = player_pos_y - ball_height - 1;
		ball_vel_y = -ball_vel_y;

If there is a collision (that is, when the collision rectangles of both sprites overlap), we want the ball to bounce off. To do this, we simply invert the vertical velocity of the ball. But: Just to be safe we first place the ball one pixel above the paddle to prevent issues, such as the ball getting stuck inside of the paddle.

And that’s pretty much it! Collision handling is a rather complex and tricky subject, but for a simple game like this it’s not much more than basic geometry. Compile the game and rejoice in the fact that our game now has some actual gameplay!


We’re almost done! Now we just need to add more stuff to make it more game-like, like score and a game over state. Thanks for reading and until next time!

If you've got problems or questions, join the official SGDK Discord! It's full of people a lot smarter and skilled than me. Of course you're also welcome to just hang out and have fun!

Download the Project Files!

All patrons on Patreon get the complete source code for this tutorial, as well as other perks such as early access! And Patreon support also ensures that I can keep working on tutorials like this one. Become a Patron!
Just Want to Buy Me a Coffee?

Check out the rest of this tutorial series!

  • Megapong 1 - Hello Mega Drive World!
  • Megapong 2 - Setting Up The Environment
  • Megapong 3 - Importing Resources
  • Megapong 4 - Palettes
  • Megapong 5 - Sprites
  • Megapong 6 - Input and Paddles
  • Megapong 7 - Collisions
  • Megapong 8 - Score and HUD
  • Megapong 9 - Game Over
  • Megapong BONUS - Flashing!
  • Get Words in Your Inbox!

    Be oldschool and sign up for my newsletter to get updates! Just enter your email address, prove you're not part of Skynet and you're good to go!

    Powered by CleverReach. I will not send you spam or sell/give your email address to someone else.  You can of course unsubscribe at any time. By clicking the subscribe button above, you confirm that you have read and agreed to our privacy policy.

    By using the Disqus service you confirm that you have read and agreed to the privacy policy.

    comments powered by Disqus

    Related Posts

    HaxeFlixel Tutorials!

    If you’ve popped over to the tutorial section recently you might have noticed that I’ve added my very first HaxeFlixel tutorial! It shows how to implement a simple, pixel-perfect 2D water shader which I used for Go! Go! PogoGirl. But a few of you might be wondering what a HaxeFlixel is. Well, it’s a 2D game framework that is as powerful as it is underrated! It runs on the (also underrated) Haxe language, is extremely well documented, open source, and has built-in functions for almost anything you’d need.
    Read More

    Streets of Was

    As I’m sure many of you will remember, the original Streets of Rage for the Mega Drive had multiple endings. The real canonical ending has you beat the crap out of Mr. X, thereby ending his reign of terror forever (yeah, right). However, if you confronted Mr. X with a buddy in tow, a new possible path unlocked. A quick refresher is in order. When you confront Mr. X he will ask you to join his organization.
    Read More

    Streets of Rage 2 Design Docs

    A few years ago, Yuzo Koshiro posted a pile of old game design documents for Bare Knuckle 2 aka Streets of Rage 2 on the Ancient blog to commemorate the release of Streets of Rage 2 3D on the Nintendo 3DS. These documents gave a deep insight into the game’s inner workings, technical aspects, designs and even some cut content. They were an awesome resource for one of the most awesome games ever created.

    Read More