SoCoder -> Article Home -> Basic Game Engines
Created : 13 January 2009
System : Windows
Language : Blitz
Left-Right Slider PuzzleA great big explaination of a game!
Let's make a puzzle game!
First off, we'll start with a basic skeleton framework.
This is where we'll build up our gameplay.
Once everything's running nicely, we can shift this into a Game Loop, and add a titlescreen, menu and other things. But for the meantime, we just want to get the basic framework going, so all we need is a simple loop.
Most folk would've indented the inner part of that loop. I tend not to, though, as I think of Cls, Flip and the Keydown Quit thing as being part and parcel of the requirements of the loop.
Once we start adding bits in the middle, that's where we start to indent it.
Our game will be a bit like the old Milton Bradley game "Downfall", but with a bit of trickyness inspired by the recent relaunch of Krypton Factor on ITV.
Hey, why not!
The player will start with a bunch of blobs at the top, and must drop them all to the bottom.
In regular 2-player downfall, the player's moves are counteracted by the opposing player, leading to a slightly random gameplay style.
However, since our version will be 1 player only (for now..!) we'll instead make it a more puzzle based game.
Each blob will be symbolically different to the next, be it by color, shape or number.
The game will start with these at the top, and a different order of the same objects will appear at the bottom.
The player must use the area inbetween to make the objects fall in a different order, and thus produce the correct sequence at the bottom.
Here's what we'll need.
1. A few little colored blobs to fall through the playfield.
2. A moveable playfield.
3. A set of rules, possibly involving the number of moves the player can make, along with a timer.
4. A random selection of blobs, and a random definition as to which order you should have them at the bottom of the playfield.
Since we're not going to make it too complex, the nice circles in Original Downfall are just going to have to be cheated.
We'll use sliding panels, with holes in them, instead!
So, first up, lets make an array to hold most of our data.
Holes should fit into a single binary digit. (0=Block, 1=Hole)
Blitz works with 32 bit integers, but we don't need that much space.. Remember that Original Downfall only used 5 holes maximum, so lets make the game 16 blocks wide.
Vertically, lets go for about 50 spaces, so we can play with the gameplay quite a bit as the levels increase.
Open up your drawing tool of choice, create a 32x32 pixel image, and draw a grey circle.
Create a 320x320 image, copy the grey circle over and over, down the left of the image.
Into each circle, stick a number, 1-10
Then, copy these circles horizontally, so you have 10 of each.
Next, make each row a different color.. Red, Orange, Yellow, Green, Cyan, Blue, Purple, Pink, Dark Grey, Light Grey
(If you're using PaintShop Pro, Ctrl-L, Set Saturation to 255, and then do 0, 20, 40, 80, 130, 160, 195, 220, then just tweak the last two to be different shades of grey.)
That'll be our circles. 10 colors, 10 numbers, plenty of possibility.
If you want to make it trickier in the future, you can make other shapes to add extra possibilites.
Lets keep the sliders simple.. Grey for Walls, Nothing for holes..
Place that in the Init section, and it'll make us a nice simple block that we can redraw all over the place.
Now, lets try to make a slider.
Inside the Gameloop area, add the following.
Note, this is only temporary, and we'll have to tweak this as we go to become a proper bunch of sliders..
You can see we've stored the hole data as a nice simple binary line.. (The % tells Blitz we're working with a binary number)
In order to get each binary digit back, we need to convert it to a string, and access it that way.
It might seem awkward, but reading characters left to right is easier than having to do bitshifts, ANDS and other things, just to get a 1 or a 0!
That's the basic slider.
You'll notice we've indented it a little bit, so that later on we can turn y=1 into a fully formed For-Next loop, to cater for all of our sliders.
Next up, slide the slider.
Gripped will let us keep track of which slider the user's holding.. It's no good if the player grabs hold of one slider, moves the mouse too far, and ends up dragging the wrong one.
So we flag the one that they initially grabbed, and then release that flag whenever the mousebutton's released.
Nice and simple.
The Slide(y) should then be added to the slider's drawn position, so that it moves along with us.
The msx variable should be the Mouse's X Speed.
We need to grab that every frame, so up at the top of the loop, just after cls, add..
And also ensure gripped=0 before our loop begins.
By now, the code should look something like this..
Next up, we'll create a basic function to generate our holes for us.
We want everything to be in nicely lined up groups, so we'll pregenerate our hole layouts, stick it in a function, and output the results.
We say MakeHoles(5), and it returns a nice string of 5 holes.
To test this out, make a simple for loop of random strips at the Init section, and don't forget to also change the y=1 bit in the gameloop into a for y loop. (And remove the Hole(y)=%0010... line, too)
You'll now notice that the sliders aren't quite as clicky as they should be.
We need to lock each slider's position so that it clicks into a 32 pixel grid.
Take the mousedown(1)=0 line, and convert it like so..
The addition of 1616 is for two reasons.. 16 gets the center of each 32 block, so that we can slide left if it's a bit too far right, and right if it's a bit too far left.
Additionally The Mod command will go all screwy if our number's negative..
So, to ensure the number's always positive, we add 1600 to our figure.. It's a nice (32*50) number that we can be sure we won't hit.
The Settled figure, we'll use in a bit, to drop our blobs whenever the grid isn't moving.
You'll also want to add limits to the slider, so the player doesn't send it way off the charts!
Place those lines inside the main movement code, and it'll keep the sliders within our wanted area..
Your sliders, at this point, are more or less complete, so lets move on to adding the blobs..
Top of the Init section, load in our Circles image.
And, after we've generated our random sliders, place some random blobs into the topmost holes.
The main dropping and image drawing will be inside our slider loop.
Where we "; Draw blocks along slider.", add the following..
To draw our blobs in their correct places.
Within there, we need to discover what's under each blob.
If there's a hole beneith our blob, we should drop the blob into the hole.
Will tell us exactly which grid spot is below our blob.
Now, before we begin dropping blobs, we should ensure that blobs won't drop when they're outside of the allocated area of gameplay.
So, we insert an if, to check that.
Next, figure out whether the spot is a hole or a block, then check if there's anything in the grid there..
If there's a hole, and an empty grid spot, then we place our blob into the grid, and remove it from it's old position.
Blimey, that's a big line!!
Altogether, we should now have this.
And that's the basis of our game!
You can have a play with it, if you'd like.
There's really not much of a challenge there, yet though, so we'll spend the next part of this guide building up a few basic gameplay elements.
Wrap the two generator loops (up at the top) into a new function.
We'll tweak this function so that it'll make a whole bunch of increasingly difficult levels for us.
But first we need to globalise Sliders (stick "Global Sliders" up in the Init section) and then actually Call the MakeLevel function. So stick a "MakeLevel(1)" under Gripped=0, just before our make game loop.
Now, we said earlier on that we'd have our blobs start in a line at the top, so lets do that first.
Create a simple loop to create enough single-holed sliders for the blobs, then do the blob-position finder thing below that.
(Most of this can be copy+pasted from the original stuff inside the function.)
Now, we don't need the Blob finder again, but we will need to carry on and build up a bit of a level.
So, next we add some more sliders into the mix.
And last, we need to have 5 little slots for the blobs to fall into.
After that, you can delete the original code from the function, because we don't need it anymore.
Now, give it a whirl, and see if you can get the blobs down to the bottom, so they're in the opposite order.
It *should* be possible
But the player won't know they're meant to do that.. So we need to tell them somehow.
Explain it to the Player
Add an extra Dim up at the top. This will hold our "order", so that we can tell the player what they oughta be getting.
and also a second grid array where we can place the targets for each blob.
And, in our main loop, insert every new object into the Gets() array.
And underneath our Aim_Holes loop, add an extra "Blob finder", but backwards, so that it places the Gets into the right places.
Next, to draw them.
Since Blitz doesn't have any nice quick image recolouring functions, we'll have to nip back into our art package, darken the circle image, and save it as circles_dark.
Load that into Blitz
And get it drawn when it needs to be.
We draw it Before our actual blobs, so that the targets appear to be behind the blobs.
Then, to be sure the player's complete the level, we only need check that everything on Grid2(x,y) has a similar Grid(x,y)
Rather than checking if all = all else, we'll do the opposite.
At the top of the game loop, set HasAll=1 (Stick it below the msx=MouseXSpeed() line..)
This will be flagged as true, if we don't encounter anything that's wrong.
Then in your grid2 drawing piece, add the following line.
and then, right at the bottom, after the Flip, stick in the nice endgame line.
At this point, your code should look as follows..
It should be quite playable, albeit only a single level, and quite quick at quitting on you!
And, that's also where we're going to leave this little tutorial.
You can continue the game in many directions, adding multiple levels, adding extra tiles, adding a level editor, a titlescreen, scores, timers and much much more.
If you're interested, my completed game is available here, and even contains the sourcecode that you can follow through and see what kinds of changes I've made before I'd finished.
If you create any other versions of this game, let me know!