-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- INTRODUCTION TO QBASIC SERIES #3 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Writer: Matthew River Knight
Welcome to the third part in the Introduction to Qbasic Series! We went over quite a lot of information last time, having covered some more of the capabilites of Qbasic with regard to the handling of text, demonstrated how to allow the user input from the keyboard, did some LOOPing, and we even took a brief look at how to display graphics in Qbasic. This time I'd like to cover some more of these simple things before we go onto more difficult areas of programming, hopefully picking up some information that we left out along the way.
First of all, let's take a look at what else we can do with Qbasic as far as text handling is concerned. For starters, it would be nice if we could place text at a specific location on the screen wouldn't it? Lucky for us, Microsoft wrote made a nice little routine to do this for us. This is the LOCATE statement. The LOCATE statement tells the computer at which location on the screen the next PRINTed text must be placed. You'll recall that last issue, in order to explain how PSET works, I described the screen as a grid. When using LOCATE you also have to think of the screen as a grid, but it works a little differently. The 'grid' that we're talking about when using LOCATE is not made up of pixel spaces, it is made up of much larger blocks that are basically the same size as your average ASCII character. And what is an ASCII character you ask? Well, all the letters and numbers you see on the screen in DOS are ASCII characters. Apart from the number and letter characters, there are also some other ASCII's which look quite strange. You have seen some of them before. Some of them are used by the Qbasic editor to draw the menu's and the scrollbar, etc. ASCII stands for American Standard Code for Information Interchange.
Another way of thinking about how LOCATE works is like this: suppose you wanted to put some text, for example "Qbasic rulz!", 5 ASCII spaces across the screen, and 10 ASCII spaces down. Then all you'd have to do is this:
LOCATE 10, 5 PRINT "Qbasic rulz!"
Try experimenting with different numbers and see what results you get. Using LOCATE will make your life much easier when using text! There are some other similar text handling routines, but there is no need to use them since LOCATE is generally capable of doing exactly the same as them, but is easier to use and more versatile.
Okay, now onto something more fun ^_^ Last time when we looked at using graphics in Qbasic we really didn't do very much. All we used was PSET and LINE - not too interesting. So we'll cover some better stuff this time round.
It is sometimes necessary that you know the color code of a certain pixel on the screen. You can actually do some pretty cool graphics effects just by knowing this simple information. In Qbasic, we use the POINT statement to obtain the color code of a certain pixel on the screen. The POINT statement is very versatile in the way that it may be used, and this makes it very easy to understand.
For example, if you wish to get the color of a pixel at the coordinates (2,5) on the screen 'grid' into the Col variable then all you do is this:
PSET (2, 5), 2 'Place a green pixel at coodinates (2,5) Col = POINT(2, 5) 'Get the color code of the pixel at (2,5)
You can also use POINT like this:
IF POINT(2, 5) = 2 THEN PRINT "That pixel is green"
Try playing around with this, and maybe you'll figure out how to do something cool using a combination of POINT and one of the other Qbasic drawing routines. I once wrote a little program using PSET and POINT that allowed you to print text on the screen, and it melted what looked like lava around it. There is no reason why you couldn't write a program to do exactly that!
Okay, now on to something a bit more cool. You have probably found that using LINE to draw graphics is rather difficult and time consuming. There is another Qbasic command for drawing that is much easier to use. It's called DRAW! It works quite unlike any other Qbasic routines we have covered so far, as you'll soon see.
The DRAW statement has its own commands for doing things. For example, it has the U command for drawing lines up, and the D command for drawing lines down. Let's demonstrate this by means of an example:
SCREEN 13 PSET (10, 10), 2 'Start drawing at (10,10) in green DRAW "U100" 'Draw a line up, 100 pixels in length
PSET (100, 100), 14 'Start drawing at (100,100) in yellow DRAW "D20" 'Draw a line down, 20 pixels in length
There are lots of commands used with DRAW, but you'll probably never use half of them. We'll cover the most commonly used ones. If you want to know the others then you'll have to take a look at the Qbasic help file.
You have probably already guessed that in order to draw right, you use the DRAW command R, and to draw left you use L. This should have been obvious. But what if you want to draw diagonally? Well, to draw diagonally up and right you use the DRAW command En, where n is a number specifying the pixel length of the line to be drawn. To draw diagonally down and right you use the commnd, F. To draw diagonally down and left you use G, and lastly, to draw diagonally up and left you use H. Simple no? Okay, here's an example:
SCREEN 13 PSET (160, 100), 2 'Start drawing at (160,100) in green DRAW "H20 E20 F20 G20"
Note that I have put a space between each of the DRAW commands in order to make it easier for you to read. You don't have to do it this way though. You could just as easily have left them out, and it would do exactly the same thing. Like this:
SCREEN 13 PSET (160, 100), 2 'Start drawing at (160,100) in green DRAW "H20E20F20G20"
It really doesn't make a difference.
Another usefull DRAW command is C which sets the DRAWing color. All you do is say Cn where n is the color code of the color in which you'd like to DRAW, and voila - you're DRAWing in that color. Could it really be any easier?! Let's demonstrate this by means of an example:
SCREEN 13 PSET (160, 100), 2 'Start drawing at (160,100) in green DRAW "C2 H20 C3 E20 C4 F20 C5 G20"
Once again you can see that I've put spaces between each of the DRAW commands in order to make this easier to read and understand. If I were writing a program in which readability was not a necessity, I'd have left the spaces out since they're a waste of space.
There are many other DRAW commands that can be used, but I'm not going to cover it all here, when there is a perfectly good description of all of them sitting right there in the Qbasic help files. One thing that I should mention before we go onto something else is that you are able to use DRAW with strings instead of specifying it right after the command. This allows you to save a lot of space. To clarify this further, here's an example:
Diamond$ = "C2 H20 C3 E20 C4 F20 C5 G20" SCREEN 13 PSET (160, 100), 2 'Start drawing at (160,100) in green DRAW Diamond$
In the above example you can clearly see that we have used DRAW with a string variable, instead of placing all the commands right after the DRAW statement. You will find this ability very usefull when you find the need to DRAW an object more than once. Without this ability you'd have to specify all those commands to draw the object again, and again, and again, which is really a waste of space.
Right. Now we've covered PSET, POINT, LINE and DRAW. With that you can, with some ingenuity, draw some fairly good graphics. But what if you want to draw a circle? Can you imagine writing the DRAW code for all of that! Yeah, it would be a total nightmare! Fortunately there is a Qbasic statement called CIRCLE which allows you to draw circles. It's actually a bit more versatile than that in the light that it can not only draw circles, but also ellipses, and fractions of circles/elipses. It's a really great little routine. So let's learn how to use it!
We'll start off using CIRCLE just to do simple stuff, and then we'll work our way up, step-by-step, finally getting onto some more difficult stuff.
Okay. In order to draw a yellow (color code 14) circle with a radius of 15 at the coordinates (160,100) on the screen 'grid' we'd type the following code:
SCREEN 13 CIRCLE (160, 100), 15, 14
Now that wasn't so hard, was it? Right, now that we've mastered the drawing of circles, I think it's time that we move onto ellipses. You may not have heard of an ellipse before, so this is what it is: an ellipse is, in the most simple terms I can think of, basically like a squashed circle! You can probably imagine what I mean. It can be squashed from the top, or from the side. It doesn't really matter. Any squashed circle is an ellipse!
Let's, for example, say you wanted to have a circle that looked squashed from the top. First thing you have to think about is how squahed you want it to be. If we wanted to squash the circle, from the top, by 50% then we'd do this:
SCREEN 13 CIRCLE (160, 100), 15, 14, , , 50 / 100
If we wanted it squashed by 70%, from the top, then we'd do this:
SCREEN 13 CIRCLE (160, 100), 15, 14, , , 30 / 100
Simple no? Unfortunately, although we are able to describe the squashing effect in degrees here, the CIRCLE routine doesn't actually think of it that way, and that makes life quite difficult when we want to squash a circle from the sides - the degrees thing doesn't work anymore. It actually works like this: the division (above it is 29/100) which is actually called the aspect describes the ratio of the x radius to the y radius (x;y). The defualt aspect ratio depends on the screen mode, but gives a visual circle in any graphics mode, assuming a standard monitor screen aspect ratio of 4:3.
Did that make you a little dizzy? Yep? Okay, well, then let's go about it this way...practise! Play around with this until you understand! That's the best way to understand programming. Just to get you started, here's an example program showing you how to squash a circle from the side:
SCREEN 13 CIRCLE (160, 100), 15, 14, , , 170 / 100
Play around with this and it'll soon make sense.
Okay, as I mentioned earlier, it is possible to draw fractions of the circle, but that is slightly mathematical so I'll leave that for another time. I think I've confused you enough for one day!
There are still other graphics routines to cover, but we'll have to leave that for another issue. We have said more than enough about graphics this month!
Okay, we'll cover one more aspect of programming before I leave you to play around with what you've learned this issue. Sound in Qbasic! Before we even start this I need to explain one simple thing - Qbasic is, ordinarily, only able to produce sound through the internal PC speaker. You probably didn't even know that you have a speaker inside your computer, but you do. In the old days of computing there was no such thing as sound cards, and sound amplifiers for the computer. Such things were unheard of. In those days everyone used to have to play sound through the little speaker inside the computer. Unfortunately the internal speaker is really junky. Any sound that comes from it sounds terrible. But, as a newbie, it's the only sound that'll be available to you for a while. There are ways to use the sound card in Qbasic, but it's really difficult, so we are not going to cover that at this stage.
Okay, I have rambled on long enough! We have quite a few Qbasic statements at hand which generate sound through the PC speaker. We'll start off with some simple stuff. It's fairly clear that the simplest form of sound we could possibly get the computer to do is just a beep. What could be easier than that? Well, there is a Qbasic statement called BEEP that does just that! BEEP generates a beep-like noise from the internal speaker at 800hz (800 cycles per second) for one-quarter of a second. It's really easy to use BEEP. Let's test it:
Yep! That's it! That's all you have to type to use BEEP. Could anything be any easier than that?! Well congratulations, you've just mastered yet another Qbasic statement, and it's only taken you two seconds! ^_^
Okay, soon you're likely to get bored with BEEP. With BEEP you are not able to specify the pitch of the BEEP and the duration for which it plays. And that is no good. No good at all. Okay, well this isn't much of a problem. There is a Qbasic statement called SOUND which allows you to do exactly what BEEP won't allow you to do! The syntax of SOUND is:
SOUND frequency, duration
frequency is the pitch of the sound. For those of you who don't know what this means (get a dictionary!) here's some examples - an example of a low pitch would be thunder. It sounds deep and has a low pitch. An example of a high pitch would be the squeek of a mouse. It has a high pitch. The higher the number is in place of frequency, the higher the pitch of the sound. The frequency may not be lower than 37, and not higher than 32767.
duration specifies the amount of time the computer has to spend making the sound. It is measured in clock ticks. Clock ticks occur 18.2 times per second. The duration may not be less than 0, and not higher than 65535.
Ah, okay, now is a good time for an example, no?
SOUND 300, 70
If you really want to give yourself a headache (why would you want to do that?!) then run the following program:
SOUND 5000, 65535
I would not advise running that program. You'll get a terrible headache. You could easily write a program that would trick somebody into thinking there's a mosquito in the room ;)
Now the problem with this stuff is that it's really hard to write music with it. It's even harder to try and write sound effects. With music we are accustomed to sounds being described as A,B,C,D,E,F and G. Well here's a list of the equivelent frequency's for them! ^_^
I took this list from a book I have on Qbasic. For some reason there are a number of different A's, B's, C's...etc. I know nothing about music so I have no idea why this is the case. Those of you who know about music will be able to make more sense of this than I can ;)
Note Frequency Note Frequency
C 130.810 C* 523.250 D 146.830 D 587.330 E 164.810 E 659.260 F 174.610 F 698.460 G 196.000 G 783.990 A 220.000 A 880.000 B 246.940 B 987.770 C 261.630 C 1046.500 D 293.660 D 1174.700 E 329.630 E 1318.500 F 349.230 F 1396.900 G 392.000 G 1568.000 A 440.000 A 1760.000 B 493.880 B 1975.500
By doubling or halving the frequency, the coinciding note values can be estimated for the preceding and following octaves.
To produce periods of silence, use the following statement:
SOUND 32767, duration
To calculate the duration of one beat, divide the beats per minute into the number of clock ticks in a minute (1092).
The following table illustrates tempos requested by clock ticks:
Tempo Notation Beats/Minute Ticks/Beat
very slow Larghissimo Largo 40-46 27.3-18.2 Larghetto 60-66 18.2-16.55 Grave Lento Adagio 66-76 16.55-14.37 slow Adagietto Andante 76-108 14.37-10.11 medium Andantino Moderato 108-120 10.11-9.1 fast Allegretto Allegro 120-168 9.1-6.5 Vivace Veloce Presto very fast Prestissimo
Like I said, I know nothing about music, and I thus have no idea what the above table is talking about. The only thing that I know about music is that it comes out of the radio! ;) Those of you who know about music will probably find the above information very usefull, but as for the rest of you who know no more about that stuff than me, don't worry about it. It's still possible to do cool stuff with SOUND without any knowledge of music.
There's another way to use music with the internal speaker in Qbasic, but we'll cover that (and other things) next issue. Until next month, just play around with what you have learned, and see if you can come up with something cool. If you make a little program, and you are proud of it and would like others to see it, then email it to me at firstname.lastname@example.org and I'll include with the next issue of the QBCM! Have fun with Qbasic!!! ^_^
Cya next month!