Pete's QBASIC Site

Tutorial #4


Hello! Welcome to Pete's QBASIC Site's QBASIC Tutorial #4. This is the fourth in a series of tutorials to teach you how to program in QBASIC. It's been a while since tutorial #3. (That one was released December 19, 1998 - now it's February 6, 1999. Sorry about that, but I promise that this one will be better than ever!


Okay, here's what you will be learning today:









         Sub Routines



         Sample GOSUB/RETURN program

         Seperate "page" subroutines




         EXIT SUB



Looks like a lot, eh? Well it is. I'm going to be typing for a while, and you'll be reading for a while. Okay, let's get started...




INKEY$ is an extremely useful command. Basically what it does is check the keyboard to see if you are pressing a key, and if so what is it? It's pretty simple, but easy. INKEY$'s syntax is INKEY$. What you do with it is treat it like a string variable. You can use it in IF...THEN statements, LET statements, PRINT statements - anything you could normally use with a string variable or text in quotations.

Here is what INKEY$ would look like in a program: "IF INKEY$="a" THEN GOTO 100" That line of code will check to see if the key that is being pressed is "a", and if it is, goes to line #100. Simple as that. You could also use it like this: "a$ = "INKEY$" or "PRINT INKEY$". Just think of it as a string variable, and it will be easy to understand.

There is another trick to INKEY$. If you are checking for a standard key (a letter or number), it will be read as a one byte letter. That's simple. For extended keys (arrow keys, function keys, escape, enter, etc.) a "null" character and an ascii scan code. What that means is that if you want to check and see if the up arrow is being pressed, the code would look like: IF key$=CHR$(0) + "H". (For some more of these "codes", check my tutorials section. There is a tutorial that has all of the keyboard scancodes.) You don't know the CHR$ command, but it is the fourth heading down from here, so go head and read it if you want to know it ahead of time.

One more thing: If you check what key is being pressed, there is a very good chance that the user is not pressing that key at that specific nano second. What are you going to do? Well, the most logical answer is to check and see if the user presses it the next nano second. If they aren't pressing a key, you should check it again. Over and over until something is being pressed. If something is being pressed,. go off into a branch of your program depending on what is being pressed.



         INKEY$ checks to see what key is being pressed at the exact time that the command is being executed.

         It is a good idea to check what key is being pressed with INKEY$ many times in a row because there is a big chance that the user will not be pressing that key at that time.

         The syntax for INKEY$ is INKEY$, but it is used as a string variable. This command can't be used without a "helping" command.

         Extended keys use "codes" instead of the exact letter or number.




INPUT$ is basically a cross between INKEY$ and INPUT. It is used to take a certain number of keypresses from the keyboard without displaying them on the screen. It is also used to read from OPENed data files, but you won't be getting in to that for a while.

The syntax for INPUT$ is "INPUT$ (Number of expressions you want read)". Simple as that. This command must be used with a "helping" command that is normally used with a string variable. (Commands like "LET", "PRINT", "IF...THEN", etc.) Use it just like INKEY$, just realize that it will store or read more than one character.



        INPUT$ reads or stores (depending on the command it's used with) a specified number of characters.

        The syntax for INPUT$ is: INPUT$. It must be used with a "helping" command.




DO...LOOP is, as far as I'm concerned, the most useful loop. It is very useful for main loops of games, and can even do the same functions as IF...THEN if you put an adding statement in the middle. Okay, enough talk. DO...LOOP is a command that DOes something forever, or until you tell it to stop. In older versions of BASIC, this was a major problem, because if you ran your program, and did not provide an "exit" from the loop, it would continue forever. The programmer would have to turn off their computer and would lose all of the programming they had done from the last time they saved. Now, though, you can just use CTRL + Break

Here's how to use DO...LOOP: "DO : 'execute commands here : LOOP" simple as that. This code doesn't do anything because in between the DO and LOOP I don't have any commands except for a REM command. If there was other code in between, say, "PRINT "hello!", "hello" would be PRINTed over and over again - forever or until you press CTRL + Break or turn off your computer.

DO...LOOP already is pretty useful, but back when Microsoft developed QBASIC, they decided to make a couple more functions you could use to end the LOOP, thus making programming easier. These commands are, among others UNTIL and WHILE. UNTIL keeps on going through the LOOP UNTIL some variable equals something. It looks like this: "DO : x=x+1 : LOOP UNTIL x=1783" This simple program LOOPs around until x=1783, adding one to itself every time it goes through. UNTIL can be used with both DO and LOOP in the same manner. WHILE works pretty much the same. WHILE makes the LOOP continue until the variable after it does not equal itself. This command usually is used with greater than or less than signs, but can be used with an equal sign. It looks like this: "x=400 : DO WHILE x > 10: x=x-1 : LOOP" This program makes x=400, then subtracts one from it every single time it LOOPs until x=10. Once again, this command can be used with the DO or the LOOP.



        DO...LOOP is a loop that continues forever until it is stopped.

        Any commands can be put between the DO and the LOOP that you want done over again later.

        WHILE and UNTIL can be used with either the DO or the LOOP to stop the loop if somthing equals the expression or variable following the WHILE or UNTIL.

        WHILE checks if something is equal or not equal to something WHILE the loop is running.

        UNTIL makes the LOOP continue UNTIL a variable equals the variable or expression following the UNTIL command.

        This is useful for main loops of programs.




CHR$ is a command that converts ascii code numbers into ascii characters. It takes a character (a letter or a number) and converts it to an ascii number code. It can be used with any command that can be used with any command that supports string variables. The syntax is: CHR$, but always needs a "helping" command to be used. Here is what it looks like: "PRINT CHR$(150)" will PRINT the ascii character corresponding with 150, which is "".



        CHR$ converts numbers into ascii characters.

        The syntax is CHR$, but must be used with a "helping" command that is normally used with a string variable or expression.




ASC is a command that ascii characters numbers into ascii number codes. It takes an ascii number code and converts it to a character (a letter or a number). It can be used with any command that can be used with any command that supports number variables. The syntax is: ASC, but always needs a "helping" command to be used. Here is what it looks like: "PRINT ASC()" will PRINT the ascii number corresponding with , which is 150.



        ASC converts ASCII Characters into Ascii number codes.

        The syntax is ASC, but must be used with a "helping" command that is normally used with a number or a number variable.




SLEEP is a command that makes the computer sleep for a certain amount seconds or until a key is pressed. It is universal, so SLEEP will cause the same delay on all computers - 286 to P800. Here's how it works: "SLEEP 5". This line of code will make the computer delay for exactly five seconds, then resume the program with the lines of code after it. It's very simple. There are some problems with SLEEP, though. If the computer is "SLEEPing", and you press a key, it skips from wherever it is in the current second to the beginning of the next one. Also, you can't use decimals with SLEEP - only whole numbers.

SLEEP has one more function. If you type in just "SLEEP", the computer will stop and wait for a key to be pressed.



         SLEEP makes the computer stall for a specified number of seconds or waits for a key to be pressed.

         The syntax of SLEEP is: SLEEP [number of seconds to stall] . If no number of seconds is given, the computer waits for a key press.

         SLEEP can not support decimals and if the computer is stalling for a specified number of seconds, and a key is pressed during a second, it goes to the beginning of the next second.


Sub Routines

Sub Routines are small programs that are in a bigger program. They can be CALLed upon to perform a specific task any time during the course of a program. They are very useful in big programs that perform multiple functions, or games.

Here's an easier way to think of a sub routine. Think of the main program as your brain and involuntary organs (heary, lubgs, etc.). Your arms, hands, legs and feet are subroutines to the main program. Say that you wanted to walk across the room, pick up a baseball and throw it out the window. Now it would be very hard for you to go across the room and throw the ball without using your arms or legs - your subroutines. Now, you could do it using your main program, but it would be way too hard for you to go across the room, pick up the ball and get it out the window without using your arms or legs. If you had those subroutines, you could do it very simply. It's the same thing with subroutines on a main program. Subroutines make the program size much smaller, much simpler to use, faster, and makes much less work for the programmer.

Lets say that you have two subroutines on your main program - one for your legs and one for your arms. The one for your legs takes a message from the main program that says "stand up and walk to the other side of the room." The legs do this task and return control to the main program. The main program says to the arm subroutine "pick up the ball and throw it out the window." The arms throw the ball out the window and return control to the main program.

Okay, enough talk about arm subroutines and throwing baseballs. Subroutines are little tiny programs that do one simple task whenever you want that to happen and can do it differently to fit different needs (variables). They can be on the main "page" of your program, or side "pages". By "page", I mean place where code is displayed for you to edit it. A program can be one long, complex page that has all subs included, reachable with a GOSUB statement, or they can be on seperate pages and be reached by CALL statements.

All my rambling isn't really helping you much, so we'll just get started with the coding process and you should catch on.




GOSUB basically means "go to a sub routine". This only goes to a sub on the main "page" of the program. It is almost like GOTO, but has a cool built-in feature. When the subb is done with, it RETURNs to the place where it was called. So if you call it anywhere in a program, it will return to the same place that it was called from.

The syntax for GOSUB is "GOSUB [line number or name]". That's all it is. It goes to the line number that the sub begins on, goes through the sub and RETURNs to the next command after the line where it was called. This is what it would look like in a program: "GOSUB 1080". This statement would send the computer to line 1080 to execute the commands in the sub routine until it is told to RETURN to the line where it came from.



         GOSUB sends the computer to another part of the program and executes the statements there until it is told to RETURN.

         The syntax for GOSUB is: GOSUB [line number or name]




RETURN is a command used to RETURN to the place in a program where the last GOSUB command was executed. This command is put at the end of subroutines on the main "page" of a program.

The syntax for RETURN is just plain old RETURN. There are no variables or expressions you have to fill in. It's very simple.



         RETURN is used to RETURN to the place in a program where the last GOSUB command was executed.

         The syntax for RETURN is just plain old RETURN. No bells and whistles with this one.



Sample GOSUB/RETURN Program

Since you might not be completely clear on subroutines and usage of GOSUB and RETURN, I've written a small program to better explain it here:


'Program using a GOSUB/RETURN subroutine

PRINT "Cool! We're goinng to demonstrate how to use suboutines!"

PRINT "Press a key to continue..."


GOSUB hello 'Goes to a subroutine beginning on the line "hello"

PRINT 'After the subroutine ends, you are sent here.

PRINT "Wow! That subroutine ran and RETURNed us to the same place in the program! Neato!"

PRINT "Press a key to continue..."



PRINT "Now, to prove that we didn't cheat, I'll run that sub again!"

GOSUB hello 'calls upon the subroutine again.

PRINT "Groovy!"

END 'The End!


hello: 'The line label that this subroutine begins on.

FOR t=1 to 10 'starts a loop to PRINT some words ten times.

PRINT "This loop is in a subroutine! This will be printed ten times!" 'PRINT's some crap


RETURN 'RETURNs to where this sub was called from via GOSUB


Seperate "Page" Subroutines

Okay, you know how to make a subroutine on the same "page" of program as the main loop, but what if you want your program on a different "page" of program? Well, QBASIC has that incorporated into it. Now to get you started, I'll type out step by step instructions for you to follow to start your very first subroutine. First, (this is in QBASIC, mind you), click on "Edit" on the heading row of the screen. After the drop down menu is opened, go down to "New Sub". Click it. Now a pop up window will appear. Next to name, type in the name that you want to give your sub. For this example, I'll call the sub "myfirstsub". After you have that typed in, click on OK or press enter (whatever you prefer.) Now three things will happen. Where the name of your file is displayed, it will show [subname]:[filename]. In this case, "myfirstsub : Untitled". The main program screen will have disappeared, and in the screen is the following text: "SUB [subname], (NEXT LINE) END SUB". What does this mean? Well, END SUB is just like RETURN. It just returns the computer to the same spot on the previous page, not to a different spot in the program. The SUB [subname] line identifies the sub for both you and teh computer. That's about it. No executable commands can be put before these two lines of code, but any command you want can be put in between.



DECLARE is a command that tells the computer that there is a seperate page subroutine, and what variables are associated with it. Think of DECLARE as a REM statement for the computer. It tells the computer that there is a subroutine on a seperate page in the program, and when you run the program, what the variables supplied by the main loop mean in the subroutine. The computer puts this statement in for you after you save the program and load it again, or you can type them in yourself. It must always be at the top of the main page of your program, and be before executable statements.

The syntax for DECLARE is: "DECLARE SUB [subroutine name](parameter list)". The subroutine name is hust that - the name of the subroutine that you are declaring. The parameter list is a list of variables that you supply when you CALL the subroutine that are going to be used in the subroutine. These varaibles are listed, seperated by a comma. This is what DECLARE would look like in a program: "DECLARE SUB shop(itemname$, price%, money%)". This declares the sub "shop", and makes the variables itemname$, price% and money% variables that must be supplied every time the sub is CALLed. When you CALL teh sub, you just supply what those variables are equal to in that particular case.



         DECLARE is a command that tells the computer that there is a subroutine on another page, and supplies parameter names that are to be supplied when the sub is CALLed for use in the sub.

         The syntax is DECLARE SUB [subroutine name](parameters seperated by commas)

         If you don't type in this statement, the computer puts it in for you the next time the program is loaded.

         DECLARE must always proceed executable statements.




CALL runs a subroutine on a different page of a program. It can be located in any sub or on the main page (but if you CALL too many subs out of subs, you run out of stack space.) It must contain all parameters that are DECLAREd with the subroutine.

The syntax for CALL is "CALL [sub name](parameters)". The sub name is the name of the sub. Parameters are the variables DECLAREd with the DECLARE statement in the exact order that they were originally written, and seperated by commas. Here is what CALL would look like in a program: "CALL oogabooga("abracadabra", 17, "Hello!")" This CALLs the sub oogabooga and supplies variables with information to store for use in the sub.

CALL has one more cool feature. You can omit the word CALL, and CALL a sub with just it's name. It would look like this: "moveplayer". If the sub has parameters, You must omit the parenthesis around them. It would look like this: "CALL wagtail "wagging...", 83.7, "Wag completed!", 104.98" Simple, eh?



         CALL runs a subroutine on a seperate "page" than the current one.

         The syntax for CALL is "CALL [sub name](parameters seperated by commas)

         The CALL can be omited, but if omited, parenthesis must be omited too.




Ever notice how variables that are used in the main program are reset when they are used in subs? COMMON SHARED is the command(s) that you can use to solve this problem until you learn DIM. COMMON SHARED tells the computer not to reset certain variables in subroutines. The syntax for COMMON SHARED is "COMMON SHARED [parameters seperated by commas]" Very simple. It would look like this in a program: "COMMON SHARED name$, HP, MP, weapon$". This code tells the computer not to reset the variables name$, HP, MP and weapon$ when they are used in subroutines. COMMON and SHARED have different meanings, but you don't need to know them now. Also, COMMON should be located at the top of the main page of a program.



        COMMON SHARED tells the computer not to reset certain variables when they are used in subroutines.

        The syntax is "COMMON SHARED [parameters]

        COMMON SHARED should be located towards the top of the main page of a program.




EXIT SUB is a command to end the subroutine in the middle of it and return to the place where the sub was called from. It performs the same funtion as END SUB, but it does it in the middle of a sub, as END SUB must be the last command in a subroutine. The syntax for EXIT SUB is EXIT SUB. Nothing special about it. You would probably use this with IF...THEN statements if certain variables are equal.



        EXIT SUB exits a subroutine and returns the computer to the plave where the subroutine was CALLed from before the END SUB command.

        The syntax for EXIT SUB is EXIT SUB.




Algorithms are plans for a program that you should make before you begin coding it. Somtimes you would write this out, sometimes you would just visualize it in your head, but anyway, this is how you think up how a program works, and how to code it.

Algorithms are made up of many simple steps (commands) and go in an order. They ask yes or no questions (IF...THEN) to decide what to do next. Here is the algorithm for a simple shooting game:


1.) Move target a little bit.

2.) Get input from player.

3.) If no input is given, repeat from #1.

4.) If INPUT is a press from the spacebar, shoot bullet.

5.) If INPUT is from escape key, end the program.

6.) Move bullet forward, move target a little bit.

7.) Repeat #6 until bullet is off the screen or hits the target.

8.) If the bullet hits the target, add one to target hits.

9.) If target hits equals 5, tell the player that they one. If not, repeat from #1.


Understand? Converting this into a program would be much easier than writing it from scratch. Now that you are going to be maiking more complicated programs, algorithms (plans) for your programs will be very helpful.



Final Thoughts

I decided to can the idea of giving you challenges/homework to work on. It takes more work on my part, and I'm sure none of you do it anyway. And, after HOURS of typing, I'm don't feel like typing anymore. Next tutorial is on graphics!!!



February 7, 1999