T H E K E N T T E A M P R E S E N T T H E C O M P L E T E A M O S A L M A N A C I N T R O D U C T I O N As this series was originally printed one article at a time and backed up by monthly CoverDisks, you may find at times that the text assumes that, for instance, you have a few sprites or a background picture on which to practice. These files would have been supplied with the original article. Simply substitute example files from the Amos program disks when this situation arises. Issue 42 ­ November 1991 ` Putting together various previously discussed "modules" as the Pacman game begins to take shape Entertainment software is big business now, and people have to be a little bit more creative to produce a good game, something which can be distinctly different to a good seller! Hopefully Amos will help you to spend a lot more of your time exercising these creative energies. One important thing to remember about games software is that a lot of programmers cheat. We have covered different methods of `cheating` in previous issues. Some of the most amazing effects seen in games are, in fact, merely illusion ­ screen swapping, colour cycling and palette switching are just some of the ways to get amazing results without compromising the speed of your program. Almost anybody can use these methods, but the real skill is in integrating them with the software so that they are invisible to the player, while at the same time making him or her think `wow, I wonder how they did that`?. OK, the first step in any piece of software is to set up your screen, we`ve done all of this before ­ if you missed it then buy the back issues ­ so I won`t take you through all of the old details again: ' Set up Screen Open 0,320,200,16,Lowres Curs Off Flash Off Cls 0 Get Sprite Palette Double Buffer Autoback 0 Now we have the task of initialising all of the variables that we will use. Although Amos ­ and most other versions of Basic for that matter ­ does not require you to do this, it is a habit you should get into. After all, you won`t be using Amos forever, will you` We will need to keep track of the X and Y position of our character, so we will use two variables call X_GOOD and Y_GOOD. As well as storing the position of our character the joystick status will have to be stored, so we will call that variable WAY: X_GOOD=150 Y_GOOD=100 WAY=0 Of course we will also need to move the bad guy around, so we will call its X and Y co-ordinates X_BAD and Y_BAD: X_BAD=0 Y_BAD=0 Finally we may want to introduce individual speeds for each of the characters in the game, so we will call these ­ guess what? ­ GOOD_SPEED and BAD_SPEED. Notice that by using meaningful variable names we can tell a glance what a particular section of code is doing, but be careful of falling into the trap of ending up with variable names 40 characters long ­ they can be a real drag to type in! GOOD_SPEED=1 BAD_SPEED=1 Ohhhh, I almost forgot. This game is very simple and because of this it is going to be blindingly fast, so in order to slow it down we will only update everything occasionally. It sounds strange I know, but all will become clear very soon. The variable we are going to use to control this is called T ­ or time! ­ and the variable used to hold the score is called SCORE: T=1 SCORE=0 Now we have to stick the player and the bad guy on to the screen. For this example program we are using BOBs, but you could use hardware SPRITEs: Bob 1,X_GOOD,Y GOOD,1 Bob 2,X_BAD, Y_BAD,2 Now for the main part of the game: Repeat The first line here tells the program that we only want to execute everything inside the IF structure when the variable T has a value of two. At the moment it only has a value of one: If T=2 Our next task is to check the joystick to see if a movement has been made. We will use the JOY() function rather than the JUP/JDOWN functions, because it is more versatile. A fuller explanation as to why this is will be given in the next issue. We store the current joystick value ­ which is a number between 0 and 16 ­ in the variable WAY. If WAY has a value greater than zero then we know that the joystick is being moved, and we can then test the direction and move our character: WAY=Joy(1) If WAY>0 At this point we know that our man has moved so we can increase the score by one: Inc SCORE Now comes the joystick testing bit. In a previous issue we saw how the JOY() function returns values depending on how it is currently positioned. Just to recap, these are the values for the four basic directions: UP=1, DOWN=2, LEFT=4, RIGHT=8. Knowing this we can see if the player wants to move the character and so can increase/decrease the X_GOOD/Y_GOOD variables accordingly: If WAY=8 Add X_GOOD,GOOD_SPEED,0 To 319 End If If WAY=4 Add X_GOOD,-GOOD_SPEED,0 To 319 End If If WAY=1 Add Y_GOOD,-GOOD_SPEED,0 To 199 End If If WAY=2 Add Y_GOOD,GOOD_SPEED,0 To 199 End If Another trick when writing a game is not to update anything on the screen unless it has moved. For this reason we will only redraw our little character when the joystick has been moved: Bob 1,X_GOOD,Y_GOOD,1 End If Here is a tricky question, with a very simple answer. How do you make a nasty home-in on your good guy? Well, imagine you were playing a game where you had to run after somebody. The brain would follow a simple set of rules, like: `If the person is to the left of me, I must move left,` and, `if the person is in front of me I must move forward.` These are the simple rules we can follow to make a `homer`. Of course most games have a slightly longer list of rules to control movement of bad guys and good guys, but at the end of the day they are still only a list of rules that the program must ollow. I am sure you have played many games where after a while you realise that if you perform a certain action at a certain point, you can make the program do the same thing almost every time. This is because it is just following a set of simple ­ or com licated ­ rules: If X_GOOD0 and BLOCK<9 Paste Icon LOP2*16,LOP*16,BLOCK End If Next LOP2 Next LOP The maze! Data "12222222222222222223" Data "48888888888888888884" Data "48123812381223812384" Data "484 485268522684 484" Data "484 488888888888 484" Data "48526812222223852684" Data "4888884 4888884" Data "48123852222226812384" Data "484 488888888884 484" Data "48526812222223852684" Data "4888884 4888884" Data "5222226 5222226" Erm? What next? Well, it's a bit of a surprise actually. The method I have just showed you to draw the maze screens is OK, but we need a quick way to look at the maze shape to find out where the blocks are. This way we can control the movement of any creatures we decide to put into the maze without resorting to slow and complex collision detection commands. So we will now put all of the data needed to create a maze into an Amos memory bank which will be 240 bytes long (20 blocks wide x 12 blocks tall): Reserve As Work 10,240 We now have to set up that funky screen and load those icons again: Screen Open 0,320,200,16,Lowres Flash Off Curs Off Cls 0 Get Icon Palette Load "MAZE_ICONS.ABK" This time we will read the data into memory bank 10 which we reserved earlier: For LOP=0 To 11 Read MAZE$ For LOP2=0 To 20 BLOCK=Val(Mid$(MAZE$, LOP2+1,1)) Take note of the formula that is used to calculate the position of each block ­ we will use a slightly adapted version of this for collision detection: POSITION=Start(10)+(LOP*20)+LOP2 Poke POSITION,BLOCK Next LOP2 Next LOP Once that is stored we can draw the screen by reading the data. Simple formula time! Next month when we start to more our pacman around the maze, and will need a routine to make sure it does not career into any walls. We can find this out by constantly keeping a track of the position of our pacman and then using the following formulae to see if any walls blocks its path: UP=((Y-1)*20)=X DOWN=((Y+1*20)+X LEFT=(Y*20)+(X-1) RIGHT=(Y*20)=(X+1) If that seems a little bit confusing don't worry, everything will become clear as mud (sorry crystal)... Issue 44 ­ January 1992 ` Making our pacmen move around the maze In the days before hardware sprites and automatic collision detection, programmers still managed to produce games by looking at position of players, enemies and background objects. They could then calculate whether or not they overlapped. The first thing we must do to do this is set a working screen and load the Pacman sprites and maze icons in memory: Reserve As Work 10,240 Screen Open 0,320,200,16,Lowres Flash Off Curs Off Cls 0 Hide On Load `MAZE ICONS.ABK` Load `PACMAN_SPRITES.ABK` Get Icon Palette OK, now we must define some simple variables. Those of you who have just started to learn how to program will notice the GLOBEL statement. This lets our program know that the variables X and Y are used in all parts of the program (including procedures). If we did not execute this command, the procedures - which are really mini programs, independent of the main one ­ would assume that the variables X and Y were used only in themselves. It is probably easier to think of the GLOBEL as making the proced res share information: Globel X,Y X=1 Y=1 MAKE_MAZE OK, now is the interesting part. The formulas which are calculated into the variables UP, DOWN, LEFT and RIGHT check the position of our Pacman compared the maze data we have stored in bank 10. If the joystick is pushed in a direction and there is a pill found there, the program will move the Pacman and erase the dot accordingly! If you remember how we built up the maze last time you will recall that the pills had a value of eight: Repeat UP=((Y-1)*20+X DOWN=((Y+1)*20+X LEFT=(Y*20)+(X-1) RIGHT=(Y*20)+(X+1) Bob 1,16*X,16*Y,2 Wait 2 WAY=Joy(1) If WAY<>0 If WAY=1 and Peek(Start(10)+UP)=8 EACH_DOT Dec Y End If If WAY=2 and Peek(Start(10)+DOWN)=8 EAT_DOT Inc Y End If If WAY=4 and Peek(Start(10)+LEFT)=8 EAT_DOT Dec X End If If WAY=8 and Peek(Start(10)+RIGHT)=8 EAT_DOT Inc X End If End If Until False End This procedure erases the pill when the Pacman moves: Procedure EAT_DOT Cls O,X*16+6,Y*16+6 To X*16+12,Y*16+12 End Proc The following procedure is identical to the one we wrote last month to draw the maze: Procedure MAKE_MAZE For LOP=0 To 11 Read MAZES ' For LOP2=0 To 20 BLOCK=Val(Mid$(MAZES,LOP2+1,1)) POSITION=Start(10)+(LOP*20)+LOP2 ' Poke POSITION,BLOCK ' Next LOP2 ' For LOP=0 To 11 For LOP2=0 To 19 BLOCK=Peek(Start(10)+(LOP*20)+LOP2) If BLOCK<>0 Paste Icon LOP2*16,LOP*16,BLOCK End If Next LOP2 Next LOP Wait Vbl Double Buffer ' Data `12222222222222222223` Data `48888888888888888884` Data `48123812381223812384` Data `484 485268522684 484` Data `484 488888888884 484` Data `48526812222223852684` Data `4888884 4888884` Data `48123852222226812384` Data `484 488888888884 484` Data `48526812222223852684` Data `4888884 4888884` Data `5222226 5222226` End Proc Issue 45 ­ February 1992 ` Introducing ghosts to chase your pacman As you will recall, we have now generated our maze and made a Pacman travel around it with our joysticks ­ now it`s time to introduce a nice ghostie to chase you. Some of the code we will be looking at will be familiar to you, but there are subtle differences between the program we looked at in the last issue and this one. First we open our screens and reserve our bank to store the maze data. Then we load in the sprites and icons: Reserve As Work 10,240 Screen Open 0,320,200,16,Lowres Flash Off Curs off Cls 0 Hide On ` Load `PACMAN_SPRITES.ABK` Load `MAZE_ICONS.ABK` Load `MAZE_ICONS.ABK` Get Icon Palette Note that most of the code is now in separate procedures. This is to keep matters a little clearer when explaining things. As you write your own programs you will find it much more efficient to break them down into smaller, more manageable parts. This means that all of our variables must be declared as Global ­ if we do not do this, our procedures will not recognise them! The next step is to generate the maze and execute the main loop: MAKE_MAZE Repeat Wait 2 Right, because we have changed things a little, the program now checks the joystick and moves our pacman by calling two procedures: CHECK_STICK DO_PACMAN Because our ghost is moving quite quickly we need to weigh the odds in our favour a little. To do this we will use a variable counter called PASS. Every time the loop is executed we increment this variable, and when it reaches three we move the ghost. So for every three moves we could make, the ghost will make one: If PASS=3 DO_GHOST End If Add PASS,1,1 To 3 Finally, we will check to see if the ghost has hit the Pacman by comparing their co-ordinates. BX & BY are the ghost`s position X & Y are the Pacman`s position in the maze: Until(BX=X and BY=Y) End The next procedure is the one which makes the ghost so hard to beat. Remember how a couple of issues ago we looked at baddie intelligence` This program uses exactly the same method and follows these rules: 1] IF PACMAN IS LEFT OF GHOST THEN MOVE GHOST LEFT ELSE MOVE GHOST RIGHT 2] IF PACMAN IS ABOVE GHOST THEN MOVE GHOST UP ELSE MOVE GHOST DOWN Of course, if a wall is in the way the pacman cannot move. You can easily overcome this by introducing more complex rules. Remember ­ baddie intelligence is always governed by a set of rules, simple or complex: Procedure DO_GHOST If BX<>X GHOST_RIGHT Else If BX>X GHOST_LEFT End If End If If BY>Y GHOST_UP Else If BY<>Y GHOST_DOWN End If End If Bob 2,16*BX,16*BY,4 End Proc The following procedures check to see if a wall is in the way before moving the ghost. Any value found in the maze band other than eight is classified as a wall. In more complex versions of the game you could check for power pellets, bonus fruits, and so on: Procedure GHOST_LEFT B LEFT=(BY*20)+(BX-1) If Peek(Start(10)+B_LEFT)=8 Dec BX End If End Proc Procedure GHOST_RIGHT B_RIGHT=(BY*20)+(BX+1) If PEEK(Start(10)+B_RIGHT)=8 Inc BX End If End Proc Procedure GHOST_UP B_UP=((BY-1)*20)+BX If Peek(Start(10)+B_UP)=8 Dec BY End If End Proc Procedure GHOST_DOWN B_DOWN=((BY+1)*20)+BX If Peek(Start(10)+B_DOWN)=8 Inc BY End If End Proc CHECK_STICK looks at the value stored in JOY(1). This contains a bitmap of the joystick position. If the value found is one it means that you are pushing the joystick up, two means down, four is left and eight is right. Just for reference, if the value of 16 is found then you have pressed Fire on the joystick! Procedure CHECK_STICK WAY=Joy(1) If WAY<>>0 If WAY=1 and Peek(Start(10)+UP)=8 EAT_DOT Dec Y End If If WAY=2 and Peek(Start(10)+DOWN)=8 EAT_DOT Inc Y End If If WAY=4 and Peek(Start(10)+LEFT)=8 EAT-DOT DEC X END IF IF WAY=8 AND Peek(Start(10)+RIGHT)=8 EAT_DOT Inc X End If End If End Proc This procedure does exactly the same as the routine we looked at last month. Basically it looks at the four directions surrounding the pacman to discover if a wall is in the way. It stores this information in the global variables UP, DOWN, LEFT, RIGHT: Procedure DO_PACMAN UP=((Y-1)*20)=X DOWN=((Y=1)*20)+X LEFT=(Y*20)+(X-1) RIGHT=(Y*20)+(X+1) Bob 1,16*X,16*Y,2 End Proc The next procedure does, guess what? Yes it erases the dot! Procedure EAT_DOT Cls 0,X*16+6,Y*16+6 To X*16+12,Y*16+12 End Proc Finally comes the procedure to generate the maze, which we looked at in depth a couple of issues ago. Procedure MAKE_MAZE For LOP=0 To 11 Read MAZE$ ` For LOP2=0 To 20 BLOCK=Val(Mid$(MAZE$,LOP2+1,1)) POSITION=Start(10)+(LOP*20)+LOP2 ` Poke POSITION,BLOCK ` Next LOP2 Next LOP ` For LOP=0 To 11 For LOP2=0 To 19 BLOCK=PEEK(Start(10)+(LOP*20)+LOP2) If BLOCK<>>0 Paste Icon LOP2*16,BLOCK End If Next LOP2 Next LOP Wait Vbl Double Buffer ` Data "12222222222222222223" Data ... Issue 46 ­ March 1992 ` Taking a break from Pacman, and looking at Easy Amos, as well as some Funschool tips Easy Amos is basically a version of Amos which has been designed for people who don`t know much about computer programming but want to learn, as well as people who know a little but find Amos just a little too daunting. To describe it as a cut down version of Amos is a little unfair ­ there are a few commands and facilities which are missing (like menus) but it makes up for them with some really great new ones (like commands to load and play Soundtracker music without conversion!). Easy Amos really is looking splendid. The manual ­ written by computer veteran Mel Croucher ­ is humorous and informative and incorporates lots of cartoons. There are loads of example programs on the accompanying disk which are documented and discussed in the manual, so there is only a little typing for those keyboard-shy beginners! The whole appearance of the user interface has changed since its parent (Amos) was written. Everything is made up from the grey relief type boxes which we are so used to seeing in Workbench 2, and the editor now uses an eight colour screen to improved the rather bland look associated with four colour examples. Everything about Easy Amos oozes friendliness. You can customise the actual language and the accompanying demos with your own name! It really is aimed at the absolute beginner. One of the more advanced features of this new Amos is the Tutor. It is, in fact, a full source code debugger which will allow you to single step through your program in order to test it. You can set up break points and even set your own screens, Bobs, text and graphics up in a shrunk down window. This is really amazing and has to be seen to be believed. I understand that Europress Software will be taking this feature and adding it to an improved `full` version of Amos currently dubbed `Amos II`. Roll on that day!!! HERE`S a fabo tip for all of you programming Fun School 4 owners. On the Under 5s and 5 to 7s package a new experimental sound extension has been used! This is compatible with the StarTrekker program (a SoundTracker clone) and will allow you not only to play Soundtracker modules without using that dodgy converter but also supports the synthetic instrument/Sound FX option in StarTrekker! The file is called `MUSIC.LIB` and is a direct replacement for the `MUSIC.LIB` file contained inside your `Amos_SYSTEM` directory, so all you have to do is copy it across. Unfortunately I do not have any details of the playing commands so you will have to route around the FS4 programs for more information about that. Issue 47 ­ April 1992 ` An introduction to AMAL, the powerful Amos sub-language Now it's time to really break free and attempt a task using something really meaty (or soya-beanie) if you are vegetarian) ­ AMAL. We have covered AMAL previously, but not to write a whole game. Over the next couple of issues I will be showing you how to get the most out of this sub- language and more importantly how to use it in conjunction with the other (less powerful) parts of Amos. You will notice that I have referred to AMAL as a sub-language. This is because it is a separate part of Amos and is quite capable of existing by itself. In many respects AMAL is similar to assembly language, especially in its use on mnemonics to represent the commands we use to create an AMAL program, and like assembly language, it must be well structured in order to keep tracks of any tasks we may ask of it. To control AMAL we use a series of Channels ­ 16 in all. These can be assigned to control a single AMAL mini-program which will run alongside your main Amos program. Let's look at a way of using of AMAL. First we set up an AMAL channel using a command like this: Channel 1 To Screen Display 0 This would prepare your channel to accept an AMAL program. Now we will tell AMAL to feed the mouse co-ordinates into the external registers RA and RB, after which we will read and display them onscreen. One thing to remember about AMAL is that you must type it exactly otherwise errors can occur quite easily. This is due to the fact that AMAL is case sensitive ­ that is, it can tell the difference between upper and lower case letters: mal 1,"Start: Let RA=XM ; Let RB=YM ; Jump Start ; " Amal On1 Repeat Print At(0,0);Amreg(0);" " Print At(0,1);Amreg(1);" " Until False AMAL registers are like ordinary variables in Amos itself, and can be used to store numbers for calculations or later use. These are two types of AMAL register, internal and external. The internal registers are labelled R0 to R9 and are mainly used for temporary storage of values within an AMAL program. The external registers are labelled RA to RZ and are (or at least should be) used for communicating with the outside world. Reading these registers from your main Amos program is simple ­ we just use the AMREG() command (see your Amos manual for a fuller explanation of AMREG). Incidentally, you can store values in the AMAL registers from your main Amos program once again using the AMREG() command.. Being a fully featured sub-language means that AMAL programs can be quite long. For this reason AMAL allows you to structure commands within strings. I know it sounds a little weird but you do get used to it ­ trust me! In the previous example we saw how to create a simple loop jumping from the end of the string back to the label "Start". Labels used for structuring AMAL programs are all single letters of the alphabet, in upper case. Because AMAL ignores all lower case letters you can pad out the label to create something a little more meaningful. The next example is made up of may smaller strings "glued" together t create a single long string. You don't really want to know this but joining two or more strings together is known as concatenation: Channel 0 To Screen Display 0 A$=" Start:" A$=A$+" Pause ; " A$=A$+" Let Y=YM-100 ; " A$=A$+" If XM-160<64 Jump Start ; " A$=A$+" Let X=XM-160 ; " A$=A$+"Jump Start ; " Amal0,A$ Amal On 0 This program will work in direct more and will allow you to move the default screen around with the mouse. It's a little like the larger program which appeared last month. Notice the way I have put each command on a separate line. I have also padded out the short labels and commands with lower case letters so that should I come back to the program in a couple of months I will be able to work out what it does quite easily. AMAL also allows you to execute a simple form of FOR`NEXT loop, the main difference between the AMAL version and the actual Amos version of the loop is that you cannot perform STEPs (if you are unsure what a STEP is, check your Amos manual). The following example does the same job as the previous program, but only for a limited amount of times: Channel 0 To Screen Display 0 A$=" For R0=1 To 80" A$=A$+"Start: " A$=A$+" Pause ; " A$=A$+" Let Y=YM-100 ; " A$=A$+" If XM-160<64 Jump Start ; " A$=A$+" Let X=XM-160 ; " A$=A$+"Next R0 ; " Amal0,A$ Amal On 0 If you look at the Amosteroids game which came with Amos you will see that most of the work is dome by AMAL ­ it controls the starship and asteroids. In fact the only things Amos has to do is play the samples and update the score during the game. These AMAL programs need not be limited to controlling aliens in Xenon MXXIIX ­ how about using them to make Bobs to follow your mouse` Or making constant calculations and feeding them into your main program using the AMAL registers? Issue 48 ­ May 1992 ` Rewriting the Pacman game to take advantage of AMAL If you can cast your mind back a couple of months, we were playing around with simple Bob movements using Amos. Our goal was to create a small Pacman game, which we did. Now we will look at a different method of creating such a game, using the Amos sub-language AMAL. We took a look at the major AMAL functions in the last issue so I won`t be going into too much fine detail concerning the basic functions. Instead we will concentrate on the structure of an AMAL program. The first thing to do is load in the Bobs for the game and set up our default screen stuff. If you are unsure how to get these Bobs loaded in ­ trust me when I say it`s not quite as straightforward as it sounds.. Load `GAME_SPRITES.ABK` Screen Open 0,320,200,16,Lowres Curs Off Flash Off Cls 0 Get Sprite Palette Double Buffer Autoback 0 Now comes the time to define our AMAL string. As you can see, I have built the program up into the string A$. AMAL ignores spaces so I have taken advantage of this to produce a clear piece of code which is easy to look at and ­ hopefully ­ to understand. The first line sets up a label `Start:` and after a brief pause stores the current joystick value in the register R0: A$=" Start: Pause ; Let R0=J1 ; " By using comparisons we can then jump to routines depending on the current joystick action. As I have said before, the numbers returned by the joystick are 1=up, 2=down, 4=left, 5=right and in turn 9=up plus right (8+1=9), 6=down plus left (2+4=6) and so on. A$=A$=" If R0&8 Jump Right ; " A$=A$=" If R0&4 Jump Left ; " A$=A$=" If R0&1 Jump Up ; " A$=A$=" If R0&2 Jump Down ; " A$=A$=" Jump Start ; The next four routines perform the actual movements of the Bob ­ for more details of how the Move command works see your Amos manual. A$=A$+"Right: ; " A$=A$+" Move 10,0,2 ; " A$=A$+" Jump Start ; " A$=A$+"Left: ; " A$=A$+" Move -10,0,2 ; " A$=A$+" Jump Start ; " A$=A$+"Up: ; " A$=A$+" Move 0,-10,2 ; " A$=A$+" Jump Start ; " A$=A$+"Down: ; " A$=A$+" Move 0,10,2 ; " A$=A$+" Jump Start ; " ` For LOP=1 To 15 Bob LOP,Rnd(150),Rnd(100),1 Channel LOP To Bob LOP Amal LOP,A$ Next LOP ` Wait Vbl Amal On ` Direct OK, so you don`t want to structure your AMAL programs, you could shorten them by just using the UPPERCASE characters. Just look at the following AMAL string. If you value your sanity, don`t try to type it in! A$="S:P;LR0=J1;" A$=A$+"IR0&8JR;" A$=A$+"IR0&4JL;" A$=A$+"IR0&1JU;" A$=A$+"IR0&2JD; " A$=A$+"JS;" A$=A$+"R:;" A$=A$+"M10,0,2;" A$=A$+"JS;" A$=A$+"L:;" A$=A$+"M-10,0,2;" A$=A$+"JS;" A$=A$+"U:;" A$=A$+"M0,-10,2;" A$=A$+"JS;" A$=A$+"D:;" A$=A$+"M0,10,2;" A$=A$+"JS;" Having fun` I hope so! The final part of this exciting instalment gives us an AMAL-controlled player and baddie: Load "GAME_SPRITES.ABK" Screen Open 0,320,200,16,Lowres Curs Off Flash Off Cls 0 Get Sprite Palette Double Buffer Autoback 0 Bob 1,150,100,1 Bob 2,20,20,2 The string A$ is exactly the same as in the first program except that the horizontal and vertical positions of the player are fed into the external registers RA and RB. These are then read inside the baddie control program stored in B$ to make that the evil beastie tracks us down! A$=" Start: Pause ; Let R0=J1 ; " A$=A$+" Let RA=X ; Let RB=Y ; " A$=A$+" If R0&8 Jump Right ; " A$=A$+" If R0&4 Jump Left ; " A$=A$+" If R0&1 Jump Up ; " A$=A$+" If R0&2 Jump Down : " A$=A$+" Jump Start ; " A$=A$+"Right: ; " A$=A$+" Move 10,0,2 ; " A$=A$+" Jump Start ; " A$=A$+"Left: ; " A$=A$+" Move -10,0,2 ; " A$=A$+" Jump Start ; " A$=A$+"Up: ; " A$=A$+" Move 0,-10,2 ; " A$=A$+" Jump Start ; " A$=A$+"Down: ; " A$=A$+" Move 0,10,2 ; " A$=A$+" Jump Start ; " ` B$=B$+"Start: Pause ; " B$=B$+" If X>RA Jump Right ; " B$=B$+" If XRB Jump Up ; " B$=B$+" If XDX2 : T=DX1 : DX1=DX2 : DX2=T : End If If DY1>DY2 : T+DY1 : DY1=DY2 : DY2=T : End If End If Until GOTIT Gr Writing 1 End Proc Once the button is released the window is redrawn to the new size. When the new co-ordinates have been stored the old Zone is cancelled and re-drawn to the new size, and it's all ready to start again. And there you have it, perfect windows, and not a single patch of putty in sight. Now you can create multiple-windowed programs and multi-windowed games too! How about a Dungeon Master clone in the PD then? Issue 57 ­ February 1993 ` How to put music to your creations It seems that every program on the Amiga written with Amos has some lovely piece of music to go with it. Don't you wish that you could make music like that` Well you can. It's tempting to steal other people's music off of bulletin boards, demos and so on. But wait, don't touch that dial. The tracker programs you need to make beautiful music are all public domain, with the exception of certain versions of MED which are what they call "licenceware". These disks costs a bit more than PD disks, but the author of the program gets a royalty every time the program is sold. They almost always feature what we call in the trade a "pattern editor" like you find on most modern drum machines and certain Mini sequencers. The sounds in trackers are always samples, like the kind you can make with your own sound sampler, with the exception again of MED which also uses the sound chip in the Amiga to create synthesized sounds, what we call "chip music". Most trackers come with disks of sounds for you to get started. The way they work is that you assemble patterns, short sequences of music lasting for 64 beats. Then when you've made a pattern for your verse, chorus and other fill-ins etc, you chain them all together to make a complete piece of music. You specify which pattern you'd like to play and in what order, and the program plays each pattern in turn to make meaningful music. Sometimes. So for example you could have an intro on pattern 1, a verse on pattern 2, a chorus on pattern 3 and a fill-in on pattern 4. The real kick of a pattern- based sequencer is that you only have to input your patterns once and then they can be played and arranged as many times as you like, rather than a more linear system which would mean you'd have to type the tune in every time. Creating pleasant music with a tracker is easy, as you can have four tracks (in some cases even eight with programs like OctaMED Professional) and you can put the notes in one at a time in what we call "step time", or play along with the other tracks live on the keyboard in what is termed "real time". Step time is easier for learners as you can fiddle about with each track of the pattern until it sounds right, like typing words into a wordprocessor and editing them until the spelling and syntax is perfect. Once a piece of tracker music has been made, or produced, you can convert it to Amos ABK format and load it into a program or into a bank in direct mode. The Amos disks contain many different converters to serve most of the different kinds of trackers such as Noisetracker, Soundtracker, StarTrekker, Protracker, Games Music Creator, Sonix and so on. All you do is run these very clever little Amos programs and they read in a tracker file and spit out a ABK file onto disk ready to be loaded. Some of these programs work fine, but the problem is that so many of the tracker programs (being in the PD for some time now) have all been revamped and re- written so that they are very different in format from the originals. Some tracker tunes will not play properly once they've been converted. Usually the reason is that the samples are too long or the system has changed. Either the tracker has a pattern length which is variable and not fixed at 64, or it stores its samples in a different way. Luckily, there are ways around this ­ see the programs documented in the box on this page for some ideas. Do try to cultivate the use of tracker programs. You'll find they are not as hard to use as you might think, and the results will be all your own work, rather than just a steal from someone else. A recent addition to the Déjà Vu licenceware library is Music Engine by Paul Townsend (aka Technical Fred Software). This program lets you use tracker music without having to convert it. What this program provides is an interface between Amos and the Shell. You can use this to play many different music file formats, and this is done by running an appropriate "player program" which means you can hear the music without having to convert it. Once you've bought the Music Engine program from Déjà Vu, you are free to use the source code, if it's for public domain, shareware or licenceware use, providing of course you acknowledge the source of your source. If you want to use the routines in a piece of commercial software, however, then you have to contact the programmers to arrange a suitable fee. Music Engine is a very powerful tool, and not just for driving music programs. The trick is a very good one, and although it's handy for music, it's powerful enough to run any program from the Workbench, effectively making your Amos system multitask with other programs. For more details of Music Engine (disk number LPD79) get in touch with Déjà Vu Software, or write direct to: Technical Fred Software, 117 Hilton Lane, Walkden, Worsley, Manchester M28 5TB. Phone or Fax: 061-703 7842. Another fine program disk from the Amos PD Library is the MED Utils disk, containing a copy of MED v2.13 and some convert utilities to make the SoundTracker modules from MED more palatable to the ST-to-ABK converters. The disk number is APD155 Lucky users of Amos Professional will know that, of course, Amos Pro is able to use files from MED and Noisetracker (and it's various clones) directly using libraries and features built into the program. If you are using Amos Pro you don't need to use a converter or any of the programs mentioned. You do however need a copy of MED or Noisetracker to make the music in the first place. I should also say that the most up to date version of MED isn't in the public domain, but is available as licenceware, where the author gets a fee each time the program is bought. You can get information about MED from Amiganuts United, 12 Hinkler Road, Southampton SO4 6FT Issue 58 ­ March 1993 ` Vectors ­ what they are and how to move them Moving sprites on the screen is a pain in the bum, and no mistake. First you have to get the damn things moving and then you've got to hold their hand every step along the way, seeing what they hit, and then deciding how to bounce off or explode depending on what the object you've hit is. It's like having kids, or something. Wouldn't it be so much nicer if you could just send an object off in a certain direction and not worry about it until it actually does hit something? Well, you can. But first a bit of maths (groan). No, don't turn the page. Maths is a good thing. Keep that thought in mind and you'll last a lot longer as a programmer! Vectors are a method of moving objects around quickly and simply, with no complex calculations or faffing about. They should be thought of as a change of direction of an object (or point in space), rather than the usual way of moving objects which is manually hiking them about using INC, DEC or things like X=X+1. It's the difference between picking a toy car up in the air and putting it manually in another place (the old method) and pushing it along the ground and letting go (like vectors). In Amos terms it works like this. As usual you use the standard pair of variables to hold the X and Y co-ordinates of the sprite or Bob position. So for example this is the vector demo program: Curs Off : Hide : Flash Off : Cls 0 : Ink 4,4 : Paper 0 Input "What X ";DX# Input "What Y ";DY# It's traditional to use the variables DX and DY, as these variables will tell anyone reading your program that these are vectors. If your vectors are designed to use an FPU (floating point unit), then append them with a hash or # symbol. In this demo program you start by inputting the x and y direction vectors ­ this has a result on the direction that the sprite will go. It's best to try a range of numbers between -8 and 8 for each of the vectors. First the vectors you require are accepted through the input command and stored in two variables called DX and DY: Cls 0 : Bar 0,0 To 5,5 Get Bob 1,0,0 To 6,6 Cls 0 The Bob used in the program is grabbed from the screen using Get Bob, having first been placed there using a Bar command. This is a good way of making simple sprites without having to mess about with sprite editors or anything silly like that. Next we want to talk about X and Y, which in this case are floating point numbers so they are appended with #: X#=160 : Y#=100 Then the start position of the Bob is set to X=160 and Y=100, or slap dab in the middle of the screen, as the screen we are looking at 320 by 200: While X#>0 and X#<320 and Y#>0 and Y#<200 Bob 1,X#,Y#,1 Wait Vbl X#=X#+DX# Y#=Y#+DY# Wend End The While Wend loop moves the sprite in the direction given by the vectors. After a while of running this program you'll be able to predict the precise direction. The Bob is moved until it reaches the edge of the screen, either less than screen position 0 at the top or left of the screen, or screen position 320 or 200 to the right or bottom. Each time the While Wend goes around, the DX and DY vectors are added to the current co-ordinates, affecting the direction of the sprite. The DY and DX vectors can be positive or negative, and the speed of the movement can be varied too. You can put random speeds and random directions into a sprite making it possible to simulate the bouncing of a ball in a ping pong or squash game, or you can even simulate gravity, if you have the right formulae. This is a very cool and efficient way of shifting objects around, and with a little bit of experimentation you can create very realistic movements for your sprites with very small code. A lot of Aaron Fothergill's ten-liners (Amos games written in just ten lines of code!) use vectors to chop down the amount of code needed to do very intelligent things. If you haven't seen any of these disks, then join the Amos Club right away! Why aren't you a member? If you're into Amos you might like to join the club. Write for details to Amos Club, 1 Lower Moor, Whiddon Valley, Barnstaple EX32 8NW. You can even do vectors in 3D, but this is more complex (worth looking in to though!). Obviously you have facilities at your disposal in Amos 3D to translate objects in 3D, but a little bit of vector magic wouldn't hurt for some really special effect. The whole point is that vector riffs are small compared to those really big routines which you can end up with when you try to do this stuff by hand. S O U R C E This is a collection of Amiga Computing magazine's Amos columns, issues 42 to 58, Nov 1991 to March 1993! I M P O R T A N T This file taken from a PC, it seemed to confuse the "?" and "`" characters, when I moved them to the Amiga, I have done my best to correct them, but you may find the odd one that still needs swapping. Sorry I couldn`t do them all, but Amos is too hard for me, i`m still on 68000 myself! CALL THESE BOARDS...