The Complete STOS Reference

 pre-release 0.2 Edited By Dr Phibes

Missing Link Tutorial

Part 2

By Deano

Part 1: BOBs & JOEYS | Part 3: soon
Hello again STOSSERS. Welcome to the second part of the missing link tutorial. This month we are going to look at the mapping commands.
 
WORLD X1,Y1,X2,Y2,0,1  REPLACE BLOCKS MADR,BLOCK1,BLOCK2 
WORLD SCR,BLOCKS,MADR,X,Y,0  R=BLOCK AMOUNT(MADR,BLOCK) 
LANDSCAPE X1,Y1,X2,Y2,0,1  XY BLOCK MADR,XADR,YADR,BLOCK,NUM
LANDSCAPE SCR,BLOCKS,MADR,X,Y,0  X=X LIMIT(MADR,X1,X2)
R=WHICH BLOCK(MADR,X,Y) Y=Y LIMIT(MADR,Y1,Y2)
SETBLOCK MADR,X,Y,BLOCK  A=MAP TOGGLE(MADR)
These 'mapping' commands are used for scrolling the screen. Note that you could use 'def scroll' for this purpose but these new command make scrolling a lot easier. For a start, scrolling left and right can be done in steps of less than 16 pixels thus creating smoothy scrolling. It also solves the nightmare of moving sprites across a scrolling background. Right.....lets look at the first command.
 

WORLD,X1,Y1,X2,Y2,0,1

The WORLD commands allow you to scroll the screen left, right, up, and down. This version of the command allows you to specify how much of the screen you wish to use as the scrolling area. This is usefull for having the top half of the screen as the scrolling area, and the bottom half as the games scoreboard.

If you've seen how the STOS 'limit sprite' command works, you'll see that the mouse is limited to that part of the screen, its like having it trapped in an invisible box.

This is how this version of 'world' works. It traps the scrolling map in an invisible box. X1 and Y1 hold the start co=ordinates of the screen area to be trapped...in other words the top left hand part of the screen. X2 and Y2 hold the end co-ordinates of the box..IE: the bottom right hand part of the screen. The last two parameters have no meaning as yet so leave them as they are.

In order to create these scrolling areas, known as maps. We first have to define one. We can do this using the EDDY program supplied with the missing link package. This is simular to using the 'Map Definer' supplied with STOS only we don't use normal STOS sprites to create the map. We use the MAKE program to make the sprites into world blocks so they can be loaded into EDDY. Note that even though the EDDY manual tells us that we can load 'world' and 'landscape' blocks into the EDDY definer...we can only load 'world' blocks into it. If I get time I'll do an article on these two programs.
 

WORLD SCR,BLOCKS,MADR,X,Y,0

This is the command that actually scrolls the map we defined with EDDY. Note that we need two sets of data installed before we can use this command. These are...World Blocks, and Map Data.

SCR= This is the screen to display the map on, it can be either LOGIC, PHYSIC, or BACK.

BLOCKS= This tells 'world' where our world blocks are, load them into a memory bank and use 'start(bank-number)'.

MADR= The bank number of the map data saved from EDDY, note it must have been saved as 'world data', again use 'start(bank-number)'.

X and Y= The X and Y co-ordinates of the maps starting point.

The nought does nothing as yet, maybe in an update. Anyway, heres a routine that shows the use of the two commands.

10 key off : hide : flash off : mode 0
20 load"BLOCK.MBK",5 : rem load world blocks into bank 5
30 load"MAP.MBK",6 : rem load world map data into bank 6
40 logic=back : X=0 : Y=0
45 world 32,10,288,190,0,1
50 repeat
60 world logic,start(5),start(6),X,Y,0
70 if jleft and X>0 then dec X
80 if jright and X<1500 then inc X
90 if jup and Y>0 then dec Y
100 if jdown and Y<2000 then inc Y
110 screen swap : wait vbl
120 until fire
If we look at lines 80 and 100 we see that the program is checking if the X and Y varibles are less than a number thats higher than the co-ordinates of the actual screen. This is because the varibles are the co-ordinates of the scrolling area of the map and not the screen.

Note that the first version of the WORLD command must have its X co-ordinates in steps of 16 pixels due to a bug in the ST's registers.

LANDSCAPE

The LANDSCAPE command is exactly the same as WORLD except that it can only scroll its map in two directions. Its only used for games that scroll just up and down. It can't do the multi scrolling that WORLD can do. The parameters are the same as those of WORLD, but the X co-ordinate cannot be changed in a loop, only the Y co-ordinate. X is just used to set the X starting point of the map to be scrolled.

Note, as with the first version of WORLD, the first version of LANDSCAPE must have its X co-ordinates in steps of 16 pixels. Note that we can use the last routine to see these commands in action. Just convert your sprites to LANDSCAPE blocks, load them into EDDY and make your map making sure you don't go over the X co-ordinate of 304 and make your map downwards, not exceeding the 320 X co-ordinate. Save your map data as landscape data, load your landscape blocks into bank five, and new landscape map data in bank six. Remove lines 80 and 90 and run the program. As we can see, we can only move up and down.

Note, due to the bug in EDDY, we have to make our sprites first into world blocks, then landscape blocks. Load the world blocks into EDDY to make the landscape map, then load the landscape blocks into our example routine. Bit of a pain but there we go.

R=WHICH BLOCK(MADR,X,Y)

As you may have noticed, we have being uses these things called blocks, ie: converted sprites, to make the world and landscape maps. So we can now use this command as a form of collision detection. The MADR varible holds the bank number of the map data used by the world and landscape commands, and X and Y are the co-ordinates of the block we're checking for. R holds the block number. So really its like checking for a sprite entering a zone without having to set the zone first. If we look at the screen in EDDY where we select our blocks, we can count along to a certain block to find its number in the row. Note that the row starts from nought to the number of blocks in the row, just like the BOB command. So, if we defined, say a diamond as sprite number one. This would be block number 0.

So what we want to do is place our diamond blocks in certain places of the map as we define it, then tell STOS that when our BOB touches it, to detect a collision, add this line to our example.

105 BL=which block (start(6),XBOB+14,YBOB+12)
The varibles XBOB and YBOB hold the X and Y co-ordinates of the bob, as the bob touches a certain block, the varible BL would contain the row number of it. So, if the bob touched the diamond, then BL would be set to nought. If the bob touched the next block in the row then BL would be set to one. Lets say we defined two sprites has part of the map, and converted them to map blocks. We could use this routine to check which block has been touched. Try these lines...
106 if BL=0 then print"You have found the diamond."
107 if BL=1 then print"You have hit the wall."
Where the wall is the second block in the world/landscape blocks.

SET BLOCK MADR,X,Y,BLOCK

Each block in the map is set two either one if it exists, or nought if it does'nt. These means that if a certain block was in the map at co-ordinates X and Y, it would be set to one, or nought if it was'nt there. We can use this command with WHICH BLOCK to find a block, when its found we can set the block to nought which will then erase the found block off the screen. MADR is the bank number of the map data, X and Y is the co-ordinates to check at, and BLOCK is the row number of the block to remove from screen. Example.....
10 BL=which block(start(6),XBOB,YBOB)
20 if BL=1 then set block start(6),XBOB,YBOB,0 : bell

REPLACE BLOCKS MADR,BLOCK1,BLOCK2

This command does as it says....it replaces one type of block with another. This is usefull if say, you wanted to change all the diamonds on screen to money bags for example. We can have our diamond block as block one in the row, and the money block as block two, then change the diamonds into money bags like so....
100 replace blocks start(6),1,2

R=BLOCK AMOUNT(MADR,BLOCK)

This command is usefull for checking how many times a certain block appears in a map. If we had our diamond and money bag blocks still in the same place, and we put 20 copies of our diamond on the map screen, then we could use this command to find how many diamonds are on screen. Try this example.....
100 DIAMONDS=block amount(start(6),1)
110 if DIAMONDS=0 then print"All diamonds are collected"
So, BLOCK holds the number of block ones..(diamonds) there are in the map. As each one is removed with SET BLOCK, the DIAMONDS varible will decrease by one, line 110 checks if all diamonds have gone.

XY BLOCK MADR,XADR,YADR,BLOCK,NUMBER

If we wanted to store all the X and Y co-ordinates of a certain block in an array....this command will do it. So, if we wanted to set the X and Y co-ordinates of the diamond...(block 1), we would use this little routine....
10 A=block amount(start(6),1)
20 dim XBL(A),YBL(A)
30 xy block start(6),varptr(XBL(0)),varptr(YBL(0)),1,A
40 for X=0 to A : print XBL(X),YBL(X) : next X
XADR and YADR are the X and Y arrays to put the co-ordinates in, BLOCK is the row number of the block we want to get the co-ordinates of, and NUMBER is the total number of block ones found in the map.

This can be used if you had a number of diamonds and you wanted each one to score different points. Using the arrays you can see which diamond block has been collected and update the score with the certain diamonds points....like so

50 if A=1 and XBOB=XBL(1) then SC=SC+40
60 if A=1 and YBOB=YBL(4) then SC=SC+100

X=X LIMIT(MADR,X1,X2)
Y=Y LIMIT(MADR,Y1,Y2)

These commands imform STOS how large in width and height the map is. X1 is the X start of the map, X2 is the X end of the map, Y1 is the Y start of the map, and Y2 is the Y end of the map. X and Y hold the end co-ordinates of the map. MADR is the bank number of the map data. This can be used to check if a bob is still within the X and Y areas.

M=MAP TOGGLE(MADR)

A nice simple one here. If the data in MADR is world data, then this command will convert it to landscape data, or vise versa...
10 load"map.mbk",6 : rem World data
20 N=map toggle(start(6))
30 print"The world data is now landscape data"
40 N=map toggle(start(6))
50 print"The landscape data is now back to world data"
This is usefull if you had some levels in your game that use the landscape command, and some that used 'world'.

Well thats the end of part 2, see you in part 3 next month where we shall have a look at the text commands.