A brand new game
for Windows, Linux, Mac, HTML5, 3DS Homebrew and more
SmileBASIC 4 - Bad Scrolling Background Technique
25th April, 2020
I've been asked how I achieve my scrolling backgrounds, especially since (as you can probably tell from my games) I'm not using "normal" techniques.
So, let's code a quick example, and you can hopefully follow along.
WARNING : This is far from being the ideal, or even the "normal" way of drawing backdrops.
I am NOT the best tutor for programming. I've been coding far too long without getting rid of my bad bad habits, and have been working towards "many games, quickly" techniques, rather than "games coded properly" techniques.
I'm teaching terribly bad habits, here!!
Sidenote : I'm not going to show you how to "Make" your tilemap, only how to draw one onto the screen and scroll around it.
Start a new project
Load the project.
Remove the default text, and start a default project.
We'll begin by creating a "Tilemap" of size 128x128 tiles.
Before the main loop starts, we'll throw random numbers into the tilemap.
A couple of for-loops which together will wrap through all the possible positions in the map, and each one is given a number between 0 and 10.
This is a 100% random tilemap we're going to be scrolling. If you'd like to work on ways to create a proper tilemap, a handy start might be to know that the LoadV and SaveV function can load and save an entire array in a single command.
Next we'll add some variables for the Player's position (X and Y) as well as variables for Scroll and Aim.
Throw in some very simple movement code, too.
We'll draw everything with ScrollX and ScrollY subtracted from the position, and Aim our "camera" at the player.
Start by finding the spot that centers the player onscreen.
PlayerX-210 and PlayerY-120 will fix the Aim point so that the player's dead center on the screen.
Next we move the Scroll offset to gradually meet the Aim offset.
The maths here is a but quirky, but it basically takes the distance between Scroll and Aim, divides by 8, then adds it to the Scroll.
This is a very handy bit of code, and you can use this to smoothly transfer any number to any other one. Just remember "a=a-((a-b)/c)" and you'll be able to use this in lots of places.
Next, we draw the player with the new offset.
SPSet the player sprite (0) to be an Orange (1), Offset the sprite to the X,Y co-ordinate with Scroll subtracted, and set the SPHome so the sprite is drawn from its middle.
Run the code at this point, and you'll have a weird springy Orange in the middle of the screen.
This is fine!
Let's throw in a background full of sprites.
First, we'll find 4 values. The top, left, bottom and right.
The grid is going to be made up of 16x16 tiles, so we divide the position of the player by 16 pixels, and limit the values so we don't go beyond the limits of the Array.
We do this so that we're drawing a limited amount of the background. We can't draw all 128x128 tiles at once. That would be madness!
Instead, we limit to drawing only what's around the player at the time.
Next, another double-for loop, to cycle through all the tiles between those limits, and draw them to the screen.
We start the SpriteCount at 1, and then bump up the value each time we draw something.
There's hundreds (over a thousand!) sprites being drawn at any time, using these values.
Draw each sprite at the x and y value, multiplied by the tile size, and then with the same Scroll offset subtracted that we do to the player's sprite.
Note (again!) : This is very very very not optimised, but SmileBASIC can happily fling all of this on the screen at once. Probably best not to do this technique anywhere important, though!
About Sprite "Z-ordering"
Sprites are drawn lowest-last..
Since our player's sprite is Sprite 0, everything else is drawn underneath.
By default, the lower the sprite number, the "higher" on the pile of sprites it will be drawn, so will appear over the top of everything else.
Even though we moved the player sprite into position first, and drew the background second, the Priority of the lower sprite number means it shows up on top.
And that's the basics..
You can now run around a giant scrolling map.
Let's try vaguely interacting with the map, too.
Find the grid reference underneath the player, and change it to an orange, but only if it's within the Array's limits.
And that's roughly it!
You can use the grid reference to find objects within the map. Check for walls to run into, floors to land on, baddy positions and more.
Add extra values to your array (or additional arrays) to give yourself values for rotation, colour, things like that.
This is the scrolling background style that I've used in a number of projects, so far.
Petit Clampett (4LA4EX334) is a good example of this technique, allowing little Clampett to grab onto the roof, fall onto the floor, collect coins and more, all on a fairly large tilemap.
But this is far from a perfect way of doing scrolling backgrounds.
There are also issues with the above code, as is, mostly that it doesn't bother to clean up any sprites as it goes. (You'll notice this most if you scroll towards the far right)
A better way would be to use the background layers, draw to those, optimise the offset positions, draw minimal tiles and things like that.
But I'm very lazy in my AGameAWeek techniques. Basically, the quicker and easier, the better.
I apologise that this isn't a "Proper" method, and will probably write a Part II to this, explaining a better way, if there's enough interest.
For now, I hope this is enough to get you started on a journey involving a giant scrolling background!