As I said in my previous post, it's all about planning and organization -- when it comes to the planning and building the code, I like to use the WWH model instead of more complex (and time wasting) things like flowcharts. WWH means "What (variables), What (do we need to do with them) and How (do we do it).
I also like to use good naming practices -- thankfully cBasic lets you use meaningful names on items, and allows periods in your variable names to be used as space replacements. There's a very good article on the IBM linux developers site I like to point people at:
http://www.ibm.com/developerworks/linux/library/l-clear-code/
It's talking in C, but the lessons you can learn from that page apply to most every modern language... Of course if you are in mBasic or rom basics where you can only use one letter names for variables, well -- you are best off just REALLY documenting everything really well as you go along.
Moving on -- The first step is very simple -- WHAT information do we need to track. (variables)
For a game like this the biggest element will be the game map -- this would obviously make a nice two-dimensional array; assuming the language you are using supports two dimensional arrays. (Not all basic flavors do, cBasic does, I think mBasic does). We probably don't need anything more complex than integers for the locations, Some people would try to track it in video memory but as a rule that is even more work and video memory is slower than system ram. An 80x24 array is going to suck down memory like a pig, but there's not a lot you can do about that... though I would strip a line off the top and a line off the bottom for showing non-gameplay elements like score and lives left.
So we dim an array
dim playfield%(80,22)
What fills that array? Well, best practice is to define some named variables to say what each value in that array means. (mind you in Pascal these would be CONST, not variables... in C they would be DEFINE's)
playfield.empty=0
playfield.floor=1
playfield.ladder=2
etc, etc, etc... that way we aren't always guessing what our numbers mean. Thankfully with cBasic being compiled these don't suck all that much overhead and we can use names as long and as clear as we like. If we were talking mBasic, you'd still want them in variables as variables are faster than immediates in an interpreted language, but you'd be stuck with one letter names (making you run out of variables VERY quickly).
Then you have the various elements on the screen that are moving around -- the sprites. Even using characters as sprites the name 'sprite' works best for this. What values do sprites have? Well, there's the x and y coordinate of the screen, the previous x and y positions, the direction it wants to move, the direction it is actually moving, and what character code should be displayed for it. (or tile number in a graphics game)
How to handle that? Best bet is also an array. Let's say you are going to have four barrels max on screen, and the player. Storing them all in the same array lets you use one tight loop to show them on screen instead of iterating through each one with a different piece of code. I would make this a one dimensional array and use a offset.
So, we dim another array, setting up some values to calculate it's size.
sprite.count%=5
sprite.x%=0
sprite.y%=1
sprite.old.x%=2
sprite.old.y%=3;
sprite.inputDirection%=4
sprite.direction%=5
sprite.tile%=6
sprite.variableCount%=7 / x,y,old.x,old.y,inputDirection,direction,tile
dim sprites%(sprite.count%*sprite.variableCount%)
and some values to index it with.
sprite.player%=0;
sprite.barrel1%=1*sprite.variableCount%;
sprite.barrel2%=2*sprite.variableCount%;
etc, etc...
That way in your code, to access a sprite's y position for example you would just refer to it as:
sprites(sprite.player+sprite.y)
Which believe it or not is faster than letting it do the multiply in realtime for a two dimensional array.
Which is basically using an array to replicate some of the functionality objects or even records/structs bring you in more modern languages.
From there you have things like score, high.score, lives, max.lives, starting.lives, points.to.gain.a.life, etc, etc.
It is always easier to figure out what information you need to process before you lay down a single line of code to process it.
THEN on to the next step, WHAT are we doing with it?
Figuring out the central loop of your game code sounds simple -- and it is if you take the time to break it into smaller tasks. This is where MANY programmers screw it up as they will try to do everything on every single loop, or they will just put it all together in any order or do everything for a single screen element before moving on to the next one. This does not translate well when you get into more advanced programming relying upon timers, does not translate well if you use co-op multitasking internally or timer breakups -- and in general ends up a bit slopppy.
For my games, I always grouped like tasks into groups even if performed on different elements... so my breakdown of "what we're doing" ends up thus:
update the screen -- go through every sprite with a for loop and erase old.x,old.y and draw at x,y. By doing screen updates on their own we avoid 'flicker' type issues and do all of our screen interctions in one fell swoop. I do this first so that on the first time throug the loop everything is drawn.
Check inputs -- once we've drawn the old stuff, we want to read in any changes the user wants.
AI Logic these do basically the same thing as checking inputs, just for the elements the player does not control. This can actually be the most complex of things to do given it's often endless nested IF statements.
update positions -- take our inputs, compare them to the playfield to see if they are valid moves, if they are, change 'direction' to match and then do it. If they aren't, check the existing direction to see if it's valid, if it isn't stop moving, otherwise keep going.
check sprite collisions -- usually in games bad things happen when certain sprites collide, or good things could happen (like eating a super-power pellet in pac-man). Since we moved everything to it's position, it's now time to test for those events.
That's basically the top level of inside our loop -- from there we have to ask what other actions could occur. Classic 'other events' would be things like scoring points or losing a life. Instead of wasting time redrawing the number of lives and the score on every loop of the game logic, we just call a routine to redraw just those parts when it happens. This helps distribute the load and keep the game running as smoothly as possible.
Which covers the basic What/what -- just leaving "how"... and for how, well.. that's when you need to start writing real code.
Which I don't have the time to explain right now.