Hello and welcome to to the Beginners guide to BASIC! Are there some amongst you who have always wanted to have a go at writing something with BASIC but never got around to it for whatever reasons (like playing Sabrewulf for instance)? Or some of you who have returned to the “scene” to find that you’ve forgotten all that you knew about the good ol’ ZX Basic? Or maybe you are a fresh faced youngster who would like to know what this BASIC thingy is when everyone else is talking about C++ and C#?
If you fit into one of the above categories then you’ll like what’s coming up, if not, well you best get back to your game then and try improve your high-score!
Right. Are all those sods gone? Good! So are we comfortably sitting with some music in the background and a pint of good beer at hand? Yes? Let’s get the ball rolling then!
To keep things interesting and informative I think the best way will be a “hands-on” approach. What we are going to do is to write a game from scratch, learning concepts and techniques as we go, and I’ll explain not only how to write bits of it but also why we are doing it the way we are doing it. And the game I’ve chosen for this purpose is the rather excellent (and completely crap – Ed) game “Dash-it” written by a rather excellent fellow by the name of “Arjun” by some spooky co-incidence. Why? Well apart from the fact that I’m biased towards it for obvious reasons, it is also a short game with a simple design and is relatively easy to implement. It’s also included as an example program with BASin so you already have the full source code for reference, if you can’t be bothered to type-it all in again – although I would strongly recommend that you do so.
This rather nicely brings me to BASin, which in case you didn’t know, is a full featured IDE (Integrated Development Environment) to develop programs for the ZX Spectrum. There is a review of it somewhere in this edition of ZX Shed that lists its features, so I won’t describe it further except to say that we’ll be using it heavily since it makes life so much easier. If you don’t know first thing about BASin, don’t worry, I’ll explain bits of it too as we go along.
“Dash-it” is a simple game that is a variation on the popular “snake” game. The aim of the game is to eat the dots without crashing into the blue trail that you leave behind. A timer counts down the time on the top left, and once it reaches zero, you are thrown into the next level with even more dots to devour! Finally, there is a force-field around the playing area, and crashing into it will cause the player to lose a life.
So that’s the game design (if I can call it that!). From the game design we can derive the following essential elements that will make up the game:
1) A player sprite that can be moved around by the player.
2) Dots that the player must collect.
3) A force-field that defines the playing area. Colliding with it causes loss of life.
4) A timer that counts down to zero.
5) A blue trail that the player must leave behind as the sprite moves around. Colliding with it causes lose of life.
With the above simple foundations in place, we can always extend the game if we want to (and we will).
Well that’s the core of the game. What other stuff could we want in the game? Hmm… let’s see. How about an instructions screen, a way to redefine the keys, and a credits screen (just like in professional game!)? That way, anybody new to the game can read the instructions on how to play the game, change the keys to suit his or her taste, and maybe have a look at the utterly cool people that the author wishes to thank for some reason!
The logical way to go about it would be to code the “features” as separate sections in the game that exist more or less independently of each other. We can then code the game one section at a time, adding and revising individual sections anytime we want. Typically, one would code the core of the game first then add in the other “features” one at a time. However, in our case, since this is a tutorial and since our wanted features are technically easier to implement and understand, we will code them first and then move on to the actual game core.
As already mentioned, our features will be individual sections of the game. Think of the game as a house, and the sections as individual rooms. Every room stands independent (more or less) of each other, but together they make up the entire house. Similarly for our sections! Going by that logic, our instructions, credits, key redefinition and the actual game can be divided into individual sections. In programming terminology they can be thought of as sub-routines.
For example, in Dash-it I have coded the instructions as a sub-routine that exists from line 9000 to 9070. Lines 8300 to 8380 is the credits sub-routine; lines 8400 to 8540 is the key redefinition sub-routine and finally, lines 4000 to 6000 is the actual game. As you can see, what I have done is carve up the program into logical code blocks. Let’s examine one such code block to understand this sub-routine business:
8300 REM *** Credits *** 8310 CLS 8320 PRINT "Dash it! was originally written": PRINT "especially for the CSS Crap ": PRINT "Games Competition 2004.": PRINT '"This version is an updated one ": PRINT "with some bug fixes and sound!": PRINT "It's still crap though! 🙂 " 8330 PRINT : PRINT "Developed on the BASin IDE written by Paul Dunn." 8350 PRINT : PRINT "Hello to all WoS regulars (and irregulars) and to folks at CSS.Speccy forever! Amen." 8360 PRINT #0; INK 5;" www.yantragames.com “ 8370 PAUSE 0 8380 RETURN
BASin Tip: For the code, you can do either of the following in BASin: type it in, or load the existing code from hard disk. To do the latter, simply choose the LOAD option from the File menu option, navigate to EXAMPLES > BAS Files> CSGCC and choose ‘Dash-It!”. If you go the typing route, make sure you enter the line numbers exactly as you see them here or unpleasant things will happen shortly (like the program not running as it should)!
Hey, there is English in some of the lines of code! There is hope yet eh? A pity you can’t write an entire game in BASIC using English statements, but hey, this is good enough. For starters consider line 8300. The REM keyword is short for REMark and is just a placeholder for comments in your program. You can put any piece of drivel after it and the Spectrum won’t care. In fact, as soon as it sees a REM in the program, it goes into “ignore” mode and just moves on the next line of the program. I have used REM to remind myself that this is the “credits” sub-routine.
The next line features our first ever useful command: CLS, which simply CLearS the display screen. If you had specified any ink or paper colours before this, CLS would have cleared the screen to them (we’ll see an example of that shortly).
Lines 8320 to 8350 print a number of messages on screen. This is achieved via the PRINT command – a very powerful and versatile way to output to the screen. The syntax is simple: Just put whatever you want to output between the quotation marks (“”) following the PRINT command. For example, if you wanted to display “The answer is 42” on the screen you would do:
PRINT “The answer is 42”
In LINE 8320 you will see that we have multiple PRINT commands in one line, all of them separated by a colon (:) symbol. The colon operator serves to separate statements from each other. You can therefore put multiple statements on one line using a colon, which is what we have done.
One problem you will immediately run into when printing to the screen is that words may split at the end of the line resulting in ugly looking on screen text. This is because the speccy can display 32 characters on one line, and if you are trying to display more than a 32 character long message, the speccy will move to the next line to print the next character. There is no fancy word wrapping facility so you’ll have to ensure that your words don’t break unexpectedly when printing on screen. What you have to do is count the number of characters right after the first quotation mark. When you hit 31 (32 characters range from 0 to 31) you know that the next character will spill to the next line so you may need to add white-spaces to move the entire word to the next line (see the second PRINT statement in line 8320).
BASin Tip: BASin makes formatting text output easy. Instead of counting the characters, just watch the character ruler at the bottom of the window. The ruler automatically indicates the 32nd character mark with a red arrow as you type in the words!
Using the PRINT command all by itself prints a blank line, which is what we have done in line 8330 to split our output into paragraphs. However, I’ve been a bit cheeky I must admit. If you look at the fourth PRINT statement in line 8320, you will see that right before the first quotation mark, there is an apostrophe (‘) symbol. This is a shortcut way of making the PRINT command display a blank line! For example, this PRINT command will display the words “King” and “Kong” on successive lines:
Note the apostrophe symbol wedged between the end of the first quotation pair and the beginning of the second quotation pair!
Line 8360 is a very interesting one because it uses a BASIC trick to print on the 22nd line of the screen (which is usually reserved for input by BASIC although it’s part of the display screen. Normally you can only print from lines 0 to 21.). The trick is to simply put #0 after the PRINT command. Honestly, that’s all there is to it! This will simply make BASIC print whatever you want on the 22nd line. Nifty eh?
Okay so there are some more interesting things in line 8360. The first of which is the semi-colon symbol, which serves a very different purpose than a colon in a print statement. Here it serves to separate the data items in the PRINT statement. Examine the following:
PRINT “Hello ”;“there”
This will print “Hello there” on the screen. The semi-colon here merely tells the speccy to continue printing the word “there” right after the word “Hello ”. You can have many data items in just one PRINT statement.
If we had wanted to specify a colour for the text we would have used the INK keyword. The way to do is to simply use the INK keyword followed by the number corresponding to the colour we want (range 0 to 7). Cyan is 5 so INK 5 will print the text in cyan colour. The simplest way to print using cyan colour would be:
PRINT INK 5; “This text is cyan in colour”
Again, we use the semi-colon to split up the information (data item) to the PRINT command – the first being the ink colour and the second being the actual text.
In line 8360 we are trying something complicated: we want to print some text, we want it to be in cyan colour and we want it on line 22, which is why it reads the way it does with multiple semi-colons.
There are other sophisticated things you can do with the PRINT command but we’ll examine them later on as we deal with them in the code.
Line 8370 introduces the PAUSE command, which waits for n number of frames. Since the Speccy displays rate is 50 frames per second (or 60 in North America), you can wait for x seconds by using a value that’s equal to n times x. For example, if you want to put the Speccy on hold for 4 seconds you will use PAUSE 200, since 4 x 50 = 200. For 10 seconds, the value will be 500 and so on and so forth. However, if you use a value of 0, the Speccy will wait indefinitely till you press a key to move things along. This is ideal for “Press any key to continue” situations as you will no doubt realise. And we us this very fact to our advantage by displaying a screen full of information and then waiting for a key press before continuing.
The last line in the code block is a simple RETURN command. This one command though is single-handedly (well almost) responsible for making this code block a sub-routine! You see, a sub-routine can be called from anywhere in the program. That is, it is a re-usable piece of code. It needs to be written once, and if you need to use it anytime just call the sub-routine whereupon the speccy will transfer control to the sub-routine, execute it and then return to the point where it was called. You call a sub-routine with a GO SUB command (as we’ll see in the next code segment).
We shall examine the GO SUB command and other useful stuff in the next installment of this guide. Stay tuned!