Mega Drive SGDK Megarunner

Learn how to make an endless runner for the Sega Mega Drive using SGDK! I highly recommend working through the Megapong Tutorial first, as that explains a lot of the basics of MD coding.

Megarunner 3 - Scrolling


Welcome back! Last time we drew a background with a floor and even some street lights. This time we’ll get things moving by scrolling the background to create the illusion of endless running!

Preparations

As usual, we have to do a bit of preparation work. First off we’ll define a new constant at the top of the file that will store the speed at which our background will scroll.

const int scrollspeed = 2;

Next up we’ll set our desired scrolling mode. In main(), add this line after VDP_setPlanSize(32,32);:

VDP_setScrollingMode(HSCROLL_PLANE,VSCROLL_PLANE);

What does this actually do? First of all, note that we’re giving the function two values: The first one sets the desired mode for horizontal scrolling (HSCROLL) the second one for vertical scrolling (VSCROLL). But what is a mode? SGDK (and the Mega Drive hardware) supports multiple ways of scrolling. The values that we have chosen (with _PLANE) tell SGDK that we want to scroll the entire plane at once. You could also scroll tiles or lines, which are slightly more advanced modes that allow you to create parallax effects and such. But we simply want to scroll the entire plane for now.

One more thing before we get to the actual scrolling. We will need a variable that stores the scrolling offset, which I’ll explain in a second. Define this variable right before your main game loop starts:

int offset = 0;
while(1){
    //game loop stuff
}

Keep Scrollin’ Scrollin’ Scrollin’ Scrollin’

Alright, let’s get scrolling! As you might expect, SGDK offers us a function that will handle the scrolling. Put this one right at the beginning of your game loop:

VDP_setHorizontalScroll(PLAN_B, offset -= scrollspeed);

The first argument tells the function which plane we want to scroll. Since we put our tiles on PLAN_B, that’s of course the one we want. The second argument passes in the offset that we want. This basically tells SGDK how far we want our plane to be moved: In our case, we want to move it by scrollspeed. But why are we keeping track of offset?

It might seem obvious to some and confusing to others, depending on what game engines you’ve worked with in the past. In some cases you tell the engine “I want the background to constantly scroll at speed X” and then it just happens. In SGDK this works differently! We are not passing in the desired speed at which we want the plane to scroll, but the actual distance we want it to move each frame. This means that we have to keep track of how far the plane has already scrolled, so that we can adapt that value for the next frame.

In the first frame, we have offset == 0. Our call to VDP_setHorizontalScroll subtracts scrollspeed from that, which results in offset == -2. This offset is then applied to the plane, meaning that it will be moved two pixels to the left. In the next frame, offset is reduced again to offset == -4, meaning the plane is now rendered another 2 pixels to the left (and 4 pixels left from where it originally was). So basically we have to tell SGDK every frame where our plane is currently located.

And one last thing: On the Mega Drive, planes loop automatically. Simply put, this means that any pixels that leave the left edge of the plane are automatically rendered on the right edge. This means that our background will never really move outside of the screen.

I hope that wasn’t too confusing.

Underflowing

“But wait!” I hear you cry. “Wouldn’t that mean that offset will keep decreasing forever”? Yes it does! And this is bad, because that would eventually cause an underflow and mess everything up. True, the game would have to go on for quite a while before we’ve reached the limit of what an int can take, but it’s better to be safe than sorry. So right after VDP_setHorizontalScroll(PLAN_B, offset -= scrollspeed); add the following line:

if(offset <= -256) offset = 0;

This resets offset so that it doesn’t become too small. Wonder why I picked 256? Well…try to figure it out yourself for a minute! Remember that plane size…?

Okay, I’ll tell you the answer. We set our plane size to be 32 tiles wide. One tile is 8px x 8px, meaning that our plane is 32 * 8 = 256 pixels wide. So if the plane has moved 256 pixels to the left (that is, when offset == -256), it will have moved one entire plane-length – and since it loops, it will basically be right back to where it started. So by resetting offset when it hits 256 we get smooth scrolling without any skips! (And just for fun, feel free to try out other values and see what happens).

That was a lot of theory, but if you compile the game now you should see that we have a scrolling background! Just look at it go. Feel free to make racing car noises! Neeeeoooown…

images/scrolling.gif

And here’s a question!

As you might remember we’ve only placed one streetlight in our scene…but now, sometimes there are two on screen at the same time! Do you know why? Think about it and post your answer in the comments below!

If you have any questions, comments or criticism, post them in the comments below or reach out to me on Twitter @ohsat_games! Special thanks to Stephane Dallongeville for creating SGDK and everyone in the SGDK Discord for their help and keeping the dream alive!

Download the source code

All patrons on Patreon get the complete source code for this tutorial, as well as other perks such as early access! Become a Patron!
Just Want to Buy Me a Coffee?

Check out the rest of this tutorial series!

  • Megarunner 1 - The Framework
  • Megarunner 2 - Tiles
  • Megarunner 3 - Scrolling
  • Megarunner 4 - Player and Obstacles
  • Megarunner 5 - Jumping Math
  • Megarunner 6 - Collision and Score
  • Megarunner BONUS - Tile Scrolling
  • Get Words in Your Inbox!

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



    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

    Make a Space Shooter for the Mega Drive!

    February 24, 2020
    Mega Drive Ramblings

    Patreon Revamps

    January 28, 2020
    Mega Drive Ramblings

    New SGDK Tutorial: Megarunner!

    November 4, 2019
    Mega Drive Ramblings