Classic Computer Magazine Archive A.N.A.L.O.G. ISSUE 64 / SEPTEMBER 1988 / PAGE 90

Game Design
Workshop

by Craig Patchett



With small programs, it's very easy to just jump right into things and start programming. Unfortunately, it's not so easy once they get larger; there are so many things to take care of, that you can get totally lost and confused very quickly. The solution is to take an intermediate step between your mind and the program; something that makes sense to you and is easily converted into a program. This step is called a flowchart.

    Despite the value of using a flowchart, very few people actually use one, especially in the world of microcomputers. And, if you promise not to tell anyone, I'll let you in on a little secret. Up until this column, I had never used a flowchart either! And I've been programming for seven years now, including some very complicated video games. So I'm not going to come at you and say, "Well, you should use flowcharts because that's what I was taught to do, and it's worked for me." Instead, I'll explain the advantages and disadvantages that I ran across in using my very first flowchart.
    First of all, let's take a look at a simple example of a flowchart. This is for the part of a game that updates the score. In this particular game, which is actually the BASIC Invaders game that well be developing together, a bonus base is given at 10,000 points. The sample flowchart is shown in Figure 1.

Figure 1

    So what does this all mean? First of all, notice how easy it is to understand what's going on. That's because, apart from the funny squares and diamonds, everything is written in English, not BASIC. If you were to take a look at the BASIC program that accomplished the same thing, chances are it would be much more difficult to understand what it was doing. At the same time, it's now quite easy to take this flowchart and make it into a program; a lot easier than taking just the original idea.
    What is it exactly that a flowchart does to make programming easier? When you go to write a program, you start off with an idea of what you want the program to do. Unfortunately, computers don't run on ideas. You have to be able to break this idea down into a series of very concrete steps, and then write these steps in a language that the computer will understand. Most people (including myself), try to go straight from the idea to the computer, taking care of the intermediate steps in their head. As I said before, this works fine if the resulting program is very small, but most people don't have the capacity to keep a lot of precise steps organized in their head for a larger program. The result is a program that takes a long time to write, and even longer time to debug, and ends up looking like a mess. (Be honest, when was the last time you wrote a program that looked as neat and orderly as the ones in the magazines?) Believe me, I know from experience! Anyway, the point I'm taking too long to make is that a flowchart organizes your thoughts for you. It breaks down your terrific idea into a series of concrete steps that can then be easily translated into a program. It also often has the added benefit of letting you see in advance where things might go wrong.
    Now that you're (hopefully) convinced about the benefits of a flowchart, let's take a look at how to create one. Of course, there is nothing to say that you have to follow these rules. Whatever works best for you is fine, but the following guidelines are a good place to start.
    As you saw in our example, flowcharts are made up of a whole bunch of shapes connected by arrows. Inside these shapes are descriptions of each step. Why are there different kinds of shapes? Because there are different kinds of steps. Figure 2 is a summary of the shapes and the kinds of steps they represent.

Figure 2

    You'll see these shapes or symbols throughout future columns, and at the end of this column when we present the complete flowchart for BASIC Invaders. Actually, that's not quite true. You won't see the Input/Output symbol, largely because there is no I/O in the program. How should you use this symbol? In whatever way makes sense to you. As I said before, a flowchart is meant to make things easier for you, so you should use it in whichever way you're most comfortable with.
    Now that you know what a flowchart is and how to make one, you're probably wondering whether or not it's worth the effort to use one. After all, it does take time to do a flowchart, and that time could otherwise be spent programming. Well, we've already seen most of the advantages of flowcharts. They break down a program into small steps that can then be easily programmed; which means that it takes less time to do the programming, which makes up for the time it takes to do the flowchart. Another advantage is that it's often easy to look over a flowchart and see where problems might arise, thus helping you to get rid of bugs before they occur.
    But what about the disadvantages? After all, I've already told you that I lived without flowcharts for seven years; so there must be some disadvantages to them, right? The big disadvantage to flowcharts is the fact that they aren't the easiest things to create, and especially to change. If you're writing a program and you make a mistake or forget something, then it's easy to take out a line or add one But with a flowchart, things start to get messy. Take it from me, never do a flowchart in pen! And, there's no way around it, flowcharts do take time. Even though they'll eventually save you time on the programming, that's no consolation while you're spending hours with a piece of paper and not getting any results on the screen.
    So what's the verdict? Should you use flowcharts, or shouldn't you? My advice is to try them at least once and see what you think. Maybe they'll work for you and maybe they won't. (Just think, you paid money for advice like this!) Personally, I plan on using flowcharts again, but not for everything. I'm one of those impatient souls that needs to see immediate results on the screen.
    So much for our philosophizing, now it's time to get into a real program. As I'm sure you know by now, were going to be developing a BASIC version of the popular Invaders-type program. Appropriately enough, we're going to be calling it BASIC Invaders. In any case, we'll start off by presenting the complete flowchart for the game. As we go through the game piece by piece, it will help you to look at the flowchart and see how the BASIC code relates to it. So, without any further ado, Figure 3 is my flowchart for the BASIC Invaders game.
    Look it over carefully and then keep it in mind as we write the program. Although we won't be referring to it anymore, it will be used implicitly as we put things together.

Figure 3  Figure 3A

Figure 3C

Figure 3D

Figure 3E     Figure 3F    Figure 3H


Figure 3I   Figure 3J    Figure 3L


Another Intrduction
    Don't worry, this will be relatively short and painless. It is an introduction to the program examples that you will be coming across throughout the rest of the text. These examples serve two purposes. First of all, they are examples of the techniques that we will be covering. In this sense, I will do as much as possible to see that it is obvious how similar sections would be written for games other than the one we will be writing here. Second of all, they are, of course, a part of the final game, our BASIC Invaders. Thus they will eventually all fit together to create the game. Because of this, our line numbers are going to be a little off the wall. This is to save you time, since you will eventually be able to merge all the segments together to make a complete program. Thus the line numbers in the various segments are those from the final program.
    And now, our first program. What! How can this be? Well, I mentioned before that I'll be giving you a lot of machinelanguage routines. If you've seen machine-language routines before, you know that they are made up of either a lot of numbers or a lot of funny characters, depending on which technique the author uses. And if you've tried typing in any of these routines, you know it can be a real pain. This column's routines have a grand total of 997 such funny characters. So what do we do? My answer to this problem is the program shown in Listing 1. As you can see, it has numbers, not characters, to make life easier for you. But when you run it, the computer will take these numbers and turn them into characters for you. Neat, huh? Not only that, but it will also check to make sure that you typed in the numbers correctly, and will tell you where you made a mistake if you didn't. Assuming there are no mistakes, the program will create some new lines, because they are the ones that we'll be using in our game. To do this and get rid of the other lines, use one of the following:

LIST "D:MACHINE",29000,32510
LIST "C:",29000,32510

    Of course, which one you use depends on whether you have a disk or cassette.
    Now for a summary of each of the routines stored in the lines the program creates:

    29000-VBLOFF turns off any VBLANK routines you use.
    29500-MOVMEM moves things around in memory.
    30000-MISCLR clears one or more of the missiles.
    30500-MEMCLR clears memory.
    31000-SCROLL takes care of fine and coarse scrolling during VBLANK.
    31500-SCRLON gets SCROLL going.
    32000-32070-PMOVE lets you move players and missiles around easily during VBLANK, which means that you don't have to worry about it from BASIC.
    32500-32510-this isn't a routine, but rather the data for the redefined characters we'll be using in BASIC Invaders.

    Throughout the rest of the columns, you should make sure that these lines are included in any segment that uses one of the above routines. Do this by ENTERing the lines back in before or after typing in the segment.
    Now, after all this hassle, were finally ready to start programming a game.

Looks aren't everything
(but they're a start)
    The first step to writing a game, obviously, is deciding what kind of game you want to write and exactly how things are going to work in it. That's what we did with the flowchart. The next step is deciding how you want the game to look. Perhaps one of the hardest things for a programmer to do is design a game's graphics. Notice that I said "design;" not "program." Before all the dazzling details make it to the television screen, they have to be drawn on paper, and there aren't too many programmers that are also artists. Therefore it often takes more time to get the screen looking just right than it does to actually program it. So let's take a look at what goes into getting a good-looking game.
    We'll start with the obvious. What are the various kinds of shapes that have to be designed for BASIC Invaders? Well, there are three types of aliens and two versions of each (so that they appear to be moving). There's an alien ship and the player's base. We also have the barriers that protect the player. Did we miss anything? How about the explosion that occurs when the player shoots an alien? I bet you didn't think of that. That's about it, though, as far as the shapes are concerned. Of course, there is also the text, such as "SCORE" and so forth, but that's already been created for us. So we're left with a total of nine shapes that have to be designed. Remembering that these shapes have to be made up of dots, let's go! The shapes we'll be using are shown in Figures 4 and 5.

Figure 4


Figure 5

    Of course, it's real easy to look at these shapes and say, "Yup, that's how they look;" but what if you were designing an original game? How do you go about coming up with your own shapes? To start with, you should decide how big you want them to be. In making this decision, you should keep in mind how you're going to put the shapes on the screen. For example, anything that moves is either going to be stored in characters or players; in which case you'll have some multiple of eight dots available for width and height (any number up to 256 for player height). So if you end up with a ship that's, say, nine dots wide, you may want to consider shortening it to eight, or taking advantage of the other seven dots if you're going to use two characters or players. Things that won't be moving, such as the barriers in BASIC Invaders, will be drawn with bitmapped graphics; in which case they can be any size you want (as long as they don't overlap into the part of the screen that has character graphics).
    Once size has been determined, the next step is to come up with the actual shape. The best way to do this is to get some graph paper with reasonably small squares, and block off a section with the number of squares you'll be using for the shape (each square represents a dot). Then sketch a rough version of how you want the shape to look within this area, and color in the squares that your sketch passes through.
    You now have your first version, with heavy emphasis on the word "first:' This is the stage where somebody will look at your brilliantly designed alien and say, "Hey, nice-looking rock:" Don't despair, now is the time to experiment by erasing and filling in dots until you arrive at something that looks good. Luckily, there is a limited number of possible dot combinations; so you're bound to arrive at something that looks right sooner or later. Of course, erasing and filling in dots can be a pain in the you-know-what. The alternative is to use a character editor, which allows you to make these changes on the screen instead of on paper.
    Once you get some shapes that, hopefully, you're satisfied with, what's the next step? Are you finally ready to put your creations up on the screen? Not quite. The final step in designing the graphics is to decide how everything is going to be laid out on the screen. Again, this sounds rather obvious, but nothing is obvious to a computer. Everything must be precisely specified. This step involves deciding where the alien saucer is going to fly, where the barriers will be placed, where the player and the score will go and how far across the screen the aliens and player can travel. A lot of these choices will have to do with the display list, which we'll cover later, but the basics can be decided upon without it. The main thing to keep in mind as far as the display list is concerned is that you can't have character graphics and bit-mapped graphics on the same line. Other than this one restriction, you should lay things out in the way that looks best to you. Figure 6 shows the way we're going to do things for BASIC Invaders.
    Of course, there's no reason why you can't change any of this to suit your own tastes. As a matter of fact, that's a good point to bring up at this stage. Nothing that I do here, with the exception of the programming techniques, has to be done the way it is. If you don't like my aliens, or if you think later that the scoring system should be different, or if you run across anything that you think can be improved, then go ahead and do it. One of the easiest ways to learn how things are done is to make changes. If you're lucky, then your changes won't work right away, and you'll have to go into the program more deeply to find out what's going wrong. I've learned more by doing this than by any other method; so go ahead and play.
    Before we get into the actual programming, there's one more think that should be included that I've already touched on, but haven't really explained. We've already decided that we'll use character graphics for the aliens, bit-mapped graphics for the barriers and (as it will turn out), player/missile graphics for the alien ship and the player's base. How exactly do we go about making these decisions though? Is there a set of criteria that we should use in deciding what to use for which, or can we just do whatever suits us? Obviously I wouldn't have brought it up if we could just choose randomly; so let's take a quick (because it is relatively simple) look at the decision process.

Just what's on the screen!
    There are two basic types of objects on the screen: those that move and those that don't. There are three basic types of graphics that can be used: character, bitmapped and player/missile. Each of these three can be used for either type of object, so you can see that there are a lot of possible combinations. Let's start with the objects that stay still, because they're the easiest. The main rule here is that if the object will change during the course of the game, as in the case of the barriers in Invaders, you should use bit-mapping. The reason is simple; it's much more difficult to change characters than it is to PLOT and DRAWTO. So when should you use character graphics? Sometimes you'll have an object that doesn't move, but is nonetheless animated. Perhaps it's a building with a window that opens and closes, or a flag that waves in the breeze. As you'll see in the columns to come,  this is much easier to do with character graphics than it is with bit-mapping.
    I said that player/missile graphics (PMG) could be used for nonmoving objects as well. Why should you want to use a player for something that doesn't move? After all, the benefit of PMG is that it makes movement easier, right? Right, but it also adds some extra colors to the screen. And, if you're not using all four players, there's no reason why you can't have the ones you're not using sit around and make the screen more colorful.

Things that move
    On to the things that move. As long as we're on the topic of PMG, we may as well start there. PMG is best at moving objects over or under other objects. It's the easiest way to move something, period. Of course, you are restricted to objects that are no more than eight dots wide, unless you position two or more players side by side. This means that PMG would not be of help in moving the invaders in our game.
    How would we move the invaders? Would we use bit-mapped graphics or character graphics? Because they're relatively slow, bit-mapped graphics are not good for much more than moving a couple of dots around, which means that the answer is character graphics (if it's going to have to move).
    Believe or not, that about covers it. You'll find that most games written in BASIC tend to rely a little too much on PMG for movement and bit-mapped graphics for nonmovement or background. Why? Because redefining a character set is usually more difficult than PLOTting and DRAWTOing as far as the background is concerned, and finescrolling (which is needed for smooth character movement) is almost impossible to do well from BASIC. Still, we're going to change things a little, by giving you some handy machine-language routines that can be used just as easily as a BASIC statement to get fast professional-looking PMG and fine-scrolling. With the help of these routines, you should be able to break away from the normal and come up with some truly impressive looking games-and all of this without having to learn one bit of machine language. But we're out of time now. See you.


LISTING 1: BASIC

VW 100 GRAPHICS 0:? "Make sure you have s
   aved a copy of":? "this program before
    RUNning it":FOR X=1 TO 1050:NEXT X
SQ 110 ? :?
RO 120 DIM LN(8):FOR X=1 TO 8:READ DAT:LN
   (X)=DAT:NEXT X
PE 130 DATA 20,41,26,36,112,11,657,128
OJ 140 FOR X=1 TO 8:TOT=8:N=0:GOSUB 1000
NH 150 FOR N=1 TO LN(X):READ DAT:TOT=TOT+
   DAT
HP 160 IF N/25<>INT(N/25) THEN 190
QP 170 T=TOT:TOT=0:READ DAT:IF DAT<>T THE
   N ? "...ERROR":STOP
QY 180 GOSUB 1000
JW 190 NEXT N:READ DAT:IF DAT<>TOT THEN ?
    "...ERROR":STOP
LM 200 NEXT X
AJ 210 RESTORE 20000
OV 220 FOR X=1 TO 8:L=28500+500*X:GOSUB 1
   010
BP 230 FOR N=1 TO LN(X):READ DAT:? CHRS(2
   7);CHR$(DAT);
TJ 240 IF N/25=INT(N/25) THEN READ DAT
NF 250 IF N/90=INT(N/90) THEN GOSUB 1020:
   L=L+l0:GOSUB 1010
RQ 260 NEXT N:READ DAT:GOSUB 1020
MA 270 NEXT X
OH 280 END
LW 1000 ? :? "CHECKING LINE ";19000+1000*
   X+10*INT(N/25);:RETURN
DJ 1010 GRAPHICS 0:POSITION 2,4:? L;" MLA
   NGS=";CHRS(34);:RETURN
CU 1020 ? CHR$(34);":RETURN":? "CONT":POS
   ITION 0,0:POKE 842,13:STOP
UF 1030 POKE 842,12:RETURN
UG 20000 DATA 104,162,228,160,95,169,6,32
   ,92,228,162,228,160,98,169,7,32,92,228
   ,96,2548
QY 21000 DATA 164,104,133,207,104,133,206
   ,104,133,209,104,133,208,104,170,160,2
   55,138,208,2,104,168,177,206,145,3719
EW 21010 DATA 208,136,192,255,208,247,230
   ,207,230,209,202,224,255,208,233,96,33
   40
TH 22000 DATA 104,104,133,207,104,133,206
   ,104,104,168,104,104,133,208,177,206,3
   7,208,145,206,136,192,255,208,245,3931
YN 22010 DATA 96,96
JJ 23000 DATA 104,104,133,204,104,133,203
   ,104,170,169,0,160,255,224,0,208,4,104
   ,168,169,0,145,203,136,192,3396
PM 23010 DATA 255,208,249,230,204,202,224
   ,255,208,234,96,2365
FT 24000 DATA 173,251,6,240,104,173,252,6
   ,141,4,212,173,253,6,141,5,212,173,254
   ,6,240,79,173,48,2,3327
JY 24010 DATA 133,204,173,49,2,133,205,16
   0,3,177,204,201,65,240,61,201,1,240,52
   ,41,112,201,64,144,48,3114
IX 24820 DATA 201,80,144,42,200,173,255,6
   ,48,18,177,204,24,216,109,254,6,145,20
   4,200,177,204,105,0,145,3337
SL 24030 DATA 204,144,20,177,204,56,216,2
   37,254,6,145,204,200,177,204,233,0,145
   ,204,144,2,200,200,200,208,3984
NY 24040 DATA 189,169,0,141,254,6,141,251
   ,6,76,95,228,1556
IE 25000 DATA 104,104,170,104,168,169,6,3
   2,92,228,96,1273
HM 26000 DATA 104,104,104,141,188,6,104,1
   04,141,228,6,141,231,6,141,234,6,141,2
   37,6,238,237,6,141,240,3235
WO 26010 DATA 6,238,240,6,169,127,141,199
   ,6,162,9,160,4,173,47,2,41,16,240,9,16
   9,255,141,199,6,2765
FA 26020 DATA 162,19,160,8,140,200,6,160,
   9,189,206,6,153,189,6,202,136,16,246,1
   69,7,174,240,6,160,2969
OH 26030 DATA 108,32,92,228,96,32,238,6,1
   89,152,6,24,109,200 6,168,205,199,6,14
   4,3,172,199,6,189,2809
BK 26040 DATA 152,6,56,237,200,6,141,201,
   6,136,177,204,200,145,204,136,240,5,20
   4,201,6,176,242,169,0,3450
BE 26050 DATA 145,204,96,32,238,6,189,152
   ,6,56,237,200,6,168,176,2,160,0,189,15
   2,6,24,109,200,6,2759
MY 26060 DATA 141,201,6,200,177,204,136,1
   45,204,200,204,199,6,240,7,204,201,6,1
   44,239 240,237,169,0,145,3855
TM 26070 DATA 204,96,138,72,162,4,32,238,
   6,104,170,189,160,6,56,237,200,6,168,1
   76,2,160,0,189,160,2935
HO 26080 DATA 6,24,109,200,6,141,201,6,13
   6,177,204,61,202,6,145,204,200,200,189
   ,202,6,73,255,49,204,3206
OF 26090 DATA 136,136,17,204,145,204,200,
   200,204,199,6,176,7,204,201,6,144,221,
   240,219,189,202,6,49,204,3719
UU 26100 DATA 145,204,136,189,202,6,49,20
   4,145,204,96,138,72,162,4,32,238,6,104
   ,170,189,160,6,24,109,2994
IH 26110 DATA 200,6,168,205,199,6,144,3,1
   72,199,6,189,160,6,56,237,200,6,141,20
   1,6,200,177,204 61,4.152
BK 26120 DATA 202,,145,204,136,136,189,2
   02,6,73,255,49,204,200,200,17,204,145,
   204,136,136,240,5,204,201,3699
CO 26130 DATA 6,176,224,189,202,6,49,204,
   145,204,200,189,202,6,49,204,145,204,9
   6,189,189,6,133,204,24,3445
GY 26140 DATA 216,173,188,6,125,194,6,133
   ,205,169,0,133,77,96,162,0,188,128,6,4
   8,106,185,120,2,41,2707
MS 26150 DATA 8,208,23,189,148,6,221,136,
   6,240,43,169,0,133,77,254,148,6,189,14
   8,6,157,0,208,208,2931
WH 26160 DATA 28,185,120,2,41,4,208,21,16
   9,0,133,77,189,148,6,221,132,6,240,9,2
   22,148,6,189,148,2652
WY 26170 DATA 6,157,0,208,188,128,6,185,1
   20,2,41,2,208,17,189,152,6,221,144,6,2
   40,30,254,152,6,2668
UX 26180 DATA 32,229,6,138,16,21,185,120,
   2,41,1,208,14,189,152,6,221,140,6,240,
   6,222,152,6,32,2385
EX 26190 DATA 226,6,232,224,4,208,140,162
   ,0,189,164,6,240,83,189,168,6,240,50,1
   6,23,222,156,6,222,3182
NF 26200 DATA 156,6,189,156,6,157,4,208,2
   01,47,176,32,169,0,157,164,6,240,53,25
   4,156,6,254,156,6,2959
EL 26210 DATA 189,156,6,157,4,208,201,208
   ,144,9,169,0,157,164,6,240,106,208,196
   ,189,172,6,240,57,16,3208
XO 26220 DATA 23,222,160,6,222,160,6,32,2
   32,6,189,160,6,201,16,176,39,169,0,157
   ,164,6,240,74,254,2920
AI 26230 DATA 160,6,254,160,6,32,235,6,18
   9,160,6,24,216,105,16,205,199,6,176,4,
   41,240,208,7,169,2830
AX 26240 DATA 0,157,164,6,240,42,189,176,
   6,61,0,208,240,13,169,255,157,176,6,15
   7,184,6,169,0,157,2938
NV 26250 DATA 164,6,189,180,6,61,8,208,24
   0,13,169,255,157,180,6,157,184,6,169,0
   ,157,164,6,232,224,3141
KA 26260 DATA 4,208,145,76,98,228,0,759
NF 27000 DATA 0,0,0,0,0,0,0,0,1,3,7,13,15
   ,2,5,10,128,192,224,176,240,64,160,80,
   1,1321
MD 27010 DATA 3,7,13,15,5,8,4,128,192,224
   ,176,240,160,16,32,8,4,15,29,31,23,20,
   2,16,32,1403
PT 27020 DATA 240,184,248,232,40,64,2,20,
   23,29,31,15,4,8,64,40,232,184,248,240,
   32,16,3,15,31,2245
CH 27030 DATA 25,31,6,9,48,192,240,248,15
   2,248,96,144,12,3,15,31,25,31,13,24,12
   ,192,240,248,152,2437
XA 27040 DATA 248,176,24,48,0,9,5,0,12,0,
   5,9,0,32,64,0,96,0,64,32,16,16,56,56,1
   24,1092
UU 27050 DATA 124,198,198,520