News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_AMSDOS

Bomb Drop by Trevor Johnson

Started by AMSDOS, 05:19, 15 April 18

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

AMSDOS

I've had a look at a game Trevor wrote earlier called Bomb Drop, which had a few BASIC 1.1 commands in it. So I set a challenge of recoding it, so it works on all systems.  :D


My initial attempts wasn't working properly with a string based array, though while recoding I noticed I wasn't filling all the gaps, which may have been the trouble I was having, when my missile collided with the aliens missile. I haven't been back to fix that version because what I've got now seems to fully work.  :)


To the program:-




1 DEFINT A-Z:SYMBOL AFTER 225:MEMORY &9FFF
2 DEF FNa=&9FD7+(x+41*y)-y
3 GOTO 20
4 POKE FNa,v:RETURN
10 '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                 AMSTRAD BASIC - BOMB DROP                                        By Trevor Johnson                                              September 2017                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 MODE 1
40 POKE &BDEE,&C9
60 SYMBOL &E1,0,0,60,90,102,60,102,195
70 SYMBOL &F8,153,126,102,219,165,102,36,24
80 SYMBOL &FC,36,36,60,36,60,24,24,24
90 SYMBOL &EF,24,24,36,60,36,36,60,102
95 FOR y=2 TO 15:FOR x=2 TO 38:v=32:GOSUB 4:NEXT x,y
100 REM cls
110 INK 0,1
120 INK 1,24
130 INK 2,9
140 INK 3,6
150 LOCATE 1,1
160 PRINT CHR$(135)
170 LOCATE 1,24
180 PRINT CHR$(141)
190 LOCATE 40,1
200 PRINT CHR$(139)
210 LOCATE 40,24
220 PRINT CHR$(142)
230 FOR x=2 TO 39
240 LOCATE x,1
250 PRINT CHR$(131)
260 LOCATE x,24
270 PRINT CHR$(140)
280 LOCATE x,23
290 PRINT CHR$(253)
300 y=23:v=253:GOSUB 4
310 LOCATE x,22
320 PEN 2
330 PRINT CHR$(143)
340 y=22:v=32:GOSUB 4
350 LOCATE x,21
360 PRINT CHR$(143)
370 y=21:GOSUB 4
380 LOCATE x,20
390 PRINT CHR$(143)
400 y=20:GOSUB 4
410 LOCATE x,19
420 PRINT CHR$(143)
430 y=19:GOSUB 4
440 LOCATE x,18
450 PRINT CHR$(143)
460 y=18:GOSUB 4
470 LOCATE x,17
480 PRINT CHR$(143)
490 y=17:GOSUB 4
500 PEN 1
510 LOCATE x,16 
520 PRINT CHR$(244)
530 y=16:v=244:GOSUB 4
540 NEXT x
550 FOR x=2 TO 23
560 LOCATE 1,x
570 PRINT CHR$(133)
580 LOCATE 40,x
590 PRINT CHR$(138)
600 NEXT x
610 LOCATE 20,3
620 PRINT CHR$(248)
630 x=20:y=3:v=248:GOSUB 4
690 FOR z=1 TO 6
700 x=INT((RND(1)*37)+2)
710 IF x=w THEN x=x+1
720 w=x
730 y=INT(RND(1)*5)+2
740 y=24-y
750 PEN 3 
760 LOCATE x,y:v=233:GOSUB 4
770 PRINT CHR$(233)
780 NEXT z
790 PEN 1
800 LOCATE 3,1
810 PRINT "Targets remaining ="6 - explosion
820 REM
830 REM **** Define Variables ****
840 REM
850 playerx=20
860 playery=3
870 alien1x=8
880 alien2x=33
890 alien1y=15
900 alien2y=15
910 alienmissle1=0
920 alienmissle1x=alien1x
930 alienmissle1y=alien1y
940 alienmissle2=0
950 alienmissle2x=alien2x
960 alienmissle2y=alien2y
970 pressed=0
980 bomb=0
990 explosion=0
1000 counter=0
1010 counter2=0
1020 counter3=0
1030 countdown=INT(TIME/300)+60
1040 COUNTDOWN2=0
1050 w=0
1060 REM
1070 REM **** MAIN GAME LOOP ****
1080 WHILE pressed<>66
1090 IF explosion=6 THEN GOTO 2030
1100 IF INKEY(34)=0 THEN GOSUB 1300
1110 IF INKEY(27)=0 THEN GOSUB 1380
1120 IF INKEY(67)=0 THEN GOSUB 1490
1130 IF INKEY(69)=0 THEN GOSUB 1600
1140 IF INKEY(47)=0 THEN GOSUB 1710
1150 IF bomb=1 THEN GOSUB 1780
1160 IF alienmissle1=1 THEN GOSUB 2340 ELSE GOSUB 2140
1170 IF alienmissle2=1 THEN GOSUB 2490 ELSE GOSUB 2240
1180 GOSUB 2630
1190 GOSUB 2750
1200 IF INKEY(58)=0 THEN pressed=66
1210 COUNTDOWN2=INT(TIME/300)
1220 LOCATE 30,1:PRINT "Time ="COUNTDOWN-COUNTDOWN2
1230 REM PRINT "time="countdown   
1240 IF countdown2>countdown THEN pressed=66
1250 WEND
1260 GOTO 2030
1270 REM
1280 REM **** PLAYER RIGHT ****
1290 REM
1300 LOCATE playerx,playery:x=playerx:y=playery:v=32:GOSUB 4
1310 PRINT CHR$(32)
1320 IF playerx=2 THEN GOTO 1340
1330 playerx=playerx-1
1340 LOCATE playerx,playery
1350 x=playerx:y=playery:screenchr=PEEK(FNa)
1360 IF screenchr=252 THEN GOTO 2030 ELSE PRINT CHR$(248):v=248:GOSUB 4
1370 RETURN
1375 REM **** PLAYER  LEFT ****
1380 LOCATE playerx,playery:x=playerx:y=playery:v=32:GOSUB 4
1390 PRINT CHR$(32)
1400 IF playerx=39 THEN GOTO 1420
1410 playerx=playerx+1
1420 LOCATE playerx,playery
1430 x=playerx:y=playery:screenchr=PEEK(FNa)
1440 IF screenchr=252 THEN GOTO 2030 ELSE PRINT CHR$(248):v=248:GOSUB 4
1450 RETURN
1460 REM
1470 REM **** PLAYER UP ****
1480 REM
1490 LOCATE playerx,playery:x=playerx:y=playery:v=32:GOSUB 4
1500 PRINT CHR$(32)
1510 IF playery=2 THEN GOTO 1530
1520 playery=playery-1
1530 LOCATE playerx,playery
1540 x=playerx:y=playery:screenchr=PEEK(FNa)
1550 IF screenchr=252 THEN GOTO 2030 ELSE PRINT CHR$(248):v=248:GOSUB 4
1560 RETURN
1570 REM
1580 REM **** PLAYER DOWN ****
1590 REM
1600 LOCATE playerx,playery:x=playerx:y=playery:v=32:GOSUB 4
1610 PRINT CHR$(32)
1620 IF playery=5 THEN GOTO 1640
1630 playery=playery+1
1640 LOCATE playerx,playery
1650 x=playerx:y=playery:screenchr=PEEK(FNa)
1660 IF screenchr=252 THEN GOTO 2030 ELSE PRINT CHR$(248):v=248:GOSUB 4
1670 RETURN
1680 REM
1690 REM **** LAUNCH BOMB IF ONE NOT LAUNCHED ****
1700 REM
1710 IF bomb=1 THEN RETURN
1720 bomb=1
1730 bombx=playerx
1740 bomby=playery+1 
1750 LOCATE bombx,bomby:x=bombx:y=bomby:v=252:GOSUB 4
1760 PRINT CHR$(252)
1770 RETURN
1780 REM
1790 REM
1800 REM **** CHECK IF BOMB IMPACT ****
1810 REM
1820 LOCATE bombx,bomby:x=bombx:y=bomby:v=32:GOSUB 4
1830 PRINT CHR$(32)
1840 IF bomby=22 THEN GOTO 1980
1850 bomby=bomby+1
1860 LOCATE bombx,bomby:x=bombx:y=bomby
1870 IF bombx=alienmissle1x THEN IF bomby=alienmissle1y THEN PRINT CHR$(32):v=32:GOSUB 4:alienmissle1=0:bomb=0:RETURN
1880 IF bombx=alienmissle2x THEN IF bomby=alienmissle2y THEN PRINT CHR$(32):v=32:GOSUB 4:alienmissle2=0:bomb=0:RETURN
1890 screenchr=PEEK(FNa)
1900 IF screenchr<>32 THEN GOSUB 1920 ELSE PRINT CHR$(252):v=252:GOSUB 4
1910 RETURN
1920 IF screenchr=233 THEN PRINT CHR$(238):v=32:GOSUB 4:explosion=explosion+1
1930 IF screenchr=238 THEN PRINT CHR$(238):v=32:GOSUB 4
1940 IF screenchr=244 THEN PRINT CHR$(32):v=32:GOSUB 4
1950 IF screenchr=143 THEN PRINT CHR$(32):v=32:GOSUB 4
1960 LOCATE 3,1
1970 PRINT "Targets remaining ="6 - explosion
1980 bomb=0
1990 RETURN
2000 REM
2010 REM **** END GAME ****
2020 REM
2030 CLS
2040 MODE 0
2050 LOCATE 7,10
2060 IF EXPLOSION=6 THEN PRINT"YOU WON" ELSE PRINT"YOU LOST"
2070 CALL &BB03
2080 CALL &BB18
2090 GOTO 20
2100 END
2110 REM
2120 REM **** LAUNCH ALIEN 1 - MISSLE ****
2130 REM
2140 IF alien1x=alienmissle2x AND alienmissle2=1 THEN RETURN
2150 alienmissle1x=alien1x
2160 alienmissle1y=alien1y-1
2170 LOCATE alienmissle1x,alienmissle1y:x=alienmissle1x:y=alienmissle1y:v=239:GOSUB 4
2180 PRINT CHR$(239)
2190 alienmissle1=alienmissle1+1
2200 RETURN
2210 REM
2220 REM **** LAUNCH ALIEN 2 - MISSLE ****
2230 REM
2240 IF alien2x=alienmissle1x AND alienmissle1=1 THEN RETURN
2250 alienmissle2=1
2260 alienmissle2x=alien2x
2270 alienmissle2y=alien2y-1
2280 LOCATE alienmissle2x,alienmissle2y:x=alienmissle2x:y=alienmissle2y:v=239:GOSUB 4
2290 PRINT CHR$(239)
2300 RETURN
2310 REM
2320 REM **** ALIEN 1 MISSLE COLLISION ****
2330 REM
2340 LOCATE alienmissle1x,alienmissle1y:x=alienmissle1x:y=alienmissle1y:v=32:GOSUB 4
2350 PRINT CHR$(32)
2360 IF alienmissle1y=2 THEN GOTO 2440
2370 alienmissle1y=alienmissle1y-1
2380 LOCATE alienmissle1x,alienmissle1y:x=alienmissle1x:y=alienmissle1y
2390 aliencollision=PEEK(FNa)
2400 IF aliencollision<>32 THEN GOTO 2420 ELSE PRINT CHR$(239):v=239:GOSUB 4
2410 RETURN
2420 IF aliencollision=252 THEN PRINT CHR$(32):v=32:GOSUB 4:alienmissle1=0:bomb=0
2430 IF aliencollision=248 THEN GOTO 2030
2440 alienmissle1=0
2450 RETURN
2460 REM
2470 REM **** ALIEN 2 - MISSLE ****
2480 REM
2490 counter3=counter3+1
2500 IF counter3>2 THEN counter3=0 ELSE RETURN
2510 LOCATE alienmissle2x,alienmissle2y:x=alienmissle2x:y=alienmissle2y:v=32:GOSUB 4
2520 PRINT CHR$(32)
2530 IF alienmissle2y=2 THEN GOTO 2610
2540 alienmissle2y=alienmissle2y-1
2550 LOCATE alienmissle2x,alienmissle2y:x=alienmissle2x:y=alienmissle2y
2560 aliencollision=PEEK(FNa)
2570 IF aliencollision<>32 THEN GOTO 2590 ELSE PRINT CHR$(239):v=239:GOSUB 4
2580 RETURN
2590 IF aliencollision=252 THEN PRINT CHR$(32):v=32:GOSUB 4:alienmissle2=0:bomb=0
2600 IF aliencollision=248 THEN GOTO 2030
2610 alienmissle2=0
2620 RETURN
2630 REM
2640 REM **** MOVE ALIEN 1 - FAST ****
2650 REM
2660 counter=counter+1
2670 IF counter>2 THEN counter=0 ELSE RETURN   
2680 LOCATE alien1x,alien1y:x=alien1x:y=alien1y:v=32:GOSUB 4
2690 PRINT CHR$(32)
2700 IF playerx<alien1x AND alien1x>=2 THEN alien1x=alien1x-1
2710 IF playerx>alien1x AND alien1x<=38 THEN alien1x=alien1x+1
2720 LOCATE alien1x,alien1y:x=alien1x:y=alien1y:v=225:GOSUB 4
2730 PRINT CHR$(225)
2740 RETURN
2750 REM
2760 REM **** MOVE ALIEN 2 - SLOW ****
2770 REM
2780 counter2=counter2+1
2790 IF counter2>5 THEN counter2=0 ELSE RETURN
2800 LOCATE alien2x,alien2y:x=alien2x:y=alien2y:v=32:GOSUB 4
2810 PRINT CHR$(32)
2820 IF playerx<alien2x AND alien2x>=2 THEN alien2x=alien2x-1
2830 IF playerx>alien2x AND alien2x<=38 THEN alien2x=alien2x+1
2840 LOCATE alien2x,alien2y:x=alien2x:y=alien2y:v=225:GOSUB 4
2850 PRINT CHR$(225)
2860 RETURN





The main challenge was to write something to replace the extensive use of COPYCHR$(#0) within the original program. In BASIC 1.0 the options are, write a small M/C routine to patch in the firmware TXT RD CHAR (&BB60), which is available in Firmware 1.0, though that may have complications between Firmware 1.0 & 1.1, the reasons I demonstrated in this little program.
The alternative to that is an array. As I mentioned earlier, I was trying to code it with a string based array and the code was almost working, if someone is interested in it let me know and I'll see if I can plug where I think I saw the fault.
I've tried a more unusual approach of rather than trying to define an Array, set aside some Memory instead by working out how much memory I needed. This game plays in MODE 1, which is 40x25 or 1000 bytes. 1000 bytes in Hexadecimal is &3E8. The first 4 Lines of the program setup & handle that array which I'll break down:-


Line 1 - Define variables as Integers (Whole Numbers), Reserve space for redefining characters, Reserve space above &9FFF for the array.


Line 2 - This declares a Function called "a" for the array. The calculation works like this, &9FD7 is a Base Address, when x is added to it followed by it's Width+1 then multiplied by y and y is subtracted, to make this sort of array compatible with this program values can range between 1-40 along the xpos line and 1-25 for the ypos, so when x=1 and y=1 adding those calculations to &9FD7, &A000 is obtained. The &9FD7 is basically acquired based on the width+1 of the array, so in this case the array is 40 columns wide, 1 is added to that and then &A000 is then subtracted by 41 to give the base address of &9FD7. If I had made it another way so x equaled between 0 and 39 and y equaled between 0 and 24 then my base address would of been &A000, but it would of involved a lot of mucking about with the program.


Line 3 - Is there to skip Line 4.


Line 4 - A short subroutine which gets called regularly though the program. It used Function "a", so when it gets called up through the program (GOSUB 4) "x" needs to equal something (e.g. "playerx") as does "y", the POKE simply uses that Function to calculate where it needs to POKE a value into the array. Obviously "v" contains the value it needs to store, as the original program was using character values for its tests, I'm using the "v" to store the appropriate value. Once that's done the subroutine RETURNs back to where it was called from.


So with all that setup numerous changes need to take place in the program for that to work. The subroutine to CHECK IF BOMB IMPACT between Lines 1820 & 1950 seems like a good place to look at changes.


Line 1820 - Locates the position of "bombx,bomby":x equals "bombx", y equals "bomby", a value of "32" is used and the array is called to clear that position, Line 1830 simply clears the bomb position onscreen.


Line 1840 - Checks if the y coordinate of bomb has reached the bottom of the screen, if it has routine jumps to the end of the subroutine.


Line 1850 - Otherwise y coordinate for bomb is incremented accordingly.


Line 1860 - New positions are used. x & y variables are updated accordingly.


Line 1870 - Checks for collision between your bomb and alienmissle, if it has screen is cleared at that position with character 32. The array is also updated with the value of 32, x & y values from line 1860 ensure the correct position is called in the array. Following that the alienmissle and bomb variables are cancelled.


Line 1880 - As above, but checks are made between your bomb and the 2nd alien missiles.


Line 1890 - This line replaces the BASIC 1.1 COPYCHR$(#0) with a PEEK. PEEK works by returning a value from a specified address. In this case I popped in the Function for my user defined "a" array. x & y positions were already defined at Line 1860, so the appropriate position of the array is in place and a value is returned into screenchr variable. The main difference here now is PEEK deals in numeric values instead of string values, so screenchr now holds a numeric value instead of a string one.


Line 1900 - Checks what that value is from the previous line, if it doesn't equal 32, then some more checks are made between 1920 and 1950. Otherwise if 32 is found (a space) then the bomb is printed, the bomb is also updated in the array.


Line 1910 - That RETURN actually returns you to the place from where the CHECK IF BOMB IMPACT was called from, which I think was within the Main Loop of the game.


Line 1920-1950 - As mention above this lines are check when the screenchr variable doesn't equal 32. A screenchr value of 233 is a mine in the ground for example. IF that's found the appropriate explosion symbol is updated, in this case I've updated my array with a value of 32 because what I found in the original program was if a mine had a series of mines underneath, it was impossible to reach the mines under the other mine. Applying this form of control allows me to print the explosion, but also issue a value which allows my bombs to proceed through to other mines if they need to be reached.




Advantages of this Array


* A Byte size Array accessible from BASIC
* Possible to replace COPYCHR$(#0) with PEEK checks for compatibility across all systems.
* Memory Dumps can be used to view this kind of array, which may help in debugging situations.
* HIMEM could be used to define place of the Array.


Disadvantages of this Array


* It reserves MEMORY, so may become awkward if working with a M/C Routine.
* SYMBOL Table needs to be defined first, prior to defining an area of space for the Array.
* Just need to be careful Array isn't going to be placed somewhere delicate.



* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Powered by SMFPacks Menu Editor Mod