QBASIC 4 - the totally irrelevant one Okay, it's time for something fun... we've decided to write a game. Yep, don't argue, we're going ot write a game. Let all thoughts of databases and spreadsheets and sorting programs and the like totally leave your mind, and I suppose we'd better get programming. Or rather, I'll do the initial programming, and you can type it in and improve it and then brag to your mates that you've written your own game. Okay, here it is: SCREEN 12 x = 320 y = 240 d = 0 INPUT "Please enter a skill level (1 is hardest)? ", s IF s < 1 THEN s = 1 score = 0 score.per.move = INT(40 / s) CLS FOR n = 1 TO 29 GOSUB print.stuff NEXT main: c = c + 1 IF (c / s) = INT(c / s) THEN GOSUB move.player ELSE LOCATE 1, 1: PRINT score; GOTO main print.stuff: b$ = "" skill = s + 15 FOR a = 1 TO 80 r = INT(RND * skill) + 1 IF r = 1 THEN b$ = b$ + "*" IF r = 2 THEN b$ = b$ + "x" IF r = 3 THEN b$ = b$ + "#" IF r = 4 THEN b$ = b$ + "@" IF r > 4 THEN b$ = b$ + " " NEXT PRINT b$; RETURN move.player: k$ = INKEY$ k$ = LCASE$(k$) IF k$ = "q" AND d <> 2 THEN d = 0 IF k$ = "a" AND d <> 0 THEN d = 2 IF k$ = "o" AND d <> 1 THEN d = 3 IF k$ = "p" AND d <> 3 THEN d = 1 IF d = 0 THEN y = y - 1 IF d = 1 THEN x = x + 1 IF d = 2 THEN y = y + 1 IF d = 3 THEN x = x - 1 score = score + score.per.move IF x = 640 THEN x = 1 IF y = 480 THEN y = 1 IF y = 0 THEN y = 479 IF x = 0 THEN x = 639 IF POINT(x, y) > 0 THEN GOSUB crash PSET (x, y), 15 RETURN crash: CLS PRINT "Oh dear. You seem to have run into something rather solid and unmovable. Could it have been a wall? Either way, your game it most definitely over." PRINT "However, you did score: "; score END Okay, for all of you who are now gibbering insanely, don't - it makes you look unattractive. Calm down, and think about it logically. There is nothing here that is more complicated than anything you've yet done, so just look through it bit by bit until it starts to make some sense. Even if you don't want a future in games programming, it is always useful to consider games programming as it requires some very focused logic. I'm not going to tell you what every line does, this time. It'd take far too long and you wouldn't enjoy it. What I am going to do, however, is tell you what each section of the program does and what some of the variables mean. Hopefully you should be able to wrok most of it out with the help of this and the QBASIC help file; if not, don't worry, just keep coming back to it as you get better at programming and eventually you will get it. Okay, here we go: SCREEN 12 This line sets up the screen mode. For a full list of screen modes, see (you guessed it) the QBASIC help file, under "Screen Statement" in the index. Screen 12 is 640 pixels wide by 480 pixels high, although it has a limit of 16 colours. Note that the ranges are 0-639 and 0-479; (640,480) is off the screen. x = 320 y = 240 d = 0 This sets up three important variables. The variable x stores the horizontal position of the player. The variable y stores the vertical position. The variable d stores the direction of travel: 0 is upwards, 1 is right, 2 is down, 3 is left. More on that later. INPUT "Please enter a skill level (1 is hardest)? ", s IF s < 1 THEN s = 1 score = 0 score.per.move = INT(40 / s) This ass the user for a skill level. If the skill has been entered as less than one then it will be set to one. The score is then set to 0 and the score per move is worked out as 40 divided by the skill level. The INT command turns a number into an integer, or a whole number. No problem. CLS FOR n = 1 TO 29 GOSUB print.stuff NEXT This clears the screen then visits the subroutine print.stuff 28 times. For the sake of simplicity I'll talk about that routine next: print.stuff: b$ = "" skill = s + 15 FOR a = 1 TO 80 r = INT(RND * skill) + 1 IF r = 1 THEN b$ = b$ + "*" IF r = 2 THEN b$ = b$ + "x" IF r = 3 THEN b$ = b$ + "#" IF r = 4 THEN b$ = b$ + "@" IF r > 4 THEN b$ = b$ + " " NEXT PRINT b$; RETURN The purpose of this routine is the create one strip of the playing area - a random line of all the symbols shown, with the majority being spaces. It does this using the string b$. First b$ is set to "", or nothing, then characters are randomly added onto it 80 times, using the skill level to make more non-space characters appear on the harder settings. It then prints b$, with a semicolon on the end to tell the computer not to go onto the next line yet. The command RETURN takes the program back to the GOSUB command that called the subroutine. Don't worry if this freaks you out - the next tutorial will cover subroutines properly. main: c = c + 1 IF (c / s) = INT(c / s) THEN GOSUB move.player ELSE LOCATE 1, 1: PRINT score; GOTO main This is the main loop. Tiny, eh? That's because most of the work is done by the subroutine move.player, which, unsurprisingly, gets input from the player and moves them accordingly. This bit also controls the speed and prints the score. Basically, if c is divisible by s then it will move the player, otherwise it will print the score. See if you can work out how it does this, bearing in mind the the INT command turns a number into a whole number. move.player: k$ = INKEY$ k$ = LCASE$(k$) IF k$ = "q" AND d <> 2 THEN d = 0 IF k$ = "a" AND d <> 0 THEN d = 2 IF k$ = "o" AND d <> 1 THEN d = 3 IF k$ = "p" AND d <> 3 THEN d = 1 IF d = 0 THEN y = y - 1 IF d = 1 THEN x = x + 1 IF d = 2 THEN y = y + 1 IF d = 3 THEN x = x - 1 score = score + score.per.move IF x = 640 THEN x = 1 IF y = 480 THEN y = 1 IF y = 0 THEN y = 479 IF x = 0 THEN x = 639 IF POINT(x, y) > 0 THEN GOSUB crash PSET (x, y), 15 RETURN Looks complicated? It's not. First, the command INKEY$ is used to store any key being pressed in k$. This is then converted to lowercase for ease of processing. Next, k$ is checked to see if any of the controls have been pressed. If they have, it then checks that they are not about to make a turn of 180 degrees (not a good idea on a bike) and if they're not, it makes the appropriate change in direction. Then this direction variable is used to make the neccessary changes to the player's position. Note that, on any system at all to do with computers, (0,0) is the top left corner of the screen. This means that ot go up y has to decrease, and to go down y has to increase. This is the accepted standard, so get used to it. Just remember to forget it during maths lessons. The final part of the routine does several things. The score is increased by the amount that was established at the start of the program. Some IF statements check if the player has reached an edge of the scree, and if they have it flips them over to the other edge. The POINT command is used to check if they have crashed into anything; it returns the colour of the pixel at (x,y). If it is greater than 0, the player has crashed and the subroutine crash is invoked. If not, the PSET command is used to plot a pixel at the player's position. Fifteen, by the way, is white - change this if you want. Finally the subroutine returns control to the main loop. crash: CLS PRINT "Oh dear. You seem to have run into something rather solid and unmovable. Could it have been a wall? Either way, your game it most definitely over." PRINT "However, you did score: "; score END The very last routine just prints a message along with the score, and exits. Okay, so that's the game. Play it, enjoy it, have fun. Now, improve it. Here are some suggestions: Is it running too slowly? Try putting this at the start: DEFINT A-Z See how much faster it runs? The command simply tells QBASIC that all the variables to be used are integers. An integer, as you will already know, is a whole number. If you don't use this command, the computer stores all variables as "floating point" numbers, in other words they do not have to be whole numbers. Using "floating point" numbers takes up a heck of a lot of processing power; the computer finds it far easier to deal with integers, and so the whole program increases in speed. Bored of playing on your own? Try putting in a two player mode. This is going to be quite difficult, but here's a quick guide: - Decide on some new variables for player 2. How about xx, yy and dd? - Work out which routines you will need to duplicate and which bits will need to be changed, for example, you will need some extra lines to check for player two's controls and update dd accordingly. The changes will be to the controls - you need to work out another set for player two. - You could draw the second player a different colour. - Does the skill rating have to apply to both players? - You will need to create another crash routine to print a different message when player two dies. Good luck! Having two players will improve this game immensly. You could even have three players, but then controls and things start getting a little hectic. Does the presentation look a little... nonexistent? Have a got at printing a nice introduction screen, using different colours, possibly replacing the (rather primitive) random board with ones that you can design yourself, or with proper graphics instead of text characters. These are just some suggestions - experiment. What about putting in a cheat mode? This could make you invincible, or just give you more score. Either way, it's going to be good for your programming skills. I'll leave you there, I think. See if you can improve my game - if you think you've done something pretty good with it, feel free to send me a copy - I'd be very pleased to see what people can come up with.