We created our sprite and made it move around the screen. Now let's see how to create the collision between sprites. The MSX has a control created specifically for collisions. This works like a switch, every time two sprites "touch" each other, it drops everything it is doing to go into this specific subroutine. First of all, to make this work we must activate it. To do this we must put the following command at the beginning of our game program: ON SPRITE GOSUB Line number. We have prepared the MSX for collisions, but it is not active yet. To do this we must give another command: SPRITE ON. From this moment on all the sprites that will enter
in collision, they will be intercepted, that is, the program execution will go into the subroutine that we created with ON SPRITE GOSUB. If we want to deactivate collisions, just change the command to SPRITE OFF. There is another one: SPRITE STOP,
which suspends collisions, i.e. recognizes them but does not go to the interception subroutine. To reactivate everything just bring it back to SPRITE ON. I will make a little program to be more clear about everything I said. But first I want
talk about 2 other fundamental commands for our games. The first is STICK, it controls the state of the cursor keys or the joystick. In fact, it will return -1 if we pressed a cursor key or moved the joystick. The aforementioned function recognizes eight movements, or rather 9 if we consider the rest one. I'll make a sketch to make the explanation easier.
8 1 2
\ | /
7 - 0 - 3
/ | \
6 5 4
We can put the function inside a variable. If we use the keys it is Q=STICK(0), if we use the joystick in port 1 it is Q=STICK(1), the second port will be Q=STICK(2).
When a cursor key is pressed or the joystick lever is moved, the command reads the movement and returns it to the variable. The program line could look like this:
100 Q=STICK(0)OR STICK(1):ON Q GOSUB 300,310,320,330,340,350,360,370
In the first part of the line I made the variable Q equal to the cursor keys and the joystick. In the second part, using the ON GOSUB command, execution will go to the established subroutine. For example, if we pressed the
slider or lever to the right, will activate the third routine, the one found on line 320.
The second command is STRIG and ON STRIG, which is used to activate the space bar or joystick buttons. It works like ON SPRITE, but seen with the latter, activating it applies to all collisions, the STRIG must be activated for each key. There are 5 possibilities: 0 = Space bar, 1 = First button of Joystick 1, 2 = First button of Joystick 2, 3 = Second button of Joystick 1 and finally 4 = Second button of Joystick 2. To activate one of the buttons or all together ,
we have to put the line number in the ON STRIG command. ON STRIG GOSUB 400,400.
By doing this we have prepared the command for the space bar and the first button of the joystick 1. But like the ON SPRITE, to make them active we must add; STRIG(0)ON for the bar and STRIG(1)ON for the Joy button. If we want to play with the first button of the two joysticks, just add another line number to the ON STRIG command and activate it with STRIG(3)ON. Since there is position 2 in the middle which is not active, let's remember to leave an empty space: ON STRIG GOSUB 400,400,,420. STRIG(X)STOP and STRIG(X)OFF, suspends and deactivates the command, just as happens with SPRITE OFF/STOP.
After explaining how to use the keys for movement, I proceed with the program. I will use the spacecraft created in the previous lesson.
10 SCREEN 2,2: COLOR 15,1,1: CLS: OPEN “GRP:” AS#1: ON SPRITE GOSUB 200: ON STRIG GOSUB 400,400
20 S$=””: FOR I=0 TO 31: READ A$: S$=S$+CHR$(VAL(“&H”+A$)): NEXT I: SPRITE$(0)=S$: S$=””: FOR I= 0 TO 7: READ A$: S$=S$+CHR$(VAL(“&H”+A$)):NEXT I: SPRITE$(1)=S$:L=1:P=0
30 FOR I=1 TO 100: PSET(RND(1)255,RND(1)191),11: NEXT I: FOR I=1 TO 5: CIRCLE(RND(1)240,RND(1)180),5,13: NEXT I: PRESET(0,0):PRINT#1,”SCORE”;P: PRESET(0,184):PRINT#1,”LEVEL”;L
40 V=0:F=0:X=0:Y=120:X1=240:Y1=120:R=0:SPRITE ON: STRIG(0)ON: STRIG(1)ON
50 Q=STICK(0)OR STICK(1): ON Q GOSUB 300,310,320,330,340,350,360,370
60 PUTSPRITE 0,(X,Y),15,0
70 GOSUB 100
80 IF F=1 THEN X2=X2+R:PUTSPRITE 2,(X2,Y2),14,1:IF X2<16 OR X2,Y2),0
90 IF V=5*L THEN 150 ELSE 50
99' ** ENEMY SPACESHIP MOVEMENT **
100 IF X1>X THEN X1=X1-8 ELSE IF X1<=X THEN X1=X1+8
110 IF Y1>Y THEN Y1=Y1-8 ELSE IF Y1<=Y THEN Y1=Y1+8
120 PUTSPRITE 1,(X1,Y1),6,0: RETURN
149' **LEVEL PASSAGE**
150 SPRITE OFF: STRIG(0)OFF: STRIG(1)OFF
160 PRESET(40,120):PRINT #1,”YOU WIN! LEVEL PASSED!”:FOR I=0 TO 2: PUTSPRITE I,,0: NEXT
170 L=L+1:X2=0:Y2=0:FOR I=0TO 3000: NEXT: CLS:GOTO 30
199' **COLLISIONS**
200 SPRITES OFF
210 IF X1+16>=X AND : PRINT #1,”YOU LOSE. TRY AGAIN!!!”: FOR I=0 TO 3000:NEXT I: RUN
220 IF X2+8>=X1 AND X2<=X1+16 AND Y2+8>=Y AND Y2<=Y1+16 THEN 2,(X2,Y2),0: P=P+100: V=V+1: LINE(41,0)-(88,7) ,1,BF: PRESET(41,0):PRINT#1,P: F=0:X1=240:Y1=120:GOSUB 120
30 SPRITE ON: RETURN
299 ' ** MOVEMENT OF OUR SHIP **
300 IF Y<8 THEN RETURN ELSE Y=Y-8: RETURN
310 IF Y<8 OR X>232 THEN RETURN ELSE Y=Y-8:X=X+8: RETURN
320 IF X>232 THEN RETURN ELSE X=X+8: RETURN
330 IF X>232 OR Y>168 THEN RETURN ELSE X=X+8:Y=Y+8: RETURN
340 IF Y>168 THEN RETURN ELSE Y=Y+8: RETURN
350 IF Y>168 OR X<8 THEN RETURN ELSE X=X-8:Y=Y+8: RETURN
360 IF X<8 THEN RETURN ELSE X=X-8: RETURN
370 IF X<8 OR Y<8 THEN RETURN ELSE X=X-8:Y=Y-8
380 RETURN
399' ** OUR SNOW FIRE **
400 IF F=1 THEN RETURN ELSE F=1
410 IF X>X1 THEN R=-8:X2=X-8 ELSE IF
420 Y2=Y+4:PUTSPRITE 2,(X2,Y2),14,1: RETURN
999 ' *** Starship Data ***
1000 DATA 0F,1F,1C,18,18,18,7C,FF
1010 DATA BF,FF,6F,7D,3F,18,30,60
1020 DATA F0,F8,38,18,18,18,3E,FF
1030 DATA FD,FF,F6,BE,FC,18,0C,06
1040 ' ** SHIP MISSILE DATA **
1050 DATA 3C,7F,FF,FF,FF,FF,7E,3C
It's a battle between two ships. The one we will drive is white, we must launch the missiles to destroy the enemy ship, which is red and will try in every way to chase us and ram us. We can only shoot
horizontally, this is done automatically by program, if the enemy is on the right he will shoot on the right and vice versa. Movements with cursor keys or joystick, to shoot: space bar or joystick button. The game will never end and will continue forever
when our spacecraft is not destroyed.
This game is a summary of everything I have explained. I will be brief to summarize some important parts of the program. Line 10, after the usual initialization data, I activated the collision and key interception wheels
fire. Line 20, loading sprite data, this time I used hexadecimal numbers. In line 30 I created a “miserable” background made of stars and some planets using random positioning, just to put something. The 40
initialize all the variables we will need and activate collisions and fire keys.
The 50 will only be processed if we press one of the movement keys. The lines that go from 300 to 370 are the movements of our spacecraft, I also put a block so as not to go beyond the edges of the screen. The 70 sends the program to the enemy ship's movement subroutine. The 80 checks the variable F, it is a control flag, to see if the space bar or the joystick button has been pressed, if it will be 1 and execute all its instructions. This is interesting because it first goes to the ON STRIG routine in line 400. In the latter there is another control that does not execute the routine if the missile is still moving i.e. if this is still 1. It will only be reactivated if the F will return 0. The 90 checks whether the number of hits scored against the enemy has been reached. If yes, it will go to 150 and start a new level again, increasing the number of shots against the enemy otherwise it will return to line 50 for another round. Finally, the
collisions that are activated on line 40. When 2 sprites touch each other the execution will jump to line 200, where the first thing to do is to deactivate them (line 200), otherwise the continuous "touch" would slow down the execution, and then activate them at exit of the routine (line 230). If you notice, at line 410, I started the missile so that it does not touch its own spacecraft, otherwise the collision switch would have been triggered and since there is no control between them, it would have been a unique slowdown. Unfortunately, this is the biggest problem when using ON SPRITE, that you cannot select the sprites to exclude, any contact between them creates the collision. As long as the game uses a few sprites, like this one, the problem is solvable, but when there are many, it is more convenient not to use it. Using a control with pixels is the ideal solution, just like I did inside the collision wheel and exactly at lines 210 and 220. I could easily eliminate everything, i.e. ON SPRITE, SPRITE ON and the complete routine and insert only the 2 lines said during the course of the program, for example the 210 became 83 and the 220 the 86, nothing would have changed. But with the advent of the MSX2 they partially solved this problem.
To end this long episode, I end up saying that the game I created is for educational purposes only and can be implemented and above all optimized to make it even faster. Anyone who wants and feels it could improve it
adding more sprites or maybe creating a more decent background or try changing the dynamics of the game. Maybe posting the updates made.
Come on guys, let me see if these explanations of mine have brought good results 🙂
Thanks everyone, see you next time.


0 Comments