Hi All,
I'm Fabrizio from Italy and i loved Amstrad from the 80s
i had (and now i have again) an CPC6128
In real life i'm a game developer (unity/obj-c/swift etc etc)
I've made a simple "game" for you and include:
- Move a sprite (char)
- Collisions
- TileMaps
This code is not optimized but only for didactic purpose :)
In near future i would like to use ASM.
Sorry for my bad english.
simple version
10 'A (simple) GAME Routine BY FABRIZIO RADICA - 2016 Retroacademy.it
100 mode 0: 'PRINT CHR$(22)+CHR$(1) 'mode 0 ed attiva la trasparenza
110 cls: border 0: ink 0,0
150 maxAr%=20: SYMBOL AFTER 240
160 SYMBOL 245,&X01011010,&X00010101,&X11000100,&X11011011,&X00100110,&X01101000,&X01011011,&X11101001
165 SYMBOL 246,&X00010000,&X00000001,&X00001000,&X01010010,&X01000010,&X00001000,&X00010001,&X01000001
166 SYMBOL 247,&X00111000,&X01111110,&X11111011,&X11111111,&X11111111,&X11111111,&X11111111,&X00111100
200 DIM map%(20,20)
250 LOCATE 1,22 : print "Loading..."
300 FOR y%=1 TO 20 'GENERO LA MAPPA DEL LIVELLO LEGGENDO I DATA
400 FOR x%=1 TO 20
500 READ map%(y%,x%)
550 if map%(y%,x%)=0 then locate x%,y%: pen 8: print chr$(246)
600 if map%(y%,x%)=9 then locate x%,y%: pen 6: print chr$(245)
610 if map%(y%,x%)=2 then locate x%,y%: pen 1: print chr$(247)
640 NEXT x%
650 NEXT y%
660 x%=10:y%=8:v%=1:sc%=0:p%=0
670 SYMBOL 240,&X00011000,&X00111100,&X01111110,&X11011011,&X01111110,&X01100110,&X11011011,&X10000001
700 print " " : print "RetroAcademy." : LOCATE 1,22 : print "Score "
740 LOCATE x%,y%: pen 3: PRINT CHR$(240)
750 IF map%(y%,x%)=2 THEN map%(y%,x%)=0 : sc%=sc%+1 : locate 6,22 : print " ";sc% :sound 2,100,8,10,1,1
780 IF NOT(INKEY() AND map%(y%,x%-v%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):x%=x%-1:sound 1,200,1
800 IF NOT(INKEY(1)) AND map%(y%,x%+v%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):x%=x%+1:sound 1,300,1
850 IF NOT(INKEY(0)) AND map%(y%-v%,x%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):y%=y%-1:sound 1,50,1
880 IF NOT(INKEY(2)) AND map%(y%+v%,x%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):y%=y%+1:sound 1,100,1
950 CALL &BD19
990 GOTO 740
1000 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
1100 DATA 9,0,0,0,0,0,0,0,0,9,9,9,9,9,0,0,0,9,9,9
1200 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
1300 DATA 9,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,0,0,9
1400 DATA 9,9,9,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,9
1500 DATA 9,0,0,9,9,0,0,0,0,9,9,9,9,9,0,0,9,9,9,9
1600 DATA 9,0,0,0,0,0,0,0,0,9,9,9,9,9,0,0,9,9,9,9
1700 DATA 9,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,9
1800 DATA 9,0,0,0,9,9,9,9,2,0,0,0,0,0,0,0,0,0,0,9
1900 DATA 9,9,9,9,9,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9
2000 DATA 9,9,9,9,9,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9
2100 DATA 9,0,0,0,0,2,9,9,9,9,0,9,9,9,0,0,0,9,9,9
2200 DATA 9,0,0,0,9,0,0,0,0,0,0,0,0,2,0,0,0,0,0,9
2300 DATA 9,0,9,9,9,9,0,0,0,9,9,9,9,0,0,0,0,0,0,9
2400 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
2500 DATA 9,0,0,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9,9,9
2600 DATA 9,0,0,0,0,0,9,0,0,9,9,9,9,9,0,0,9,9,9,9
2700 DATA 9,9,9,0,0,0,9,0,0,9,0,0,0,0,0,0,0,0,0,9
2800 DATA 9,9,9,0,0,2,0,0,0,0,0,2,0,0,2,2,0,0,0,9
2900 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
HERE Multicolor version :D
10 'A (simple) GAME Routine BY FABRIZIO RADICA - 2016 Retroacademy.it
100 mode 0: PRINT CHR$(22)+CHR$(1) 'mode 0 ed attiva la trasparenza
110 cls: border 0: ink 0,0
150 maxAr%=20: SYMBOL AFTER 240
160 SYMBOL 245,&X01011010,&X00010101,&X11000100,&X11011011,&X00100110,&X01101000,&X01011011,&X11101001
165 SYMBOL 246,&X00010000,&X00000001,&X00001000,&X01010010,&X01000010,&X00001000,&X00010001,&X01000001
166 SYMBOL 247,&X00111000,&X01111110,&X11111011,&X11111111,&X11111111,&X11111111,&X11111111,&X00111100
168 SYMBOL 248,&X10000111,&X01010100,&X10000010,&X01001000,&X10010011,&X01100011,&X10100100,&X00011100
160 SYMBOL 249,&X00000000,&X00000000,&X00011100,&X00000100,&X00000000,&X00000000,&X00000000,&X00000000
200 DIM map%(20,20)
250 LOCATE 1,22 : print "Loading..." :PRINT CHR$(22)+CHR$(1)
300 FOR y%=1 TO 20 'GENERO LA MAPPA DEL LIVELLO LEGGENDO I DATA
400 FOR x%=1 TO 20
500 READ map%(y%,x%)
550 if map%(y%,x%)=0 then locate x%,y%: pen 8: print chr$(246)
600 if map%(y%,x%)=9 then locate x%,y%: pen 9: print chr$(245):locate x%,y%: pen 12: print chr$(248)
610 if map%(y%,x%)=2 then locate x%,y%: pen 7: print chr$(247):locate x%,y%: pen 4: print chr$(249)
640 NEXT x%
650 NEXT y%
660 x%=10:y%=8:v%=1:sc%=0:p%=0: PRINT CHR$(22)+CHR$(0)
670 SYMBOL 240,&X00011000,&X00111100,&X01111110,&X11011011,&X01111110,&X01100110,&X11011011,&X10000001
700 print " " : print "RetroAcademy." : LOCATE 1,22 : print "Score "
740 LOCATE x%,y%: pen 3: PRINT CHR$(240)
750 IF map%(y%,x%)=2 THEN map%(y%,x%)=0 : sc%=sc%+1 : locate 6,22 : print " ";sc% :sound 2,100,8,10,1,1
780 IF NOT(INKEY() AND map%(y%,x%-v%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):x%=x%-1:sound 1,200,1
800 IF NOT(INKEY(1)) AND map%(y%,x%+v%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):x%=x%+1:sound 1,300,1
850 IF NOT(INKEY(0)) AND map%(y%-v%,x%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):y%=y%-1:sound 1,50,1
880 IF NOT(INKEY(2)) AND map%(y%+v%,x%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):y%=y%+1:sound 1,100,1
950 CALL &BD19
990 GOTO 740
1000 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
1100 DATA 9,0,0,0,0,0,0,0,0,9,9,9,9,9,0,0,0,9,9,9
1200 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
1300 DATA 9,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,0,0,9
1400 DATA 9,9,9,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,9
1500 DATA 9,0,0,9,9,0,0,0,0,9,9,9,9,9,0,0,9,9,9,9
1600 DATA 9,0,0,0,0,0,0,0,0,9,9,9,9,9,0,0,9,9,9,9
1700 DATA 9,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,9
1800 DATA 9,0,0,0,9,9,9,9,2,0,0,0,0,0,0,0,0,0,0,9
1900 DATA 9,9,9,9,9,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9
2000 DATA 9,9,9,9,9,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9
2100 DATA 9,0,0,0,0,2,9,9,9,9,0,9,9,9,0,0,0,9,9,9
2200 DATA 9,0,0,0,9,0,0,0,0,0,0,0,0,2,0,0,0,0,0,9
2300 DATA 9,0,9,9,9,9,0,0,0,9,9,9,9,0,0,0,0,0,0,9
2400 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
2500 DATA 9,0,0,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9,9,9
2600 DATA 9,0,0,0,0,0,9,0,0,9,9,9,9,9,0,0,9,9,9,9
2700 DATA 9,9,9,0,0,0,9,0,0,9,0,0,0,0,0,0,0,0,0,9
2800 DATA 9,9,9,0,0,2,0,0,0,0,0,2,0,0,2,2,0,0,0,9
2900 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
and... a simple multi level routine :)
10 'A (simple) GAME Routine BY FABRIZIO RADICA - 2016 Retroacademy.it
100 mode 0: PRINT CHR$(22)+CHR$(1) 'mode 0 ed attiva la trasparenza
110 cls: border 0: ink 0,0
150 maxAr%=20: lev%=0: SYMBOL AFTER 240
160 SYMBOL 245,&X01011010,&X00010101,&X11000100,&X11011011,&X00100110,&X01101000,&X01011011,&X11101001
165 SYMBOL 246,&X00010000,&X00000001,&X00001000,&X01010010,&X01000010,&X00001000,&X00010001,&X01000001
166 SYMBOL 247,&X00111000,&X01111110,&X11111011,&X11111111,&X11111111,&X11111111,&X11111111,&X00111100
168 SYMBOL 248,&X10000111,&X01010100,&X10000010,&X01001000,&X10010011,&X01100011,&X10100100,&X00011100
160 SYMBOL 249,&X00000000,&X00000000,&X00011100,&X00000100,&X00000000,&X00000000,&X00000000,&X00000000
200 DIM map%(20,20)
250 LOCATE 1,22 : print "Loading." :PRINT CHR$(22)+CHR$(1)
280 lev%=lev%+1
290 if (lev%>=2) THEN lev%=0 : restore 1000
300 FOR y%=1 TO 20 'GENERO LA MAPPA DEL LIVELLO LEGGENDO I DATA
400 FOR x%=1 TO 20
500 READ map%(y%,x%)
550 if map%(y%,x%)=0 then locate x%,y%: pen 8: print chr$(246)
600 if map%(y%,x%)=9 then locate x%,y%: pen 9: print chr$(245):locate x%,y%: pen 12: print chr$(248)
610 if map%(y%,x%)=2 then locate x%,y%: pen 7: print chr$(247):locate x%,y%: pen 4: print chr$(249)
640 NEXT x%
650 NEXT y%
660 x%=10:y%=8:v%=1:sc%=0:p%=0: PRINT CHR$(22)+CHR$(0)
670 SYMBOL 240,&X00011000,&X00111100,&X01111110,&X11011011,&X01111110,&X01100110,&X11011011,&X10000001
680 SYMBOL 250,&X00000000,&X00000000,&X00000000,&X00100100,&X00000000,&X00000000,&X00000000,&X00000000
700 print " " : print "RetroAcademy." : LOCATE 1,22 : print "Score "
740 LOCATE x%,y%: pen 3: PRINT CHR$(240)
750 IF map%(y%,x%)=2 THEN map%(y%,x%)=0 : sc%=sc%+1 : locate 6,22 : print " ";sc% :sound 2,100,8,10,1,1
780 IF NOT(INKEY() AND map%(y%,x%-v%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):x%=x%-1:sound 1,200,1
800 IF NOT(INKEY(1)) AND map%(y%,x%+v%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):x%=x%+1:sound 1,300,1
850 IF NOT(INKEY(0)) AND map%(y%-v%,x%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):y%=y%-1:sound 1,50,1
880 IF NOT(INKEY(2)) AND map%(y%+v%,x%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):y%=y%+1:sound 1,100,1
900 if sc%>=9 then cls: goto 250
950 CALL &BD19
990 GOTO 740
1000 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
1100 DATA 9,0,0,0,0,0,0,0,0,9,9,9,9,9,0,0,0,9,9,9
1200 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
1300 DATA 9,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,0,0,9
1400 DATA 9,9,9,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,9
1500 DATA 9,0,0,9,9,0,0,0,0,9,9,9,9,9,0,0,9,9,9,9
1600 DATA 9,0,0,0,0,0,0,0,0,9,9,9,9,9,0,0,9,9,9,9
1700 DATA 9,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,9
1800 DATA 9,0,0,0,9,9,9,9,2,0,0,0,0,0,0,0,0,0,0,9
1900 DATA 9,0,9,9,9,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9
2000 DATA 9,0,9,9,9,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9
2100 DATA 9,0,0,0,0,2,9,9,9,9,0,9,9,9,0,0,0,9,9,9
2200 DATA 9,0,0,0,9,0,0,0,0,0,0,0,0,2,0,0,0,0,0,9
2300 DATA 9,0,9,9,9,9,0,0,0,9,9,9,9,0,0,0,0,0,0,9
2400 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
2500 DATA 9,0,0,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9,9,9
2600 DATA 9,0,0,0,0,0,9,0,0,9,9,9,9,9,0,0,9,9,9,9
2700 DATA 9,9,9,0,0,0,9,0,0,9,0,0,0,0,0,0,0,0,0,9
2800 DATA 9,9,9,0,0,2,0,0,0,0,0,2,0,0,2,2,0,0,0,9
2900 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
3000 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
3100 DATA 9,0,0,0,0,0,0,0,0,9,9,9,9,9,2,0,0,9,9,9
3200 DATA 9,0,0,0,0,9,9,9,0,0,0,0,0,0,0,0,0,0,0,9
3300 DATA 9,2,0,0,9,9,0,0,0,0,0,9,9,9,9,9,9,0,0,9
3400 DATA 9,9,9,9,9,0,0,0,0,9,0,0,0,0,0,0,0,0,0,9
3500 DATA 9,0,0,0,0,0,0,0,0,9,9,0,0,9,0,0,9,9,9,9
3600 DATA 9,0,0,0,0,0,0,0,0,9,9,0,0,9,0,0,9,9,9,9
3700 DATA 9,0,0,0,9,9,0,0,0,0,0,0,0,9,0,0,0,0,0,9
3800 DATA 9,0,0,0,9,9,9,9,2,0,0,0,0,9,0,0,0,0,2,9
3900 DATA 9,0,9,9,9,9,9,9,9,0,0,9,0,0,0,0,9,9,9,9
4000 DATA 9,0,9,9,9,9,9,9,9,0,0,9,2,0,0,0,9,9,9,9
4100 DATA 9,0,0,0,0,2,9,9,9,9,0,9,9,0,0,0,0,9,9,9
4200 DATA 9,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,2,9
4300 DATA 9,0,9,9,9,9,0,0,0,9,9,9,9,0,0,0,0,0,0,9
4400 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
4500 DATA 9,0,0,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9,9,9
4600 DATA 9,0,0,0,0,0,9,0,0,9,9,9,9,9,0,0,9,9,9,9
4700 DATA 9,0,9,0,0,0,9,0,0,9,0,0,0,0,0,0,0,0,0,9
4800 DATA 9,2,9,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,9
4900 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
Minor bugfix and minor speedupCaching char$ and player (line 180 - 185)
10 'A (simple) GAME Routine BY FABRIZIO RADICA - 2016 Retroacademy.it
100 DEFINT A-Z : mode 0: PRINT CHR$(22)+CHR$(1) 'mode 0 ed attiva la trasparenza
110 cls: border 0: ink 0,0
150 maxAr=20: lev=0: SYMBOL AFTER 240
160 SYMBOL 245,&X01011010,&X00010101,&X11000100,&X11011011,&X00100110,&X01101000,&X01011011,&X11101001
165 SYMBOL 246,&X00010000,&X00000001,&X00001000,&X01010010,&X01000010,&X00001000,&X00010001,&X01000001
166 SYMBOL 247,&X00111000,&X01111110,&X11111011,&X11111111,&X11111111,&X11111111,&X11111111,&X00111100
168 SYMBOL 248,&X10000111,&X01010100,&X10000010,&X01001000,&X10010011,&X01100011,&X10100100,&X00011100
169 SYMBOL 249,&X00000000,&X00000000,&X00011100,&X00000100,&X00000000,&X00000000,&X00000000,&X00000000
170 SYMBOL 240,&X00011000,&X00111100,&X01111110,&X11011011,&X01111110,&X01100110,&X11011011,&X10000001
180 wall$=chr$(245):bkg$=chr$(246):bonus$=chr$(247):wallc$=chr$(248):bonusc$=chr$(249)
185 ply$=chr$(240)
200 DIM map%(maxAr,maxAr)
240 LOCATE 1,22:ink 1,3:print "Loading":PRINT CHR$(22)+CHR$(1)
250 for i=2 to 15:ink i,0:next i
280 lev=lev+1
290 if (lev>=2) THEN RESTORE 1000:lev=0
300 FOR y=1 TO maxAr
400 FOR x=1 TO maxAr
500 READ map(y,x):tile=map(y,x)
550 if tile=0 then locate x,y:pen 8:print bkg$
600 if tile=9 then locate x,y:pen 9:print wall$:locate x,y:pen 12:print wallc$
610 if tile=2 then locate x,y:pen 7:print bonus$:locate x,y:pen 4:print bonusc$
640 NEXT x
650 NEXT y
660 CALL &BC02:border 0:ink 0,0:INK 1,26:x=10:y=8:v=1:sc=0:p=0:PRINT CHR$(22)+CHR$(0)
700 print " ":print "RetroAcademy.":LOCATE 1,22:print "Score 0 - Lev ";lev
740 LOCATE x,y:pen 3:PRINT ply$
750 IF map(y,x)=2 THEN map(y,x)=0:locate 6,22:print sc:sound 2,100,8,10,1,1:sc=sc+1
780 IF NOT(INKEY(8)) AND map(y,x-v)<9 THEN LOCATE x,y:pen 8:PRINT bkg$:x=x-v:sound 1,200,1
800 IF NOT(INKEY(1)) AND map(y,x+v)<9 THEN LOCATE x,y:pen 8:PRINT bkg$:x=x+v:sound 1,300,1
850 IF NOT(INKEY(0)) AND map(y-v,x)<9 THEN LOCATE x,y:pen 8:PRINT bkg$:y=y-v:sound 1,50,1
880 IF NOT(INKEY(2)) AND map(y+v,x)<9 THEN LOCATE x,y:pen 8:PRINT bkg$:y=y+v:sound 1,100,1
900 if sc>=9 then cls:goto 240
950 CALL &BD19
990 GOTO 740
1000 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
1100 DATA 9,0,0,0,0,0,0,0,0,9,9,9,9,9,0,0,0,9,9,9
1200 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
1300 DATA 9,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,0,0,9
1400 DATA 9,9,9,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,9
1500 DATA 9,0,0,9,9,0,0,0,0,9,9,9,9,9,0,0,9,9,9,9
1600 DATA 9,0,0,0,0,0,0,0,0,9,9,9,9,9,0,0,9,9,9,9
1700 DATA 9,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,9
1800 DATA 9,0,0,0,9,9,9,9,2,0,0,0,0,0,0,0,0,0,0,9
1900 DATA 9,0,9,9,9,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9
2000 DATA 9,0,9,9,9,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9
2100 DATA 9,0,0,0,0,2,9,9,9,9,0,9,9,9,0,0,0,9,9,9
2200 DATA 9,0,0,0,9,0,0,0,0,0,0,0,0,2,0,0,0,0,0,9
2300 DATA 9,0,9,9,9,9,0,0,0,9,9,9,9,9,0,0,0,0,0,9
2400 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,0,0,9
2500 DATA 9,0,0,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9,9,9
2600 DATA 9,0,0,0,0,0,9,0,0,9,9,9,9,9,0,0,9,9,9,9
2700 DATA 9,9,9,0,0,0,9,0,0,9,0,0,0,0,0,0,0,0,0,9
2800 DATA 9,9,9,0,0,2,0,0,0,0,0,2,0,0,2,2,0,0,0,9
2900 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
3000 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
3100 DATA 9,0,0,0,0,0,0,0,0,9,9,9,9,9,2,0,0,9,9,9
3200 DATA 9,0,0,0,0,9,9,9,0,0,0,0,0,0,0,0,0,0,0,9
3300 DATA 9,2,0,0,9,9,0,0,0,0,0,9,9,9,9,9,9,0,0,9
3400 DATA 9,9,9,9,9,0,0,0,0,9,0,0,0,0,0,0,0,0,0,9
3500 DATA 9,0,0,0,0,0,0,0,0,9,9,0,0,9,0,0,9,9,9,9
3600 DATA 9,0,0,0,0,0,0,0,0,9,9,0,0,9,0,0,9,9,9,9
3700 DATA 9,0,0,0,9,9,0,0,0,0,0,0,0,9,0,0,0,0,0,9
3800 DATA 9,0,0,0,9,9,9,9,2,0,0,0,0,9,0,0,0,0,2,9
3900 DATA 9,0,9,9,9,9,9,9,9,0,0,9,0,0,0,0,9,9,9,9
4000 DATA 9,0,9,9,9,9,9,9,9,0,0,9,2,0,0,0,9,9,9,9
4100 DATA 9,0,0,0,0,2,9,9,9,9,0,9,9,0,0,0,0,9,9,9
4200 DATA 9,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,2,9
4300 DATA 9,0,9,9,9,9,0,0,0,9,9,9,9,0,0,0,0,0,0,9
4400 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
4500 DATA 9,0,0,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9,9,9
4600 DATA 9,0,0,0,0,0,9,0,0,9,9,9,9,9,0,0,9,9,9,9
4700 DATA 9,0,9,0,0,0,9,0,0,9,0,0,0,0,0,0,0,0,0,9
4800 DATA 9,2,9,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,9
4900 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
Remember, this code is not free bugs and not optimized :)
That's very cool.
:)
However, line 780 is reporting a syntax error.
It needs an extra ")".
i.e. it should be
780 IF NOT(INKEY(8)) AND map%(y%,x%-v%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):x%=x%-1:sound 1,200,1
LOL
simple errata corrige :D
How i can draw multicolor chars in basic (for background)?
I need only enable transparency, with PRINT CHR$(22)+CHR$(1)?
tnx :)
Enable transparency; change pen; print character ;)
ok guys :)
Multicolor version added on top :)
Cool avatar! And btw. always good to see new stuff for the CPC. :)
Quote from: TFM on 21:33, 29 July 16Cool avatar! And btw. always good to see new stuff for the CPC. :)
tnx :)
i'm glad to be here and i hope to help someone..
i have update again on top with two levels :)
This has potential!!!
Thanks mate.
Quote from: Fabrizio Radica on 17:31, 29 July 16
How i can draw multicolor chars in basic (for background)?
I need only enable transparency, with PRINT CHR$(22)+CHR$(1)?
tnx :)
It slows it right down though, as its printing the control character to turn on transparency, then the first character, then the CC to go back a cell, then the CC to change pen, then the second character etc etc.
Nice :)
If you want to speed it up, give it a compile : http://www.cpcwiki.eu/index.php/Fabacom_ (http://www.cpcwiki.eu/index.php/Fabacom_)(FAst_BAsic_COMpiler)
Se si vuole accelerarlo , dare una compilazione
Quote from: SRS on 21:25, 30 July 16
Nice :)
If you want to speed it up, give it a compile : http://www.cpcwiki.eu/index.php/Fabacom_ (http://www.cpcwiki.eu/index.php/Fabacom_)(FAst_BAsic_COMpiler)
Se si vuole accelerarlo , dare una compilazione
Yes thank's a lot!! it's really slow especially when i draw the level.
How i can speedup the rendering process without compile?
tnx :)
Quote from: Fabrizio Radica on 09:31, 31 July 16
Yes thank's a lot!! it's really slow especially when i draw the level.
How i can speedup the rendering process without compile?
tnx
Not showing the drawing process would be the easiest way, the easiest way to do that is simply a matter of setting all the INKs to 0 like this:
for i%=0 to 15:ink i%,0:next i%
There is another way which involves using OUT commands, but the INK approach is just as effective.
Once you've drawn the level, simply using the INKs to display, sorry I don't have your inks on hand, I couldn't see any in your source apart from INK 1,26, in that case you can set the INKs to 0, draw your screen, CALL &BC02 & INK 1,26 to give it that instant look.
Quote from: AMSDOS on 09:40, 31 July 16
Not showing the drawing process would be the easiest way, the easiest way to do that is simply a matter of setting all the INKs to 0 like this:
for i%=0 to 15:ink i%,0:next i%
There is another way which involves using OUT commands, but the INK approach is just as effective.
Once you've drawn the level, simply using the INKs to display, sorry I don't have your inks on hand, I couldn't see any in your source apart from INK 1,26, in that case you can set the INKs to 0, draw your screen, CALL &BC02 & INK 1,26 to give it that instant look.
mmh. it's slow again..
what i wrong?
the logic is correct
- inks to 0 (black screen)
- render level
- back colors
is the map too big? (20x20)
200 DIM map%(20,20)
240 for i%=0 to 15:ink i%,0:next i% 'INKs to 0
250 LOCATE 1,22 : print "Loading." :PRINT CHR$(22)+CHR$(1)
280 lev%=lev%+1
290 if (lev%>=2) THEN lev%=0 : restore 1000
291 'Render MAP
300 FOR y%=1 TO 20 'GENERO LA MAPPA DEL LIVELLO LEGGENDO I DATA
400 FOR x%=1 TO 20
500 READ map%(y%,x%)
550 if map%(y%,x%)=0 then locate x%,y%: pen 8: print chr$(246)
600 if map%(y%,x%)=9 then locate x%,y%: pen 9: print chr$(245):locate x%,y%: pen 12: print chr$(248)
610 if map%(y%,x%)=2 then locate x%,y%: pen 7: print chr$(247):locate x%,y%: pen 4: print chr$(249)
640 NEXT x%
650 NEXT y%
660 CALL &BC02 : border 0: ink 0,0 : INK 1,26: x%=10:y%=8:v%=1:sc%=0:p%=0: PRINT CHR$(22)+CHR$(0)
670 SYMBOL 240,&X00011000,&X00111100,&X01111110,&X11011011,&X01111110,&X01100110,&X11011011,&X10000001
680 SYMBOL 250,&X00000000,&X00000000,&X00000000,&X00100100,&X00000000,&X00000000,&X00000000,&X00000000
700 print " " : print "RetroAcademy." : LOCATE 1,22 : print "Score "
701 'MAIN LOOP
740 LOCATE x%,y%: pen 3: PRINT CHR$(240)
750 IF map%(y%,x%)=2 THEN map%(y%,x%)=0 : sc%=sc%+1 : locate 6,22 : print " ";sc% :sound 2,100,8,10,1,1
780 IF NOT(INKEY(8)) AND map%(y%,x%-v%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):x%=x%-1:sound 1,200,1
800 IF NOT(INKEY(1)) AND map%(y%,x%+v%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):x%=x%+1:sound 1,300,1
850 IF NOT(INKEY(0)) AND map%(y%-v%,x%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):y%=y%-1:sound 1,50,1
880 IF NOT(INKEY(2)) AND map%(y%+v%,x%)<9 THEN LOCATE x%,y%:pen 8:PRINT chr$(246):y%=y%+1:sound 1,100,1
900 if sc%>=9 then cls: goto 240
950 CALL &BD19
990 GOTO 740
tnx again :)
Well I moved the READ map%(y%,x%) from Line 500, to store the DATA from 1000-2900 into the array like this:
3000 restore 1000
3010 for y%=1 to 20
3020 for x%=1 to 20
3030 read map%(y%,x%)
3040 next x%
3050 next y%
3060 return
I don't think there was any improvement of speed.
I don't think there's anything wrong with your code either, that's simply how BASIC handles it, so some people deal with it by setting all the inks to 0, sure it looks a bit suss, some people perhaps prefer the Screen displaying itself at once?
EDIT: From what I can see of your code, I think that is the fastest way possible from BASIC, the Nested FOR..NEXT loops are faster than using WHILE..WEND, it might be slightly faster to using DEFINT a-z rather than declaring Integer variables as with "%" after the variable name.
new version on top, minor bugfixing and speedup :)
i've also tried to render map with tag and tagoff, but it's not much fast than first
295 tag:tilesize=32
300 FOR y=1 TO 20
400 FOR x=1 TO 20
500 READ map(y,x)
520 tile=map(y,x)
550 if tile=0 then move x*tilesize-32,416-y*(tilesize/2): pen 8: print chr$(246);:
600 if tile=9 then move x*tilesize-32,416-y*(tilesize/2): pen 9: print chr$(245);:
610 if tile=2 then move x*tilesize-32,416-y*(tilesize/2): pen 7: print chr$(247);:
640 NEXT x
650 NEXT y
655 tagoff
May be a little bit faster
300 FOR y%=1 TO 20 'GENERO LA MAPPA DEL LIVELLO LEGGENDO I DATA
400 FOR x%=1 TO 20
500 READ a%:map%(y%,x%)=a%:locate x%,y%
550 if a%=0 then pen 8: print chr$(246)
600 if a%=9 then pen 9: print chr$(245);chr$(:pen 12:print chr$(248)
610 if a%=2 then pen 7: print chr$(247);chr$(:pen 4:print chr$(249)
640 NEXT x%
650 NEXT y%
Also: to compact it, take the multiple used code outside to save RAM (and speed, shorter lines, so faster to interpret)
like use of xt & yt instead of using the calc in each line. This works fine with compiled languages, but not our good old interpreted basic :)
549 xt=x*tilesize-32:yt=416-y*(tilesize/2)
Quote from: SRS on 21:18, 31 July 16
May be a little bit faster
300 FOR y%=1 TO 20 'GENERO LA MAPPA DEL LIVELLO LEGGENDO I DATA
400 FOR x%=1 TO 20
500 READ a%:map%(y%,x%)=a%:locate x%,y%
550 if a%=0 then pen 8: print chr$(246)
600 if a%=9 then pen 9: print chr$(245);chr$(:pen 12:print chr$(248)
610 if a%=2 then pen 7: print chr$(247);chr$(:pen 4:print chr$(249)
640 NEXT x%
650 NEXT y%
Also: to compact it, take the multiple used code outside to save RAM (and speed, shorter lines, so faster to interpret)
like use of xt & yt instead of using the calc in each line. This works fine with compiled languages, but not our good old interpreted basic :)
549 xt=x*tilesize-32:yt=416-y*(tilesize/2)
hi :)
Line 600 is reporting a syntax error.
Is should be so?
300 FOR y%=1 TO 20
400 FOR x%=1 TO 20
500 READ a%:map%(y%,x%)=a%:locate x%,y%
550 if a%=0 then pen 8:print chr$(246)
600 if a%=9 then pen 9:print chr$(245):pen 12:print chr$(248)
610 if a%=2 then pen 7:print chr$(247):pen 4:print chr$(249)
640 NEXT x%
650 NEXT y%
btw,this is the result :)
Quote from: SRS on 21:18, 31 July 16
May be a little bit faster
300 FOR y%=1 TO 20 'GENERO LA MAPPA DEL LIVELLO LEGGENDO I DATA
400 FOR x%=1 TO 20
500 READ a%:map%(y%,x%)=a%:locate x%,y%
550 if a%=0 then pen 8: print chr$(246)
600 if a%=9 then pen 9: print chr$(245);chr$(:pen 12:print chr$(248)
610 if a%=2 then pen 7: print chr$(247);chr$(:pen 4:print chr$(249)
640 NEXT x%
650 NEXT y%
Also: to compact it, take the multiple used code outside to save RAM (and speed, shorter lines, so faster to interpret)
like use of xt & yt instead of using the calc in each line. This works fine with compiled languages, but not our good old interpreted basic :)
549 xt=x*tilesize-32:yt=416-y*(tilesize/2)
ok, new optimization (i think) with your help :)
300 curLeft$=CHR$(8)
310 fpen$=CHR$(15)
320 green$=fpen$+CHR$(12)
330 white$=fpen$+CHR$(4)
340 wall$=wa1$+curLeft$+green$+wa2$
350 bonus$=bo1$+curLeft$+white$+bo2$
400 FOR y%=1 TO 20:FOR x%=1 TO 20
500 READ a%:map%(y%,x%)=a%:locate x%,y%
550 if a%=0 then pen 8:print bkg$
600 if a%=9 then pen 9:print wall$
610 if a%=2 then pen 7:print bonus$
640 NEXT x%:NEXT y%
now works fine and a little bit faster then first :)
Try putting GOTO 640 at the end of lines 550, 600 and 610.
This way, if a%=0, then the checks for a%=9 and a%=2 will be skipped.
That should provide a nice little speedup.
Quote from: ervin on 00:25, 01 August 16
Try putting GOTO 640 at the end of lines 550, 600 and 610.
This way, if a%=0, then the checks for a%=9 and a%=2 will be skipped.
That should provide a nice little speedup.
Thank's you Ervin!,
yes we have increased e little bit more. now is "acceptable"...
but, at this point we need the power of ASM ... but i've to study Z80 or use peek and poke (like c64).
next step is add enemies, keys and doors. :)
Quote from: Fabrizio Radica on 22:49, 31 July 16
nice.
somehow copy paste lost this:
if a%=9 then pen 9: print chr$(245);chr$(8):pen 12:print chr$(248)
but I see you fixed it already ;)
Quote from: ervin on 00:25, 01 August 16
Try putting GOTO 640 at the end of lines 550, 600 and 610.
This way, if a%=0, then the checks for a%=9 and a%=2 will be skipped.
That should provide a nice little speedup.
and if you have no line between 610 and 640, you don't need a "GOTO 640" there :D
now this is "Haarspalterei" :D
New version with "physics" (LOOOL)... :D
- new map
- minor speedup
- end game
TO DO:
- keys, doors, enemies
- map loader from disk
- pixel sprite movement (not char)
- ASM optimizations .... in a galaxy far far away :D
HELP:
Anyone can send me a compiled version with BC for testing speed?
Tnx :)
Note:
uncomment the line 860 and comment the line 880 for "zelda" style gameplay
comment the line 860 and uncomment the line 800 for platform game style (default)
uncomment the line 250 for see the rendering map
1 'A (simple) GAME Routine BY FABRIZIO RADICA - 2016 Retroacademy.it
10 DEFINT A-Z:mode 0:transpOn$=CHR$(22)+CHR$(1):transpOff$=CHR$(22)+CHR$(0)
20 cls:border 0:ink 0,0:maxAr%=20:lev%=0:SYMBOL AFTER 60
160 SYMBOL 245,&X01011010,&X00010101,&X11000100,&X11011011,&X00100110,&X01101000,&X01011011,&X11101001
165 SYMBOL 246,&X00010000,&X00000001,&X00001000,&X01010010,&X01000010,&X00001000,&X00010001,&X01000001
166 SYMBOL 247,&X00111000,&X01111110,&X11111011,&X11111111,&X11111111,&X11111111,&X11111111,&X00111100
168 SYMBOL 248,&X10000111,&X01010100,&X10000010,&X01001000,&X10010011,&X01100011,&X10100100,&X00011100
169 SYMBOL 249,&X00000000,&X00000000,&X00011100,&X00000100,&X00000000,&X00000000,&X00000000,&X00000000
170 SYMBOL 240,&X00011000,&X00111100,&X01111110,&X11011011,&X01111110,&X01100110,&X11011011,&X10000001
180 wa1$=chr$(245):bg$=chr$(246):bo1$=chr$(247):wa2$=chr$(248):bo2$=chr$(249):ply$=chr$(240)
200 DIM map%(maxAr,maxAr)
240 PRINT transpOn$:LOCATE 1,22:ink 1,3:print "Loading"
250 for i%=2 to 15:ink i%,0:next i%
290 'if (lev%=2) THEN RESTORE 1000
292 lev%=lev%+1
295 if (lev%>3) THEN cls: PRINT "YOU WIN!!" : end
300 curLeft$=CHR$(:curRight$=CHR$(9):
310 fpen$=CHR$(15):green$=fpen$+CHR$(12):white$=fpen$+CHR$(4):bgcolor$=fpen$+CHR$(:bgr$=bgcolor$+bg$
340 wall$=fpen$+CHR$(9)+wa1$+curLeft$+green$+wa2$:bonus$=fpen$+CHR$(7)+bo1$+curLeft$+white$+bo2$:player$=fpen$+CHR$(3)+ply$
400 FOR y%=1 TO maxAr:FOR x%=1 TO maxAr
500 READ a%:map%(y%,x%)=a%:locate x%,y%
550 if a%=0 then ?bgr$
600 if a%=9 then ?wall$
610 if a%=2 then ?bonus$
640 NEXT x%:NEXT y%
660 CALL &BC02:border 0:ink 0,0:INK 1,26:x%=10:y%=8:v%=1:sc%=0:p%=0:PRINT transpOff$
700 print " ":print "RetroAcademy":LOCATE 1,22:print "Score 0 - Lev ";lev%
740 LOCATE x%,y%:PRINT player$
750 IF map%(y%,x%)=2 THEN map%(y%,x%)=0:locate 6,22:sc%=sc%+1:print sc%:sound 2,100,8,10,1,1
780 IF NOT(INKEY() AND map%(y%,x%-v)<9 THEN LOCATE x%,y%:print bgr$:x%=x%-v:sound 1,200,1:goto 950
800 IF NOT(INKEY(1)) AND map%(y%,x%+v)<9 THEN LOCATE x%,y%:print bgr$:x%=x%+v:sound 1,300,1:goto 950
850 IF NOT(INKEY(0)) AND map%(y%-v,x%)<9 THEN LOCATE x%,y%:print bgr$:y%=y%-v:sound 1,50,1:goto 950
860 'IF NOT(INKEY(2)) AND map%(y%+v,x%)<9 THEN LOCATE x%,y%:print bgr$:y%=y%+v:sound 1,100,1:goto 950
880 IF map%(y%+v,x%)<9 AND INKEY(0)=-1 THEN LOCATE x%,y%:print bgr$:y%=y%+v:sound 1,100,1:goto 950
900 if sc%>=9 then cls: goto 240
950 CALL &BD19
990 goto 740
1000 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
1100 DATA 9,0,0,0,0,0,0,0,0,9,9,9,9,9,0,0,0,9,9,9
1200 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
1300 DATA 9,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,0,0,9
1400 DATA 9,9,9,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,9
1500 DATA 9,0,0,9,9,0,0,0,0,9,9,9,9,9,0,0,9,9,9,9
1600 DATA 9,0,0,0,0,0,0,0,0,9,9,9,9,9,0,0,9,9,9,9
1700 DATA 9,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,9
1800 DATA 9,0,0,0,9,9,9,9,2,0,0,0,0,0,0,0,0,0,0,9
1900 DATA 9,0,9,9,9,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9
2000 DATA 9,0,9,9,9,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9
2100 DATA 9,0,0,0,0,2,9,9,9,9,0,9,9,9,0,0,0,9,9,9
2200 DATA 9,0,0,0,9,0,0,0,0,0,0,0,0,2,0,0,0,0,0,9
2300 DATA 9,0,9,9,9,9,0,0,0,9,9,9,9,9,0,0,0,0,0,9
2400 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,0,0,9
2500 DATA 9,0,0,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9,9,9
2600 DATA 9,0,0,0,0,0,9,0,0,9,9,9,9,9,0,0,9,9,9,9
2700 DATA 9,9,9,0,0,0,9,0,0,9,0,0,0,0,0,0,0,0,0,9
2800 DATA 9,9,9,0,0,2,0,0,0,0,0,2,0,0,2,0,2,0,0,9
2900 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
3000 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
3100 DATA 9,0,0,0,0,0,0,0,0,9,9,9,9,9,2,0,0,9,9,9
3200 DATA 9,0,0,0,0,9,9,9,0,0,0,0,0,0,0,0,0,0,0,9
3300 DATA 9,2,0,0,9,9,0,0,0,0,0,9,9,9,9,9,9,0,0,9
3400 DATA 9,9,9,9,9,0,0,0,0,9,0,0,0,0,0,0,0,0,0,9
3500 DATA 9,0,0,0,0,0,0,0,0,9,9,0,0,9,0,0,9,9,9,9
3600 DATA 9,0,0,0,0,0,0,0,0,9,9,0,0,9,0,0,9,9,9,9
3700 DATA 9,0,0,0,9,9,0,0,0,0,0,0,0,9,0,0,0,0,0,9
3800 DATA 9,0,0,0,9,9,9,9,2,0,0,0,0,9,0,0,0,0,2,9
3900 DATA 9,0,9,9,9,9,9,9,9,0,0,9,0,0,0,0,9,9,9,9
4000 DATA 9,0,9,9,9,9,9,9,9,0,0,9,2,0,0,0,9,9,9,9
4100 DATA 9,0,0,0,0,0,9,9,9,9,0,9,9,0,0,0,0,9,9,9
4200 DATA 9,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,2,9
4300 DATA 9,0,9,9,9,9,0,0,0,9,9,9,9,0,0,0,0,0,0,9
4400 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
4500 DATA 9,0,0,9,9,9,9,0,0,9,9,9,9,9,9,9,9,9,9,9
4600 DATA 9,0,0,0,0,0,9,0,0,9,9,9,9,9,0,0,9,9,9,9
4700 DATA 9,0,9,0,0,0,9,0,0,9,0,0,0,0,0,0,0,0,0,9
4800 DATA 9,2,9,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,9
4900 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
5000 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
5100 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
5200 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
5300 DATA 9,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,9
5400 DATA 9,0,0,0,9,9,9,0,0,0,0,9,9,9,0,0,0,0,0,9
5500 DATA 9,0,0,0,9,9,9,0,0,0,0,9,9,9,0,0,0,0,0,9
5600 DATA 9,0,0,0,9,9,9,0,0,0,0,9,9,9,0,0,0,0,0,9
5700 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
5800 DATA 9,0,0,0,0,0,0,0,9,9,0,0,0,0,0,0,0,0,0,9
5900 DATA 9,0,0,9,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,9
6000 DATA 9,0,0,0,9,0,2,0,0,0,0,0,2,0,9,0,0,0,0,9
6100 DATA 9,0,0,0,0,9,9,9,9,9,9,9,9,9,0,0,0,0,0,9
6200 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
6300 DATA 9,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,9
6400 DATA 9,0,0,0,0,0,0,9,9,9,9,0,0,0,0,0,0,0,0,9
6500 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
6600 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
6700 DATA 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9
6800 DATA 9,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,9
6900 DATA 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
First test of RPG Engine based on my Basic Engine.
- FIFO method
- menu
... i love my Amstrad :D
Quote from: SRS on 18:15, 01 August 16
and if you have no line between 610 and 640, you don't need a "GOTO 640" there :D
now this is "Haarspalterei" :D
Yes, you're absolutely right!
(I can't believe I didn't think of that!)
With a few modifications, I was able to use "ON <expression> GOSUB", which can be compared to the IF..THEN..GOTO version.
10 'A (simple) GAME Routine BY FABRIZIO RADICA - 2016 Retroacademy.it
100 MODE 0: 'PRINT CHR$(22)+CHR$(1) 'mode 0 ed attiva la trasparenza
110 CLS: BORDER 0: INK 0,0
150 maxAr%=20: SYMBOL AFTER 240
160 SYMBOL 245,&X1011010,&X10101,&X11000100,&X11011011,&X100110,&X1101000,&X1011011,&X11101001
165 SYMBOL 246,&X10000,&X1,&X1000,&X1010010,&X1000010,&X1000,&X10001,&X1000001
166 SYMBOL 247,&X111000,&X1111110,&X11111011,&X11111111,&X11111111,&X11111111,&X11111111,&X111100
200 DIM map%(20,20)
250 LOCATE 1,22 : PRINT "Loading..."
300 FOR y%=1 TO 20 'GENERO LA MAPPA DEL LIVELLO LEGGENDO I DATA
400 FOR x%=1 TO 20
500 READ map%(y%,x%)
510 ON map%(y%,x%) GOSUB 3010,3020,3000
640 NEXT x%
650 NEXT y%
660 x%=10:y%=8:v%=1:sc%=0:p%=0
670 SYMBOL 240,&X11000,&X111100,&X1111110,&X11011011,&X1111110,&X1100110,&X11011011,&X10000001
700 PRINT " " : PRINT "RetroAcademy." : LOCATE 1,22 : PRINT "Score "
740 LOCATE x%,y%: PEN 3: PRINT CHR$(240)
750 IF map%(y%,x%)=2 THEN map%(y%,x%)=0 : sc%=sc%+1 : LOCATE 6,22 : PRINT " ";sc% :SOUND 2,100,8,10,1,1
780 IF NOT(INKEY(8)) AND NOT(map%(y%,x%-v%))=1 THEN LOCATE x%,y%:PEN 8:PRINT CHR$(246):x%=x%-1:SOUND 1,200,1
800 IF NOT(INKEY(1)) AND NOT(map%(y%,x%+v%))=1 THEN LOCATE x%,y%:PEN 8:PRINT CHR$(246):x%=x%+1:SOUND 1,300,1
850 IF NOT(INKEY(0)) AND NOT(map%(y%-v%,x%))=1 THEN LOCATE x%,y%:PEN 8:PRINT CHR$(246):y%=y%-1:SOUND 1,50,1
880 IF NOT(INKEY(2)) AND NOT(map%(y%+v%,x%))=1 THEN LOCATE x%,y%:PEN 8:PRINT CHR$(246):y%=y%+1:SOUND 1,100,1
950 CALL &BD19
990 GOTO 740
1000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1100 DATA 1,3,3,3,3,3,3,3,3,1,1,1,1,1,3,3,3,1,1,1
1200 DATA 1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1
1300 DATA 1,3,3,3,3,3,3,3,3,3,3,1,1,1,1,1,1,3,3,1
1400 DATA 1,1,1,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1
1500 DATA 1,3,3,1,1,3,3,3,3,1,1,1,1,1,3,3,1,1,1,1
1600 DATA 1,3,3,3,3,3,3,3,3,1,1,1,1,1,3,3,1,1,1,1
1700 DATA 1,3,3,3,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,1
1800 DATA 1,3,3,3,1,1,1,1,2,3,3,3,3,3,3,3,3,3,3,1
1900 DATA 1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1
2000 DATA 1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1
2100 DATA 1,3,3,3,3,2,1,1,1,1,3,1,1,1,3,3,3,1,1,1
2200 DATA 1,3,3,3,1,3,3,3,3,3,3,3,3,2,3,3,3,3,3,1
2300 DATA 1,3,1,1,1,1,3,3,3,1,1,1,1,3,3,3,3,3,3,1
2400 DATA 1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1
2500 DATA 1,3,3,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1,1
2600 DATA 1,3,3,3,3,3,1,3,3,1,1,1,1,1,3,3,1,1,1,1
2700 DATA 1,1,1,3,3,3,1,3,3,1,3,3,3,3,3,3,3,3,3,1
2800 DATA 1,1,1,3,3,2,3,3,3,3,3,2,3,3,2,2,3,3,3,1
2900 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3000 LOCATE x%,y%: PEN 8: PRINT CHR$(246):RETURN
3010 LOCATE x%,y%: PEN 6: PRINT CHR$(245):RETURN
3020 LOCATE x%,y%: PEN 1: PRINT CHR$(247):RETURN
To get that to work I had to change the DATA, so when ON <expression> GOSUB finds 1 - a wall is drawn, 2 - round yellow ball, 3 - background scenery. 0 isn't valid for this statement to work, so 0 becomes 3. 9 was too big, so I brought it down to 1. This also meant changing Lines 780-880, so as long as 1 was not found, it would continue with the rest of the statement.
Quote from: AMSDOS on 04:27, 02 August 16
With a few modifications, I was able to use "ON <expression> GOSUB", which can be compared to the IF..THEN..GOTO version.
10 'A (simple) GAME Routine BY FABRIZIO RADICA - 2016 Retroacademy.it
100 MODE 0: 'PRINT CHR$(22)+CHR$(1) 'mode 0 ed attiva la trasparenza
110 CLS: BORDER 0: INK 0,0
150 maxAr%=20: SYMBOL AFTER 240
160 SYMBOL 245,&X1011010,&X10101,&X11000100,&X11011011,&X100110,&X1101000,&X1011011,&X11101001
165 SYMBOL 246,&X10000,&X1,&X1000,&X1010010,&X1000010,&X1000,&X10001,&X1000001
166 SYMBOL 247,&X111000,&X1111110,&X11111011,&X11111111,&X11111111,&X11111111,&X11111111,&X111100
200 DIM map%(20,20)
250 LOCATE 1,22 : PRINT "Loading..."
300 FOR y%=1 TO 20 'GENERO LA MAPPA DEL LIVELLO LEGGENDO I DATA
400 FOR x%=1 TO 20
500 READ map%(y%,x%)
510 ON map%(y%,x%) GOSUB 3010,3020,3000
640 NEXT x%
650 NEXT y%
660 x%=10:y%=8:v%=1:sc%=0:p%=0
670 SYMBOL 240,&X11000,&X111100,&X1111110,&X11011011,&X1111110,&X1100110,&X11011011,&X10000001
700 PRINT " " : PRINT "RetroAcademy." : LOCATE 1,22 : PRINT "Score "
740 LOCATE x%,y%: PEN 3: PRINT CHR$(240)
750 IF map%(y%,x%)=2 THEN map%(y%,x%)=0 : sc%=sc%+1 : LOCATE 6,22 : PRINT " ";sc% :SOUND 2,100,8,10,1,1
780 IF NOT(INKEY() AND NOT(map%(y%,x%-v%))=1 THEN LOCATE x%,y%:PEN 8:PRINT CHR$(246):x%=x%-1:SOUND 1,200,1
800 IF NOT(INKEY(1)) AND NOT(map%(y%,x%+v%))=1 THEN LOCATE x%,y%:PEN 8:PRINT CHR$(246):x%=x%+1:SOUND 1,300,1
850 IF NOT(INKEY(0)) AND NOT(map%(y%-v%,x%))=1 THEN LOCATE x%,y%:PEN 8:PRINT CHR$(246):y%=y%-1:SOUND 1,50,1
880 IF NOT(INKEY(2)) AND NOT(map%(y%+v%,x%))=1 THEN LOCATE x%,y%:PEN 8:PRINT CHR$(246):y%=y%+1:SOUND 1,100,1
950 CALL &BD19
990 GOTO 740
1000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1100 DATA 1,3,3,3,3,3,3,3,3,1,1,1,1,1,3,3,3,1,1,1
1200 DATA 1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1
1300 DATA 1,3,3,3,3,3,3,3,3,3,3,1,1,1,1,1,1,3,3,1
1400 DATA 1,1,1,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1
1500 DATA 1,3,3,1,1,3,3,3,3,1,1,1,1,1,3,3,1,1,1,1
1600 DATA 1,3,3,3,3,3,3,3,3,1,1,1,1,1,3,3,1,1,1,1
1700 DATA 1,3,3,3,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,1
1800 DATA 1,3,3,3,1,1,1,1,2,3,3,3,3,3,3,3,3,3,3,1
1900 DATA 1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1
2000 DATA 1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1
2100 DATA 1,3,3,3,3,2,1,1,1,1,3,1,1,1,3,3,3,1,1,1
2200 DATA 1,3,3,3,1,3,3,3,3,3,3,3,3,2,3,3,3,3,3,1
2300 DATA 1,3,1,1,1,1,3,3,3,1,1,1,1,3,3,3,3,3,3,1
2400 DATA 1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1
2500 DATA 1,3,3,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1,1
2600 DATA 1,3,3,3,3,3,1,3,3,1,1,1,1,1,3,3,1,1,1,1
2700 DATA 1,1,1,3,3,3,1,3,3,1,3,3,3,3,3,3,3,3,3,1
2800 DATA 1,1,1,3,3,2,3,3,3,3,3,2,3,3,2,2,3,3,3,1
2900 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3000 LOCATE x%,y%: PEN 8: PRINT CHR$(246):RETURN
3010 LOCATE x%,y%: PEN 6: PRINT CHR$(245):RETURN
3020 LOCATE x%,y%: PEN 1: PRINT CHR$(247):RETURN
To get that to work I had to change the DATA, so when ON <expression> GOSUB finds 1 - a wall is drawn, 2 - round yellow ball, 3 - background scenery. 0 isn't valid for this statement to work, so 0 becomes 3. 9 was too big, so I brought it down to 1. This also meant changing Lines 780-880, so as long as 1 was not found, it would continue with the rest of the statement.
oh great!
I did not know how to assign a color to a tile.
I'm learning new things . it's only a week since I program here
very usefull, tnx :)
now i've a new question.how to draw and move a sprite without symbol command?
I must put data at &4000 and move it with CALL?
i.e. call &4000,sprite,x,y?
tnx :)
Quote from: Fabrizio Radica on 09:35, 02 August 16now i've a new question. how to draw and move a sprite without symbol command? I must put data at &4000 and move it with CALL? i.e. call &4000,sprite,x,y? tnx :)
You've really reached the top end of graphics handling in Basic only, to get sprites into your game you will need to add a bit of ASM (machine code). There are topics around here which show off some sprite drivers. Perhaps you can find something that suits you.
Had a quick look and found this thread. This 10 liner (http://www.cpcwiki.eu/forum/programming/sprites/msg96956/#msg96956) is a good example of what you can do.
@Fabrizio Radica (http://www.cpcwiki.eu/forum/index.php?action=profile;u=1837) :
Welcome.
I will describe the ram of the CPC.
Ram between 0-&40 is used by firmware.
Ram between &a600-&bf00 is used by firmware (and dos).
Screen is normally at &c000-&ffff.
if you use firmware (or basic) you can use ram &40-&a600, but basic uses some of this. So normally address like &4000 or more is used.
Basic starts at &170.
To make your code safe set HIMEM variable with BASIC MEMORY command. All above HIMEM is safe, BASIC doesn't touch it. HIMEM is max address for BASIC. (Under HIMEM is SYMBOL data, variables, basic program etc)
So if you do this:
MEMORY &3FFF
LOAD"driver",&4000
then basic will use &170-&3fff and your code can use &4000-&a600.
If your basic program is large &4000 is too low (basic will tell you "out of memory"), there will not be enough space for basic :(
So you can use higher value. e.g. &8000 or &9000.
Most sprite drivers are built to be in a fixed location in ram. i.e. They can't be relocated but most are higher up in memory.
So using basic and a sprite driver and the data for the sprites requires you to manage your ram a bit.
Quote from: Fabrizio Radica on 09:35, 02 August 16
oh great!
I did not know how to assign a color to a tile.
I'm learning new things . it's only a week since I program here
very usefull, tnx :)
It's not really a colour I'm using from the Data, more of a 1=Wall, 2=Treasure, 3=Background scenario.
ON map%(y%,x%) GOSUB can be used based on the DATA read in Line 500, if 1 is found routine Goes to Subroutine 3000, likewise if 2 or 3 is found it goes to Subroutine 3010 or 3020 and naturally all those Subroutines have RETURN to take you back to the Loop to read the next bit for the Array.
I think it works well and has eliminated a few IFs on the head
Quote from: Fabrizio Radica on 21:54, 01 August 16
HELP:
Anyone can send me a compiled version with BC for testing speed?
Tnx :)
There you go: after fixing the bug in line 780 -> retrofab is the "ESC"abable version, the other one is fast with switch /LE
Quote from: AMSDOS on 11:10, 02 August 16
It's not really a colour I'm using from the Data, more of a 1=Wall, 2=Treasure, 3=Background scenario.
ON map%(y%,x%) GOSUB can be used based on the DATA read in Line 500, if 1 is found routine Goes to Subroutine 3000, likewise if 2 or 3 is found it goes to Subroutine 3010 or 3020 and naturally all those Subroutines have RETURN to take you back to the Loop to read the next bit for the Array.
I think it works well and has eliminated a few IFs on the head
works very well,
i need to disasm to see the process.
btw, i think that gosub is more faster than if in any situations.
Quote from: SRS on 11:18, 02 August 16
There you go: after fixing the bug in line 780 -> retrofab is the "ESC"abable version, the other one is fast with switch /LE
oh, tnx mate :)
now, i need to make a DSK with FA.BA.COM.
New update and new video with new stuff :)
aaargh... i've this problem with the 464 :(
how do i resolve it?
in basic 1.1 works fine (664 and 6128)
tnx.
here the code:
1 'A (simple) GAME Routine BY FABRIZIO RADICA - 2016 Retroacademy.it
10 DEFINT A-Z:mode 0:transpOn$=CHR$(22)+CHR$(1):transpOff$=CHR$(22)+CHR$(0)
20 border 0:ink 0,0:maxx%=20:maxy%=20:lev%=0:isDown%=0:SYMBOL AFTER 240
160 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X00000000,&X00000000 'wall
165 SYMBOL 246,&X01111110,&X10000000,&X10000000,&X10000000,&X10000000,&X10000000,&X00000000,&X00000000 'background
166 SYMBOL 247,&X00111100,&X01111110,&X11111011,&X11111111,&X11111111,&X11111111,&X01111110,&X00111100 'bonus
168 SYMBOL 248,&X11000000,&X00000000,&X00000000,&X00000000,&X00000000,&X00000000,&X00000000,&X00000000 'wall color
169 SYMBOL 249,&X00000000,&X00000000,&X00000100,&X00000000,&X00000000,&X00000000,&X00000000,&X00000000 'bonus light
170 SYMBOL 240,&X00111100,&X01111110,&X11101011,&X11111111,&X11111111,&X11000011,&X01100110,&X00111100 'player right
171 SYMBOL 250,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111 'ladders
172 SYMBOL 251,&X00111100,&X01111110,&X11010111,&X11111111,&X11111111,&X11000011,&X01100110,&X00111100 'player left
180 wa1$=chr$(245):bg$=chr$(246):bo1$=chr$(247):wa2$=chr$(248):bo2$=chr$(249):plyr$=chr$(240):plyl$=chr$(251):lad$=chr$(250)
200 DIM map%(maxy%,maxx%)
240 cls:PRINT transpOn$:LOCATE 1,24:ink 1,3:print "Loading"
250 for i%=2 to 15:ink i%,0:next i%
292 lev%=lev%+1
295 if (lev%>3) THEN cls: PRINT "YOU WIN!!" : end
300 curLeft$=CHR$(:curRight$=CHR$(9)
310 fpen$=CHR$(15):green$=fpen$+CHR$(12):white$=fpen$+CHR$(4):bgcolor$=fpen$+CHR$(:bgr$=bgcolor$+bg$
340 wall$=fpen$+CHR$(9)+wa1$+curLeft$+white$+wa2$:bonus$=fpen$+CHR$(7)+bo1$+curLeft$+white$+bo2$:playerr$=fpen$+CHR$(3)+plyr$:playerl$=fpen$+CHR$(3)+plyl$:ladders$=white$+lad$
345 DIM obj$(10),playerFrame$(10)
350 obj$(1)=wall$:obj$(2)=bonus$:obj$(3)=ladders$
354 frcount=1
355 pFrame$(1)=playerr$
356 pFrame$(2)=playerl$
400 FOR y%=1 TO maxy%
410 FOR x%=1 TO maxx%
420 READ a%:map%(y%,x%)=a%:locate x%,y%
430 ON map%(y%,x%) GOSUB 30010,30020,30030,30000
440 NEXT x%:NEXT y%
660 CALL &BC02:border 0:ink 0,0:INK 1,26:x%=2:y%=4:v%=1:sc%=0:p%=0:PRINT transpOff$
700 LOCATE 1,24:print "Score 0 - Lev ";lev%
720 'memory &7fff:load"music.bin",&8000:call &8000
740 LOCATE x%,y%:PRINT pFrame$(frcount):CALL &BD19
750 IF map%(y%,x%)=2 THEN map%(y%,x%)=0:locate 6,24:sc%=sc%+1:print sc%
780 IF NOT(INKEY() AND NOT(map%(y%,x%-v%)=1) AND NOT(map%(y%+v%,x%)=0) THEN frcount=2: gosub 40000: x%=x%-v%
800 IF NOT(INKEY(1)) AND NOT(map%(y%,x%+v%)=1) AND NOT(map%(y%+v%,x%)=0) THEN frcount=1: gosub 40000: x%=x%+v%
850 IF NOT(INKEY(0)) AND NOT(map%(y%-v%,x%)=1) AND map%(y%-v%,x%)=3 THEN gosub 40000:y%=y%-v%
860 IF NOT(INKEY(2)) AND NOT(map%(y%+v%,x%)=1) AND map%(y%+v%,x%)=3 THEN gosub 40000:y%=y%+v%
880 IF map%(y%+v%,x%)=0 or map%(y%+v%,x%)=2 THEN gosub 40000:y%=y%+v%
900 'if sc%>=9 then cls: goto 240
990 goto 740
1000 DATA 0,0,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0
1100 DATA 0,1,4,4,0,0,0,0,4,1,1,1,1,1,0,0,0,1,1,0
1200 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,3,0,1
1300 DATA 1,0,0,0,0,0,4,4,0,0,0,1,1,1,1,1,1,3,0,1
1400 DATA 1,1,1,0,3,0,0,0,0,2,0,0,0,0,0,3,0,3,0,1
1500 DATA 1,0,0,1,3,0,0,0,0,1,1,1,1,1,0,3,1,1,1,1
1600 DATA 1,0,0,0,3,0,0,0,0,1,1,1,1,1,0,3,1,1,1,1
1700 DATA 1,0,0,0,3,1,2,0,0,0,0,4,4,0,0,3,0,4,4,1
1800 DATA 1,0,0,0,3,1,1,1,0,0,3,0,2,0,0,3,0,0,0,1
1900 DATA 1,2,1,1,3,1,0,0,1,0,3,1,1,1,1,1,1,1,1,0
2000 DATA 1,0,1,1,3,1,0,0,1,0,3,1,1,1,1,1,1,1,0,0
2100 DATA 1,0,0,0,3,3,1,1,1,1,3,1,1,1,0,4,4,1,1,0
2200 DATA 1,0,0,0,1,3,3,0,0,0,3,0,2,0,0,0,0,0,0,1
2300 DATA 1,0,1,1,1,1,3,0,0,1,1,1,1,1,0,0,2,0,0,1
2400 DATA 1,0,3,0,3,0,3,0,3,0,0,0,0,0,1,1,1,0,0,1
2500 DATA 1,0,3,1,3,1,1,0,3,1,1,1,1,1,1,1,1,1,0,1
2600 DATA 1,0,3,0,3,4,1,0,3,1,1,1,1,1,0,0,1,1,0,1
2700 DATA 0,1,1,0,3,0,1,0,3,1,0,4,4,0,0,0,0,0,0,1
2800 DATA 0,0,1,0,3,0,0,0,3,0,0,0,0,0,2,0,2,0,0,1
2900 DATA 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
30000 locate x%,y%:print bgr$:return
30010 locate x%,y%:print obj$(1):return
30020 locate x%,y%:print obj$(2):return
30030 locate x%,y%:print obj$(3):return
40000 LOCATE x%,y%:print" ":LOCATE x%,y%:print obj$(map%(y%,x%)):return
EDIT:
Ok, the BIG problem is here, with chr$(8 ) and chr$(15)
300 curLeft$=CHR$(8 ):curRight$=CHR$(9)
310 fpen$=CHR$(15):green$=fpen$+CHR$(12):white$=fpen$+CHR$(4):bgcolor$=fpen$+CHR$(8 )bgr$=bgcolor$+bg$
340 wall$=fpen$+CHR$(9)+wa1$+curLeft$+white$+wa2$:bonus$=fpen$+CHR$(7)+bo1$+curLeft$+white$+bo2$:playerr$=fpen$+CHR$(3)+plyr$:playerl$=fpen$+CHR$(3)+plyl$:ladders$=white$+lad$
if you replacing the lines 300,310,340 with:
300 curLeft$=CHR$(8 ):curRight$=CHR$(9)
310 fpen$=CHR$(15):green$=fpen$+CHR$(12):white$=fpen$+CHR$(4):bgcolor$=fpen$+CHR$(:bgr$=bgcolor$+bg$
340 wall$=wa1$:bonus$=fpen$+CHR$(7)+bo1$:playerr$=plyr$:playerl$=plyl$:ladders$=white$+lad$
works fine on 464...
but i don't know how to resolve it... :doh:
This is becoming a more problematic as the 464 handles Strings a little bit differently from the 664/6128. Morri started a thread (http://www.cpcwiki.eu/forum/programming/basic-game-idea-help-on-music-needed/) a while ago and I posted a work around in it which worked, but when Coolbox came out, more complications arose and haven't got around to sorting them out ???
Perhaps the easiest solution is to ditch the control code thing, Morri suggested using David Hall's Ariom Sprites, which would be more than adequate here for 8x8 Sprites, I maybe able to rummage through my Disks to find the program if you don't want to type it in.
Yes I have experienced this same nightmare.
Ronaldo tried to explain it to me here. (http://www.cpcwiki.eu/forum/games/coolbox-(new-game-in-basic)/msg129022/#msg129022) Perhaps his explanation may help you.
Ok folks, this is what I knocked up to get it to work on a 464:
1 'A (simple) GAME Routine BY FABRIZIO RADICA - 2016 Retroacademy.it
10 DEFINT A-Z:MODE 0:transpOn$=CHR$(22)+CHR$(1):transpOff$=CHR$(22)+CHR$(0)
11 ON BREAK GOSUB 50000
20 BORDER 0:INK 0,0:maxx%=20:maxy%=20:lev%=0:isDown%=0:SYMBOL AFTER 240
160 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
165 SYMBOL 246,&X1111110,&X10000000,&X10000000,&X10000000,&X10000000,&X10000000,&X0,&X0 'background
166 SYMBOL 247,&X111100,&X1111110,&X11111011,&X11111111,&X11111111,&X11111111,&X1111110,&X111100 'bonus
168 SYMBOL 248,&X11000000,&X0,&X0,&X0,&X0,&X0,&X0,&X0 'wall color
169 SYMBOL 249,&X0,&X0,&X100,&X0,&X0,&X0,&X0,&X0 'bonus light
170 SYMBOL 240,&X111100,&X1111110,&X11101011,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player right
171 SYMBOL 250,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111 'ladders
172 SYMBOL 251,&X111100,&X1111110,&X11010111,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player left
180 wa1$=CHR$(245):bg$=CHR$(246):bo1$=CHR$(247):wa2$=CHR$(248):bo2$=CHR$(249):plyr$=CHR$(240):plyl$=CHR$(251):lad$=CHR$(250)
200 DIM map%(maxy%,maxx%)
240 CLS:PRINT transpOn$:LOCATE 1,24:INK 1,3:PRINT "Loading"
250 ' FOR i%=2 TO 15:INK i%,0:NEXT i%
292 lev%=lev%+1
295 IF (lev%>3) THEN CLS: PRINT "YOU WIN!!" : END
300 curLeft$=CHR$(8):curRight$=CHR$(9)
310 fpen$=CHR$(15):green$=fpen$+CHR$(12):white$=fpen$+CHR$(4):bgcolor$=fpen$+CHR$(8):bgr$=bgcolor$+bg$
340 wall$=fpen$+CHR$(9)+wa1$+curLeft$+white$+wa2$:bonus$=fpen$+CHR$(7)+bo1$+curLeft$+white$+bo2$:playerr$=fpen$+CHR$(3)+plyr$:playerl$=fpen$+CHR$(3)+plyl$:ladders$=white$+lad$
345 DIM obj$(10),playerFrame$(10)
350 obj$(1)=wall$:obj$(2)=bonus$:obj$(3)=ladders$
354 frcount=1
355 pframe$(1)=CHR$(240)
356 pframe$(2)=CHR$(251)
400 FOR y%=1 TO maxy%
410 FOR x%=1 TO maxx%
420 READ a%:map%(y%,x%)=a%:LOCATE x%,y%
430 ON map%(y%,x%) GOSUB 30010,30020,30030,30000
440 NEXT x%:NEXT y%
660 CALL &BC02:BORDER 0:INK 0,0:INK 1,26:x%=2:y%=4:v%=1:sc%=0:p%=0:PRINT transpOff$
700 LOCATE 1,24:PRINT "Score 0 - Lev ";lev%
720 'memory &7fff:load"music.bin",&8000:call &8000
740 LOCATE 1,1 : PRINT CHR$(15);CHR$(3); : LOCATE x%,y% : PRINT pframe$(frcount):CALL &BD19
750 IF map%(y%,x%)=2 THEN map%(y%,x%)=0:LOCATE 6,24:sc%=sc%+1:PRINT sc%
780 IF NOT(INKEY(8)) AND NOT(map%(y%,x%-v%)=1) AND NOT(map%(y%+v%,x%)=0) THEN frcount=2: GOSUB 40000: x%=x%-v%
800 IF NOT(INKEY(1)) AND NOT(map%(y%,x%+v%)=1) AND NOT(map%(y%+v%,x%)=0) THEN frcount=1: GOSUB 40000: x%=x%+v%
850 IF NOT(INKEY(0)) AND NOT(map%(y%-v%,x%)=1) AND map%(y%-v%,x%)=3 THEN GOSUB 40000:y%=y%-v%
860 IF NOT(INKEY(2)) AND NOT(map%(y%+v%,x%)=1) AND map%(y%+v%,x%)=3 THEN GOSUB 40000:y%=y%+v%
880 IF map%(y%+v%,x%)=0 OR map%(y%+v%,x%)=2 THEN GOSUB 40000:y%=y%+v%
900 'if sc%>=9 then cls: goto 240
990 GOTO 740
1000 DATA 0,0,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0
1100 DATA 0,1,4,4,0,0,0,0,4,1,1,1,1,1,0,0,0,1,1,0
1200 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,3,0,1
1300 DATA 1,0,0,0,0,0,4,4,0,0,0,1,1,1,1,1,1,3,0,1
1400 DATA 1,1,1,0,3,0,0,0,0,2,0,0,0,0,0,3,0,3,0,1
1500 DATA 1,0,0,1,3,0,0,0,0,1,1,1,1,1,0,3,1,1,1,1
1600 DATA 1,0,0,0,3,0,0,0,0,1,1,1,1,1,0,3,1,1,1,1
1700 DATA 1,0,0,0,3,1,2,0,0,0,0,4,4,0,0,3,0,4,4,1
1800 DATA 1,0,0,0,3,1,1,1,0,0,3,0,2,0,0,3,0,0,0,1
1900 DATA 1,2,1,1,3,1,0,0,1,0,3,1,1,1,1,1,1,1,1,0
2000 DATA 1,0,1,1,3,1,0,0,1,0,3,1,1,1,1,1,1,1,0,0
2100 DATA 1,0,0,0,3,3,1,1,1,1,3,1,1,1,0,4,4,1,1,0
2200 DATA 1,0,0,0,1,3,3,0,0,0,3,0,2,0,0,0,0,0,0,1
2300 DATA 1,0,1,1,1,1,3,0,0,1,1,1,1,1,0,0,2,0,0,1
2400 DATA 1,0,3,0,3,0,3,0,3,0,0,0,0,0,1,1,1,0,0,1
2500 DATA 1,0,3,1,3,1,1,0,3,1,1,1,1,1,1,1,1,1,0,1
2600 DATA 1,0,3,0,3,4,1,0,3,1,1,1,1,1,0,0,1,1,0,1
2700 DATA 0,1,1,0,3,0,1,0,3,1,0,4,4,0,0,0,0,0,0,1
2800 DATA 0,0,1,0,3,0,0,0,3,0,0,0,0,0,2,0,2,0,0,1
2900 DATA 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
30000 LOCATE 1,1 : PRINT CHR$(15);CHR$(8); : LOCATE x%,y% : PRINT CHR$(246);:RETURN
30010 LOCATE 1,1 : PRINT CHR$(15);CHR$(9); : LOCATE x%,y% : PRINT CHR$(245);
30011 LOCATE 1,1 : PRINT CHR$(15);CHR$(4); : LOCATE x%,y% : PRINT CHR$(248);:RETURN
30020 LOCATE 1,1 : PRINT CHR$(15);CHR$(7); : LOCATE x%,y% : PRINT CHR$(247);
30021 LOCATE 1,1 : PRINT CHR$(15);CHR$(4); : LOCATE x%,y% : PRINT CHR$(249);:RETURN
30030 LOCATE 1,1 : PRINT CHR$(15);CHR$(4); : LOCATE x%,y% : PRINT CHR$(250);:RETURN
40000 LOCATE x%,y%:PRINT" ";:LOCATE x%,y%:PRINT obj$(map%(y%,x%));:RETURN
50000 CLEAR : CALL &BC02 : PEN 1 : MODE 2 : END
I've added Line 11 and 50000, which exits the program when break, and clear helps keep the 464 running smoothly.
curLeft & curRight are not used any more, and I'm deliberately positioning the control codes for the pen. My Face character is now a single Character, though still operates from the Array so Facing Left & Right works. Lines 300-350 remain, even though there's stuff there I'm not using, other things are being used, which change the outcome if they are removed.
I made notes which I'll post here in case it helps:
-- Control Codes --
fpen$=chr$(15)
curleft$=chr$(8)
curright$=chr$(9)
white$=fpen$+chr$(4)
-- Print Wall --
obj$(1)=wall$
wall$=fpen$+chr$(9)+wa1$+curleft$+white$+wa2$
wa1$=chr$(245)
wa2$=chr$(248)
chr$(15);chr$(9);chr$(245);chr$(8);chr$(15);chr$(4);chr$(248)
locate 1,1: print chr$(15);chr$(9) : locate x%,y% : print chr$(245);
locate 1,1: print chr$(15);chr$(4) : locate x%,y% : print chr$(248);
bonus$=fpen$+CHR$(7)+bo1$+curLeft$+white$+bo2$
bo1$=chr$(247)
bo2$=chr$(249)
-- Print Bonus --
obj$(2)=bonus$
chr$(15);chr$(7);chr$(247);chr$(8);chr$(15);chr$(4);chr$(249)
locate 1,1 : print chr$(15);chr$(7) : locate x%,y% : print chr$(247);
locate 1,1 : print chr$(15);chr$(4) : locate x%,y% : print chr$(249);
-- Print Ladder --
obj$(3)=ladders$
chr$(15);chr$(4);chr$(250)
locate 1,1 : print chr$(15);chr$(4); : locate x%,y% : print chr$(250);
bgr$=chr$(15);chr$(8);chr$(246);
locate 1,1 : print chr$(15);chr$(8); : locate x%,y% : print chr$(246);
-- Print Player Left & Right --
playerr$=chr$(15);chr$(3);chr$(240)
playerl$=chr$(15);chr$(3);chr$(251)
locate 1,1 : print chr$(15);chr$(3); : locate x%,y% : print pframe$(frcount):call &bd19
pframe$(1)=chr$(240)
pframe$(2)=chr$(251)
Screenshot:
[attachimg=1]
Quote from: AMSDOS on 07:48, 04 August 16
Ok folks, this is what I knocked up to get it to work on a 464:
1 'A (simple) GAME Routine BY FABRIZIO RADICA - 2016 Retroacademy.it
10 DEFINT A-Z:MODE 0:transpOn$=CHR$(22)+CHR$(1):transpOff$=CHR$(22)+CHR$(0)
11 ON BREAK GOSUB 50000
20 BORDER 0:INK 0,0:maxx%=20:maxy%=20:lev%=0:isDown%=0:SYMBOL AFTER 240
160 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
165 SYMBOL 246,&X1111110,&X10000000,&X10000000,&X10000000,&X10000000,&X10000000,&X0,&X0 'background
166 SYMBOL 247,&X111100,&X1111110,&X11111011,&X11111111,&X11111111,&X11111111,&X1111110,&X111100 'bonus
168 SYMBOL 248,&X11000000,&X0,&X0,&X0,&X0,&X0,&X0,&X0 'wall color
169 SYMBOL 249,&X0,&X0,&X100,&X0,&X0,&X0,&X0,&X0 'bonus light
170 SYMBOL 240,&X111100,&X1111110,&X11101011,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player right
171 SYMBOL 250,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111 'ladders
172 SYMBOL 251,&X111100,&X1111110,&X11010111,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player left
180 wa1$=CHR$(245):bg$=CHR$(246):bo1$=CHR$(247):wa2$=CHR$(248):bo2$=CHR$(249):plyr$=CHR$(240):plyl$=CHR$(251):lad$=CHR$(250)
200 DIM map%(maxy%,maxx%)
240 CLS:PRINT transpOn$:LOCATE 1,24:INK 1,3:PRINT "Loading"
250 ' FOR i%=2 TO 15:INK i%,0:NEXT i%
292 lev%=lev%+1
295 IF (lev%>3) THEN CLS: PRINT "YOU WIN!!" : END
300 curLeft$=CHR$(:curRight$=CHR$(9)
310 fpen$=CHR$(15):green$=fpen$+CHR$(12):white$=fpen$+CHR$(4):bgcolor$=fpen$+CHR$(:bgr$=bgcolor$+bg$
340 wall$=fpen$+CHR$(9)+wa1$+curLeft$+white$+wa2$:bonus$=fpen$+CHR$(7)+bo1$+curLeft$+white$+bo2$:playerr$=fpen$+CHR$(3)+plyr$:playerl$=fpen$+CHR$(3)+plyl$:ladders$=white$+lad$
345 DIM obj$(10),playerFrame$(10)
350 obj$(1)=wall$:obj$(2)=bonus$:obj$(3)=ladders$
354 frcount=1
355 pframe$(1)=CHR$(240)
356 pframe$(2)=CHR$(251)
400 FOR y%=1 TO maxy%
410 FOR x%=1 TO maxx%
420 READ a%:map%(y%,x%)=a%:LOCATE x%,y%
430 ON map%(y%,x%) GOSUB 30010,30020,30030,30000
440 NEXT x%:NEXT y%
660 CALL &BC02:BORDER 0:INK 0,0:INK 1,26:x%=2:y%=4:v%=1:sc%=0:p%=0:PRINT transpOff$
700 LOCATE 1,24:PRINT "Score 0 - Lev ";lev%
720 'memory &7fff:load"music.bin",&8000:call &8000
740 LOCATE 1,1 : PRINT CHR$(15);CHR$(3); : LOCATE x%,y% : PRINT pframe$(frcount):CALL &BD19
750 IF map%(y%,x%)=2 THEN map%(y%,x%)=0:LOCATE 6,24:sc%=sc%+1:PRINT sc%
780 IF NOT(INKEY() AND NOT(map%(y%,x%-v%)=1) AND NOT(map%(y%+v%,x%)=0) THEN frcount=2: GOSUB 40000: x%=x%-v%
800 IF NOT(INKEY(1)) AND NOT(map%(y%,x%+v%)=1) AND NOT(map%(y%+v%,x%)=0) THEN frcount=1: GOSUB 40000: x%=x%+v%
850 IF NOT(INKEY(0)) AND NOT(map%(y%-v%,x%)=1) AND map%(y%-v%,x%)=3 THEN GOSUB 40000:y%=y%-v%
860 IF NOT(INKEY(2)) AND NOT(map%(y%+v%,x%)=1) AND map%(y%+v%,x%)=3 THEN GOSUB 40000:y%=y%+v%
880 IF map%(y%+v%,x%)=0 OR map%(y%+v%,x%)=2 THEN GOSUB 40000:y%=y%+v%
900 'if sc%>=9 then cls: goto 240
990 GOTO 740
1000 DATA 0,0,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0
1100 DATA 0,1,4,4,0,0,0,0,4,1,1,1,1,1,0,0,0,1,1,0
1200 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,3,0,1
1300 DATA 1,0,0,0,0,0,4,4,0,0,0,1,1,1,1,1,1,3,0,1
1400 DATA 1,1,1,0,3,0,0,0,0,2,0,0,0,0,0,3,0,3,0,1
1500 DATA 1,0,0,1,3,0,0,0,0,1,1,1,1,1,0,3,1,1,1,1
1600 DATA 1,0,0,0,3,0,0,0,0,1,1,1,1,1,0,3,1,1,1,1
1700 DATA 1,0,0,0,3,1,2,0,0,0,0,4,4,0,0,3,0,4,4,1
1800 DATA 1,0,0,0,3,1,1,1,0,0,3,0,2,0,0,3,0,0,0,1
1900 DATA 1,2,1,1,3,1,0,0,1,0,3,1,1,1,1,1,1,1,1,0
2000 DATA 1,0,1,1,3,1,0,0,1,0,3,1,1,1,1,1,1,1,0,0
2100 DATA 1,0,0,0,3,3,1,1,1,1,3,1,1,1,0,4,4,1,1,0
2200 DATA 1,0,0,0,1,3,3,0,0,0,3,0,2,0,0,0,0,0,0,1
2300 DATA 1,0,1,1,1,1,3,0,0,1,1,1,1,1,0,0,2,0,0,1
2400 DATA 1,0,3,0,3,0,3,0,3,0,0,0,0,0,1,1,1,0,0,1
2500 DATA 1,0,3,1,3,1,1,0,3,1,1,1,1,1,1,1,1,1,0,1
2600 DATA 1,0,3,0,3,4,1,0,3,1,1,1,1,1,0,0,1,1,0,1
2700 DATA 0,1,1,0,3,0,1,0,3,1,0,4,4,0,0,0,0,0,0,1
2800 DATA 0,0,1,0,3,0,0,0,3,0,0,0,0,0,2,0,2,0,0,1
2900 DATA 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
30000 LOCATE 1,1 : PRINT CHR$(15);CHR$(; : LOCATE x%,y% : PRINT CHR$(246);:RETURN
30010 LOCATE 1,1 : PRINT CHR$(15);CHR$(9); : LOCATE x%,y% : PRINT CHR$(245);
30011 LOCATE 1,1 : PRINT CHR$(15);CHR$(4); : LOCATE x%,y% : PRINT CHR$(248);:RETURN
30020 LOCATE 1,1 : PRINT CHR$(15);CHR$(7); : LOCATE x%,y% : PRINT CHR$(247);
30021 LOCATE 1,1 : PRINT CHR$(15);CHR$(4); : LOCATE x%,y% : PRINT CHR$(249);:RETURN
30030 LOCATE 1,1 : PRINT CHR$(15);CHR$(4); : LOCATE x%,y% : PRINT CHR$(250);:RETURN
40000 LOCATE x%,y%:PRINT" ";:LOCATE x%,y%:PRINT obj$(map%(y%,x%));:RETURN
50000 CLEAR : CALL &BC02 : PEN 1 : MODE 2 : END
I've added Line 11 and 50000, which exits the program when break, and clear helps keep the 464 running smoothly.
curLeft & curRight are not used any more, and I'm deliberately positioning the control codes for the pen. My Face character is now a single Character, though still operates from the Array so Facing Left & Right works. Lines 300-350 remain, even though there's stuff there I'm not using, other things are being used, which change the outcome if they are removed.
I made notes which I'll post here in case it helps:
-- Control Codes --
fpen$=chr$(15)
curleft$=chr$(
curright$=chr$(9)
white$=fpen$+chr$(4)
-- Print Wall --
obj$(1)=wall$
wall$=fpen$+chr$(9)+wa1$+curleft$+white$+wa2$
wa1$=chr$(245)
wa2$=chr$(248)
chr$(15);chr$(9);chr$(245);chr$(;chr$(15);chr$(4);chr$(248)
locate 1,1: print chr$(15);chr$(9) : locate x%,y% : print chr$(245);
locate 1,1: print chr$(15);chr$(4) : locate x%,y% : print chr$(248);
bonus$=fpen$+CHR$(7)+bo1$+curLeft$+white$+bo2$
bo1$=chr$(247)
bo2$=chr$(249)
-- Print Bonus --
obj$(2)=bonus$
chr$(15);chr$(7);chr$(247);chr$(;chr$(15);chr$(4);chr$(249)
locate 1,1 : print chr$(15);chr$(7) : locate x%,y% : print chr$(247);
locate 1,1 : print chr$(15);chr$(4) : locate x%,y% : print chr$(249);
-- Print Ladder --
obj$(3)=ladders$
chr$(15);chr$(4);chr$(250)
locate 1,1 : print chr$(15);chr$(4); : locate x%,y% : print chr$(250);
bgr$=chr$(15);chr$(;chr$(246);
locate 1,1 : print chr$(15);chr$(; : locate x%,y% : print chr$(246);
-- Print Player Left & Right --
playerr$=chr$(15);chr$(3);chr$(240)
playerl$=chr$(15);chr$(3);chr$(251)
locate 1,1 : print chr$(15);chr$(3); : locate x%,y% : print pframe$(frcount):call &bd19
pframe$(1)=chr$(240)
pframe$(2)=chr$(251)
Screenshot:
[attachimg=1]
Many thanks' mate!!!
Now i try to correct it and comprehend your modify for optimize again :)
Really thanks for your support and for having helped me :)
Quote from: Fabrizio Radica on 08:55, 04 August 16
Many thanks' mate!!!
Now i try to correct it and comprehend your modify for optimize again :)
Really thanks for your support and for having helped me :)
You might want to try this one out for size, it also works on a 464 a looks a little bit more like your code. The only difference I'm still not using curLeft$ or curRight control codes, but I'm using the Control code for Locate - chr(31)+chr(x%)+chr(y%) which lets me then incorporate it all in a single PRINT statement (even the PEN control code is in there).
1 'A (simple) GAME Routine BY FABRIZIO RADICA - 2016 Retroacademy.it
10 DEFINT A-Z:MODE 0:transpOn$=CHR$(22)+CHR$(1):transpOff$=CHR$(22)+CHR$(0)
11 ON BREAK GOSUB 50000
20 BORDER 0:INK 0,0:maxx%=20:maxy%=20:lev%=0:isDown%=0:SYMBOL AFTER 240
160 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
165 SYMBOL 246,&X1111110,&X10000000,&X10000000,&X10000000,&X10000000,&X10000000,&X0,&X0 'background
166 SYMBOL 247,&X111100,&X1111110,&X11111011,&X11111111,&X11111111,&X11111111,&X1111110,&X111100 'bonus
168 SYMBOL 248,&X11000000,&X0,&X0,&X0,&X0,&X0,&X0,&X0 'wall color
169 SYMBOL 249,&X0,&X0,&X100,&X0,&X0,&X0,&X0,&X0 'bonus light
170 SYMBOL 240,&X111100,&X1111110,&X11101011,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player right
171 SYMBOL 250,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111 'ladders
172 SYMBOL 251,&X111100,&X1111110,&X11010111,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player left
180 wa1$=CHR$(245):bg$=CHR$(246):bo1$=CHR$(247):wa2$=CHR$(248):bo2$=CHR$(249):plyr$=CHR$(240):plyl$=CHR$(251):lad$=CHR$(250)
200 DIM map%(maxy%,maxx%)
240 CLS:PRINT transpOn$:LOCATE 1,24:INK 1,3:PRINT "Loading"
250 ' FOR i%=2 TO 15:INK i%,0:NEXT i%
292 lev%=lev%+1
295 IF (lev%>3) THEN CLS: PRINT "YOU WIN!!" : END
310 fpen$=CHR$(15):green$=fpen$+CHR$(12):white$=fpen$+CHR$(4):bgcolor$=fpen$+CHR$(8):bgr$=bgcolor$+bg$
340 wall$=fpen$+CHR$(9)+wa1$+curLeft$+white$+wa2$:bonus$=fpen$+CHR$(7)+bo1$+curLeft$+white$+bo2$:playerr$=fpen$+CHR$(3)+plyr$:playerl$=fpen$+CHR$(3)+plyl$:ladders$=white$+lad$
345 DIM obj$(10),playerFrame$(10)
350 obj$(1)=wall$:obj$(2)=bonus$:obj$(3)=ladders$
354 frcount=1
355 pframe$(1)=CHR$(240)
356 pframe$(2)=CHR$(251)
400 FOR y%=1 TO maxy%
410 FOR x%=1 TO maxx%
420 READ a%:map%(y%,x%)=a%:LOCATE x%,y%
430 ON map%(y%,x%) GOSUB 30010,30020,30030,30000
440 NEXT x%:NEXT y%
660 CALL &BC02:BORDER 0:INK 0,0:INK 1,26:x%=2:y%=4:v%=1:sc%=0:p%=0:PRINT transpOff$
700 LOCATE 1,24:PRINT "Score 0 - Lev ";lev%
720 'memory &7fff:load"music.bin",&8000:call &8000
740 PRINT CHR$(31)+CHR$(x%)+CHR$(y%)+CHR$(15)+CHR$(3)+pframe$(frcount);:CALL &BD19
750 IF map%(y%,x%)=2 THEN map%(y%,x%)=0:LOCATE 6,24:sc%=sc%+1:PRINT sc%
780 IF NOT(INKEY(8)) AND NOT(map%(y%,x%-v%)=1) AND NOT(map%(y%+v%,x%)=0) THEN frcount=2: GOSUB 40000: x%=x%-v%
800 IF NOT(INKEY(1)) AND NOT(map%(y%,x%+v%)=1) AND NOT(map%(y%+v%,x%)=0) THEN frcount=1: GOSUB 40000: x%=x%+v%
850 IF NOT(INKEY(0)) AND NOT(map%(y%-v%,x%)=1) AND map%(y%-v%,x%)=3 THEN GOSUB 40000:y%=y%-v%
860 IF NOT(INKEY(2)) AND NOT(map%(y%+v%,x%)=1) AND map%(y%+v%,x%)=3 THEN GOSUB 40000:y%=y%+v%
880 IF map%(y%+v%,x%)=0 OR map%(y%+v%,x%)=2 THEN GOSUB 40000:y%=y%+v%
900 'if sc%>=9 then cls: goto 240
990 GOTO 740
1000 DATA 0,0,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0
1100 DATA 0,1,4,4,0,0,0,0,4,1,1,1,1,1,0,0,0,1,1,0
1200 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,3,0,1
1300 DATA 1,0,0,0,0,0,4,4,0,0,0,1,1,1,1,1,1,3,0,1
1400 DATA 1,1,1,0,3,0,0,0,0,2,0,0,0,0,0,3,0,3,0,1
1500 DATA 1,0,0,1,3,0,0,0,0,1,1,1,1,1,0,3,1,1,1,1
1600 DATA 1,0,0,0,3,0,0,0,0,1,1,1,1,1,0,3,1,1,1,1
1700 DATA 1,0,0,0,3,1,2,0,0,0,0,4,4,0,0,3,0,4,4,1
1800 DATA 1,0,0,0,3,1,1,1,0,0,3,0,2,0,0,3,0,0,0,1
1900 DATA 1,2,1,1,3,1,0,0,1,0,3,1,1,1,1,1,1,1,1,0
2000 DATA 1,0,1,1,3,1,0,0,1,0,3,1,1,1,1,1,1,1,0,0
2100 DATA 1,0,0,0,3,3,1,1,1,1,3,1,1,1,0,4,4,1,1,0
2200 DATA 1,0,0,0,1,3,3,0,0,0,3,0,2,0,0,0,0,0,0,1
2300 DATA 1,0,1,1,1,1,3,0,0,1,1,1,1,1,0,0,2,0,0,1
2400 DATA 1,0,3,0,3,0,3,0,3,0,0,0,0,0,1,1,1,0,0,1
2500 DATA 1,0,3,1,3,1,1,0,3,1,1,1,1,1,1,1,1,1,0,1
2600 DATA 1,0,3,0,3,4,1,0,3,1,1,1,1,1,0,0,1,1,0,1
2700 DATA 0,1,1,0,3,0,1,0,3,1,0,4,4,0,0,0,0,0,0,1
2800 DATA 0,0,1,0,3,0,0,0,3,0,0,0,0,0,2,0,2,0,0,1
2900 DATA 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
30000 PRINT CHR$(31)+CHR$(x%)+CHR$(y%)+CHR$(15)+CHR$(8)+CHR$(246);:RETURN
30010 PRINT CHR$(31)+CHR$(x%)+CHR$(y%)+CHR$(15)+CHR$(9)+CHR$(245)+CHR$(31)+CHR$(x%)+CHR$(y%)+CHR$(15)+CHR$(4)+CHR$(248);:RETURN
30011 LOCATE 1,1: PRINT CHR$(15);CHR$(4); : LOCATE x%,y% : PRINT CHR$(248);:RETURN
30020 PRINT CHR$(31)+CHR$(x%)+CHR$(y%)+CHR$(15)+CHR$(7)+CHR$(247)+CHR$(31)+CHR$(x%)+CHR$(y%)+CHR$(15)+CHR$(4)+CHR$(249);:RETURN
30021 LOCATE 1,1 : PRINT CHR$(15);CHR$(4); : LOCATE x%,y% : PRINT CHR$(249);:RETURN
30030 PRINT CHR$(31)+CHR$(x%)+CHR$(y%)+CHR$(15)+CHR$(4)+CHR$(250);:RETURN
40000 LOCATE x%,y%:PRINT" ";:LOCATE x%,y%:PRINT obj$(map%(y%,x%));:RETURN
50000 CLEAR : CALL &BC02 : PEN 1 : MODE 2 : END
It's all based around this Multicoloured Graphics article (http://www.cpc-power.com/index.php?page=detail&onglet=notices&num=10865) which was all done with a 464.
Oh and I forgot to mention Lines 30011 & 30021 can now be deleted (the program's not using them now anyway) & it appears there's some improvement in Speed.
many thanks to all, really.
Now my tiny engine is near to be completed.
I have also implemented enemies and levels from disc (or tape)
Soon, i'll be ready to release the source code full commented, if you want :)
Why don't you wait a couple of months, and enter it in the BASIC category in CPCretrodev 2016 contest? That'll give you loads of time to make a full game with it.
Quote from: EgoTrip on 20:09, 04 August 16
Why don't you wait a couple of months, and enter it in the BASIC category in CPCretrodev 2016 contest? That'll give you loads of time to make a full game with it.
Ah why not! Thank's you!
I'm new here and did not know about this contest
Soon, you will see the new graphics.
Quote from: EgoTrip on 20:09, 04 August 16
Why don't you wait a couple of months, and enter it in the BASIC category in CPCretrodev 2016 contest?
Does the BASIC category allow any machine code at all? You could do a simple routine to draw the multicolour tiles in about 20 bytes and it would be much much faster.
Quote from: Executioner on 23:07, 04 August 16Does the BASIC category allow any machine code at all? You could do a simple routine to draw the multicolour tiles in about 20 bytes and it would be much much faster.
No, the BASIC submissions must be one file (no multi-loading) and all interpreted BASIC 1.0 (no machine code pokes). My game CoolBox was going to be an entry but I couldn't get my code to work on Basic 1.0, the control code bug got me.
Quote from: Fabrizio Radica on 20:20, 04 August 16
Ah why not! Thank's you!
I'm new here and did not know about this contest
Soon, you will see the new graphics.
Entering the competition is a great idea, but if you decide to enter, you may need to stop uploading code.
If you enter a game that is too similar to things you've already shown us, the game may get disqualified.
(The rules state that game cannot have been released before).
Quote from: Morri on 23:38, 04 August 16
No, the BASIC submissions must be one file (no multi-loading) and all interpreted BASIC 1.0 (no machine code pokes).
By the looks of the graphics, you could simple POKE the overlay pixels into screen memory (that's not machine code). POKE &C000+X%*2+y%*80,255 for example should be much quicker than using transparent character overlay.
Quote from: Executioner on 02:36, 05 August 16
By the looks of the graphics, you could simple POKE the overlay pixels into screen memory (that's not machine code). POKE &C000+X%*2+y%*80,255 for example should be much quicker than using transparent character overlay.
I'm interested in having a look at this, though I recall @ervin (http://www.cpcwiki.eu/forum/index.php?action=profile;u=82) posting this program in this thread (http://www.cpcwiki.eu/forum/programming/moving-graphical-images-down-the-screen/msg67045/#msg67045) which was replacing the PRINT with POKE, but was saying the POKE was slower in that situation until the program was compiled, though the POKE is arranged a little bit differently within a FOR loop, so your suggested approach may have advantages, and then with that POKE you can use the Encoded pen. I made a crude BASIC Sprite Driver which did that (in the Silly Thread).
FURTHER EDIT: Okay, I had a look at that formula, so it works based on Character Position, 0 being the first for Row/Column, but I think the xpos might need to say x%*4 rather than x%*2 for MODE 0, so when x%=19 &4C is the result and 4 bytes will take that to &4F. So for y% that can be range 0 to 19 and a loop that increments itself by &800 will fill in the rest from that position.
Quote from: Morri on 23:38, 04 August 16
No, the BASIC submissions must be one file (no multi-loading) and all interpreted BASIC 1.0 (no machine code pokes). My game CoolBox was going to be an entry but I couldn't get my code to work on Basic 1.0, the control code bug got me.
Was somewhat tempted to do a program as a BASIC stub file, but the judges would only have to take a look at the source code to find M/C embedded in there with it.
The following code is in assembler but you may be able to use a similar idea in basic:
http://cpctech.cpc-live.com/source/charspr.asm (http://cpctech.cpc-live.com/source/charspr.asm)
The code sets the mode to 2. Then using the firmware you pretend it's in the mode of your choice (1 or 0).
At this point the character matrices will be plotted direct to the screen as bytes (char matrices copyed directly byte by byte to the screen in mode 2, in other modes they are translated).
So for mode 0, each char matrix is now 2x8. Mode 1 is 4x8 etc.
Redefine your char matrices as if they are encoded pixel data that can be poked to the screen and put them side by side and use print to display them.
Now plot them in the normal way and instant sprites!
in basic you may be able to do this for mode 0:
mode 2: call &bd1c
and this for mode 1:
mode 2: call &bd1c,1
If it works, full colour sprites! :)
But of course you need to redefine the charset too so you can't just do print"Hello" or print score% :(
You would probably need to use CHR$ to print OR ctrl+letter in the string.
Quote from: Fabrizio Radica on 15:49, 04 August 16
many thanks to all, really.
Now my tiny engine is near to be completed.
I have also implemented enemies and levels from disc (or tape)
Soon, i'll be ready to release the source code full commented, if you want :)
Hmm, guessing you noticed, your little red character wiped out some of those background blocks when they went through them.
Quote from: AMSDOS on 10:23, 05 August 16
Hmm, guessing you noticed, your little red character wiped out some of those background blocks when they went through them.
Yes little bug i've fixed last night. :)
I've also rewritten that part and now is more fast and light.
Quote from: arnoldemu on 09:17, 05 August 16The following code is in assembler but you may be able to use a similar idea in basic: http://cpctech.cpc-live.com/source/charspr.asm (http://cpctech.cpc-live.com/source/charspr.asm) The code sets the mode to 2. Then using the firmware you pretend it's in the mode of your choice (1 or 0). At this point the character matrices will be plotted direct to the screen as bytes (char matrices copyed directly byte by byte to the screen in mode 2, in other modes they are translated). So for mode 0, each char matrix is now 2x8. Mode 1 is 4x8 etc. Redefine your char matrices as if they are encoded pixel data that can be poked to the screen and put them side by side and use print to display them. Now plot them in the normal way and instant sprites! in basic you may be able to do this for mode 0: mode 2: call &bd1c and this for mode 1: mode 2: call &bd1c,1 If it works, full colour sprites! :) But of course you need to redefine the charset too so you can't just do print"Hello" or print score% :( You would probably need to use CHR$ to print OR ctrl+letter in the string.
I have seen the possibilities of this technique in a previous thread (http://www.cpcwiki.eu/forum/programming/basic-programming-tips/msg117556/#msg117556), it really is impressive and very fast compact code for BASIC.
Quote from: Executioner on 02:36, 05 August 16
By the looks of the graphics, you could simple POKE the overlay pixels into screen memory (that's not machine code). POKE &C000+X%*2+y%*80,255 for example should be much quicker than using transparent character overlay.
Hi :)
Can you explain me better? i'm interested (and curious)
&c000 is the video address?
so i can draw much quicker the player? how?
I've to study the memory addresses. :(
Quote from: Morri on 15:51, 05 August 16
I have seen the possibilities of this technique in a previous thread (http://www.cpcwiki.eu/forum/programming/basic-programming-tips/msg117556/#msg117556), it really is impressive and very fast compact code for BASIC.
I missed that post.
Example for "sprites":
5 symbol after 240
6 symbol 241,&aa,&f3,&cc,&33,&aa,&55,&cc,&33
7 symbol 242,&34,&66,&33,&66,&33,&66,&33,&66
10 mode 2:call &bd1c
20 locate 2,1:print chr$(241);chr$(242);
Use mode 2 text coordinates to move.
EDIT: The values for symbol are the bytes you need to POKE to memory to draw the same pixels.
So you could create some sprites on the screen using PLOT, then peek the memory address to fetch them for symbol.
Quote from: Fabrizio Radica on 18:42, 05 August 16
Hi :)
Can you explain me better? i'm interested (and curious)
&c000 is the video address?
so i can draw much quicker the player? how?
I've to study the memory addresses. :(
Example:
1 mode 0
5 addr=(x*2)+(y*80)+&c000
6 restore 60
7 for i=0 to 7:read d:poke addr+(i*&800),d:next
8 restore 70
9 addr=(x*2)+1+(y*80)+&c000
10 for i=0 to 7:read d:poke addr+(i*&800),d:next
60 data &aa,&f3,&cc,&33,&aa,&55,&cc,&33
70 data &34,&66,&33,&66,&33,&66,&33,&66
The data has the bytes to poke. The data is organised as a column, 2 pixels wide and 8 pixels tall.
Restore is used to choose which data to use.
There are two for loops which are almost the same. These draw line by line.
The address is calculated based on mode 2 char coordinates.
The code becomes a little more complex if you want to move more smoothly.
Screen coordinates:
You need to use mode to reset the screen location because it will change if it is scrolled by basic.
Use "mode" to do that.
&c000 is top-left. &c001 is one byte to right. &c002 is 2 bytes to right up to &c000+79 which is the byte on the right on the top line.
Next scanline down is +&800. &c800 is under &c000.
Pattern repeats for 8 scanlines:
&c000
&c800
&d000
&d800
&e000
&e800
&f000
&f800
This is the first column.
The next line is then &c000+80.
&f800
&c000+&80
&c000+&80+&800
&c000+&80+&1000 etc
Try with poke values and you will see.
Quote from: arnoldemu on 18:58, 05 August 16
Screen coordinates:
You need to use mode to reset the screen location because it will change if it is scrolled by basic.
Use "mode" to do that.
&c000 is top-left. &c001 is one byte to right. &c002 is 2 bytes to right up to &c000+79 which is the byte on the right on the top line.
Next scanline down is +&800. &c800 is under &c000.
Pattern repeats for 8 scanlines:
&c000
&c800
&d000
&d800
&e000
&e800
&f000
&f800
This is the first column.
The next line is then &c000+80.
&f800
&c000+&80
&c000+&80+&800
&c000+&80+&1000 etc
Try with poke values and you will see.
ok, i've understand.
it's similar to c64.
i've added this line and is really simple get a value from the memory.. for collisions... for example
15 print hex$(peek(&c000+&800+1))
thank's :)
I've mapped out the whole screen here (http://www.cpcwiki.eu/forum/programming/16k-cpc-screen-map/) if you were wondering.
@arnoldemu (http://www.cpcwiki.eu/forum/index.php?action=profile;u=122) made a little blue, the 1st bit is correct - adding 80, but has then added &80, which is 128 bytes, instead of adding &50 which is 80!
This is what I knocked up, but I'm unsure if this is the approach @Executioner (http://www.cpcwiki.eu/forum/index.php?action=profile;u=17) had in mind when suggesting to POKE to screen, rather than using Transparent Mode.
So in this situation I've taken your platform, converted it to bytes, line 2000..2060 pokes it to memory, and then use the main nested loop 140..190 to draw that all over the screen, 1000..1090 draws the image.
100 ' Setup Image & Display across screen
110 MODE 0:INK 0,0
120 GOSUB 2010
130 addr%=&8000
140 FOR y%=0 TO 24
150 FOR x%=0 TO 19
160 GOSUB 1020
170 addr%=&8000
180 NEXT x%
190 NEXT y%
200 CALL &BB18:CALL &BC02:MODE 2:END
1000 ' Poke Sprite to Screen
1010 ' On Entry - x% = XPOS (0..19), y% = YPOS (0..24), addr% = sprite location
1020 scradr%=&C000+(x%*4)+(y%*80)
1030 FOR v%=0 TO 7
1040 FOR h%=0 TO 3
1050 IF PEEK(addr%)<>0 THEN POKE scradr%+h%+(v%*&800),PEEK(addr%)
1060 addr%=addr%+1
1070 NEXT h%
1080 NEXT v%
1090 RETURN
2000 ' Poke Image to Memory
2010 RESTORE 2070
2020 FOR addr%=&8000 TO &801F
2030 READ a$
2040 POKE addr%,VAL("&"+a$)
2050 NEXT addr%
2060 RETURN
2070 DATA 30,c3,c3,82
2080 DATA c3,c3,c3,82
2090 DATA c3,c3,c3,82
2100 DATA c3,c3,c3,82
2110 DATA c3,c3,c3,82
2120 DATA c3,c3,c3,00
2130 DATA 00,00,00,00
2140 DATA 00,00,00,00
I mention @Executioner (http://www.cpcwiki.eu/forum/index.php?action=profile;u=17) because in interpreted BASIC it takes a while (a few minutes) to draw up, and I think this is what @ervin (http://www.cpcwiki.eu/forum/index.php?action=profile;u=82) was trying to tell me earlier. Though I think the situation changes when something like this has been compiled.
This was the outcome for interpreted BASIC:
[attachimg=1]
If your wondering how I got that DATA for your platform block from the SYMBOL data I did this:
mode 0:print chr$(22);chr$(1);:locate 1,1:pen 9:print chr$(245);:pen 4:locate 1,1:print chr$(248);:print chr$(22);chr$(0);:locate 1,10
To print the Object Top Left Corner of the screen.
I can just get the data with this:
1000 scradr%=&C000 : for loop=1 to 8 : gosub 1020 : print : scradr%=scradr%+&800 : NEXT loop
1010 end
1020 for addr=scradr to scradr+3 : print hex$(peek(addr));" ";:next addr : return
Well, the idea wasn't to POKE the whole tile into screen memory, but to print the character as normal and POKE a single byte for the two white pixels in the top corner. You gain the advantage of using a firmware print to display the tile without using transparency (which is slow). For example, a single tile in the tope corner could be something like
LOCATE x,y:PRINT CHR$(254);:POKE &C000+x*4+y*80,255
This wouldn't work particularly well if you had lots of different colour pixels in the character tile, but for just one in the corner it's fine. You could also define an array containing one (or maybe more) offsets and values to poke. So for example:
20 DATA &C000,&D801,&C800,&F800:'Address offsets
30 DATA &FF,&55,&AA,&22:'Values
Read these into variables (eg. A% and V%), then
LOCATE x,y:PRINT CHR$(tile + 252):POKE A%(tile),V%(tile)
Quote from: Executioner on 09:12, 06 August 16
Well, the idea wasn't to POKE the whole tile into screen memory, but to print the character as normal and POKE a single byte for the two white pixels in the top corner. You gain the advantage of using a firmware print to display the tile without using transparency (which is slow). For example, a single tile in the tope corner could be something like
LOCATE x,y:PRINT CHR$(254);:POKE &C000+x*4+y*80,255
This wouldn't work particularly well if you had lots of different colour pixels in the character tile, but for just one in the corner it's fine. You could also define an array containing one (or maybe more) offsets and values to poke. So for example:
20 DATA &C000,&D801,&C800,&F800:'Address offsets
30 DATA &FF,&55,&AA,&22:'Values
Read these into variables (eg. A% and V%), then
LOCATE x,y:PRINT CHR$(tile + 252):POKE A%(tile),V%(tile)
Sorry I got confused when you started asking about having a small Sprite Driver in a BASIC game for the Compo. After @Morri (http://www.cpcwiki.eu/forum/index.php?action=profile;u=95) explained M/C wasn't allowed, you posted that POKE with formula, which I thought was interesting, but got caught up in the formula and didn't realise you were suggesting merely Poking the corner of the Wall Sprite. :(
But I appreciate the explanation and agree that would be a better approach instead of using Transparent Mode to Display one small bit of the Wall Tile.
The program I posted yesterday was out of my own curiosity, I didn't mean to imply this was what you were suggesting, though I remember @ervin (http://www.cpcwiki.eu/forum/index.php?action=profile;u=82) saying that Poking was quite slow when using BASIC, though whatever was written got translated with CPC BASIC 3, with interesting results. So I ended up writing that program to have a look.
I'll post an attachment of the program in due course.
Fabrizio - In my opinion to appear whole screen fast (in about 3 sec), you can use just few PRINT, instead hundreds PRINT, CHR$, READ... etc. in FOR-NEXT loop.
Just use for tiles narrow fonts 4x8 pixels in 4 colors, which I explained here:
BASIC programming tips (http://www.cpcwiki.eu/forum/programming/basic-programming-tips/msg117556/#msg117556)
And to check tiles on map use TEST color of pixel, instead DIM and DATA. Thats should be much shorter and faster program. Narrow font show at once 4 colors of tiles or sprites. Example of small sprite I did here:
BASIC programming tips (http://www.cpcwiki.eu/forum/programming/basic-programming-tips/msg117543/#msg117543)
And this method let make quite fluent animation without assembler:
BASIC programming tips (http://www.cpcwiki.eu/forum/programming/basic-programming-tips/msg123597/#msg123597)
A bit late with my post given @ZbyniuR (http://www.cpcwiki.eu/forum/index.php?action=profile;u=840) probably has the best advice on Control Codes! :D
The program I posted earlier has to be modified a little bit to work in CPC BASIC 3, so now it looks like this:
100 ' Setup Image & Display across screen
110 MODE 0:INK 0,0
130 addr=&8000
140 FOR y=0 TO 24
150 FOR x=0 TO 19
160 GOSUB 1020
170 addr=&8000
180 NEXT x
190 NEXT y
200 CALL &BB18:CALL &BC02:MODE 2:END
1000 ' Poke Sprite to Screen
1010 ' On Entry - x = XPOS (0..19), y = YPOS (0..24), addr = sprite location
1020 scradr=&C000+(x*4)+(y*80)
1030 FOR v=0 TO 7
1040 FOR h=0 TO 3
1050 IF PEEK(addr)<>0 THEN POKE scradr+h+(v*&800),PEEK(addr)
1060 addr=addr+1
1070 NEXT h
1080 NEXT v
1090 RETURN
The data from Line 2000 gets saved into a file "wall.spr" which is on my attach disk image, so then that routine is removed line 120 also goes. CPC BASIC 3 handles variables a little bit differently from Locomotive BASIC, so the "%" is removed. That program can then be compiled in CPC BASIC 3. Which I've attached.
Performance wise, the program draws around the same pace as the BASIC version, but it's drawing 20x25, so it might be a touch faster. The only advantage in this is all the Sprite Drawing is kept within the program, so no 3rd party software, the approach @arnoldemu (http://www.cpcwiki.eu/forum/index.php?action=profile;u=122) discussed earlier would also keep the sprite drawing within the program, I reckon would be faster, my early version of Get the Cash used a similar approach, though I was surprised what the final result was after compiling it with CPC BASIC 3, which seemed a bit slow. 3rd party sprite drivers seem to change that, but present the problem of submitting to the Games Compo.
Quote from: AMSDOS on 04:38, 07 August 16
A bit late with my post given @ZbyniuR (http://www.cpcwiki.eu/forum/index.php?action=profile;u=840) probably has the best advice on Control Codes! :D
The program I posted earlier has to be modified a little bit to work in CPC BASIC 3, so now it looks like this:
100 ' Setup Image & Display across screen
110 MODE 0:INK 0,0
130 addr=&8000
140 FOR y=0 TO 24
150 FOR x=0 TO 19
160 GOSUB 1020
170 addr=&8000
180 NEXT x
190 NEXT y
200 CALL &BB18:CALL &BC02:MODE 2:END
1000 ' Poke Sprite to Screen
1010 ' On Entry - x = XPOS (0..19), y = YPOS (0..24), addr = sprite location
1020 scradr=&C000+(x*4)+(y*80)
1030 FOR v=0 TO 7
1040 FOR h=0 TO 3
1050 IF PEEK(addr)<>0 THEN POKE scradr+h+(v*&800),PEEK(addr)
1060 addr=addr+1
1070 NEXT h
1080 NEXT v
1090 RETURN
The data from Line 2000 gets saved into a file "wall.spr" which is on my attach disk image, so then that routine is removed line 120 also goes. CPC BASIC 3 handles variables a little bit differently from Locomotive BASIC, so the "%" is removed. That program can then be compiled in CPC BASIC 3. Which I've attached.
Performance wise, the program draws around the same pace as the BASIC version, but it's drawing 20x25, so it might be a touch faster. The only advantage in this is all the Sprite Drawing is kept within the program, so no 3rd party software, the approach @arnoldemu (http://www.cpcwiki.eu/forum/index.php?action=profile;u=122) discussed earlier would also keep the sprite drawing within the program, I reckon would be faster, my early version of Get the Cash used a similar approach, though I was surprised what the final result was after compiling it with CPC BASIC 3, which seemed a bit slow. 3rd party sprite drivers seem to change that, but present the problem of submitting to the Games Compo.
wow!
Now I have to learn and understand what you're writing.
aargh!! i would like to code it with CPC Basic 3 but doesn't work in OSX El Capitan and Wine :(
Quote from: AMSDOS on 05:07, 06 August 16
This is what I knocked up, but I'm unsure if this is the approach @Executioner (http://www.cpcwiki.eu/forum/index.php?action=profile;u=17) had in mind when suggesting to POKE to screen, rather than using Transparent Mode.
So in this situation I've taken your platform, converted it to bytes, line 2000..2060 pokes it to memory, and then use the main nested loop 140..190 to draw that all over the screen, 1000..1090 draws the image.
100 ' Setup Image & Display across screen
110 MODE 0:INK 0,0
120 GOSUB 2010
130 addr%=&8000
140 FOR y%=0 TO 24
150 FOR x%=0 TO 19
160 GOSUB 1020
170 addr%=&8000
180 NEXT x%
190 NEXT y%
200 CALL &BB18:CALL &BC02:MODE 2:END
1000 ' Poke Sprite to Screen
1010 ' On Entry - x% = XPOS (0..19), y% = YPOS (0..24), addr% = sprite location
1020 scradr%=&C000+(x%*4)+(y%*80)
1030 FOR v%=0 TO 7
1040 FOR h%=0 TO 3
1050 IF PEEK(addr%)<>0 THEN POKE scradr%+h%+(v%*&800),PEEK(addr%)
1060 addr%=addr%+1
1070 NEXT h%
1080 NEXT v%
1090 RETURN
2000 ' Poke Image to Memory
2010 RESTORE 2070
2020 FOR addr%=&8000 TO &801F
2030 READ a$
2040 POKE addr%,VAL("&"+a$)
2050 NEXT addr%
2060 RETURN
2070 DATA 30,c3,c3,82
2080 DATA c3,c3,c3,82
2090 DATA c3,c3,c3,82
2100 DATA c3,c3,c3,82
2110 DATA c3,c3,c3,82
2120 DATA c3,c3,c3,00
2130 DATA 00,00,00,00
2140 DATA 00,00,00,00
I mention @Executioner (http://www.cpcwiki.eu/forum/index.php?action=profile;u=17) because in interpreted BASIC it takes a while (a few minutes) to draw up, and I think this is what @ervin (http://www.cpcwiki.eu/forum/index.php?action=profile;u=82) was trying to tell me earlier. Though I think the situation changes when something like this has been compiled.
This was the outcome for interpreted BASIC:
[attachimg=1]
If your wondering how I got that DATA for your platform block from the SYMBOL data I did this:
mode 0:print chr$(22);chr$(1);:locate 1,1:pen 9:print chr$(245);:pen 4:locate 1,1:print chr$(248);:print chr$(22);chr$(0);:locate 1,10
To print the Object Top Left Corner of the screen.
I can just get the data with this:
1000 scradr%=&C000 : for loop=1 to 8 : gosub 1020 : print : scradr%=scradr%+&800 : NEXT loop
1010 end
1020 for addr=scradr to scradr+3 : print hex$(peek(addr));" ";:next addr : return
I don't understund how to draw my tiles in your data.
I see (correct me if i wrong) 4 colums and 8 row (sprite 4x8) and is ok
But, how is it subdivided?
When i draw my SYMBOL CHR, i only put one pixel color per chr$
like this:
160 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
168 SYMBOL 248,&X11000000,&X0,&X0,&X0,&X0,&X0,&X0,&X0 'wall color
Thank'you :)
I doubt this method is worth while on the CPC, but here goes.
When I code, lets say a platformer on a PC, I READ the DATA as normal and then store the X and Y of anything solid into another array. This often means that certain screens/levels have smaller content inside this other array. (can read it faster)
I then then do a FOR/NEXT match from that array against the players X&Y position.
Quote from: rk last on 21:45, 07 August 16
I doubt this method is worth while on the CPC, but here goes.
When I code, lets say a platformer on a PC, I READ the DATA as normal and then store the X and Y of anything solid into another array. This often means that certain screens/levels have smaller content inside this other array. (can read it faster)
I then then do a FOR/NEXT match from that array against the players X&Y position.
A while ago (May last year), I was writing up some simple demonstration for a platform game (http://www.cpcwiki.eu/forum/programming/basic-platform-demostration/) and had @ronaldo (http://www.cpcwiki.eu/forum/index.php?action=profile;u=1227) help with the Jumping process. The data from those examples gets stored into an Array, so when my character falls onto it, it doesn't fall any further, I think pretty much any platform game has to operate like that, some platform games would definitely have a larger array (for the whole level), so as you move through it, each sector of that larger array is stored to the smaller array (which is the playing field), but the examples I have in that thread only deals in a single screen array.
Quote from: Fabrizio Radica on 13:44, 07 August 16
wow!
Now I have to learn and understand what you're writing.
aargh!! i would like to code it with CPC Basic 3 but doesn't work in OSX El Capitan and Wine
Unfortunately that's one of the limitations with CPC BASIC 3 (requires Windows). Some other CPC Based BASIC Compilers were mentioned earlier, Fabacom might be able to do what you need, which all runs on the CPC!
Quote from: Fabrizio Radica on 15:45, 07 August 16
I don't understund how to draw my tiles in your data.
I see (correct me if i wrong) 4 colums and 8 row (sprite 4x8) and is ok
But, how is it subdivided?
I'll try and explain, though it's somewhat complicated.
Each byte can hold a certain amount of pixel data, this varies depending on the screen mode you're in, in MODE 0 in your case it can hold a left most pixel and a right most pixel, if we were using MODE 1, that number would be 4 pixels for each byte - so an 8x8 image would only take 2 bytes. In MODE 2 a single byte will hold 8 pixels! So just getting back to my example in MODE 0, because a Byte can hold 2 Pixels, a whole column (of 8 pixels), only needs 4 Bytes. But for rows it never changes. So for MODE 0,1 or 2, 8 Bytes is always required if the Tile is 8 pixels in height. So naturally this will change if the Tile was bigger.
Quote
When i draw my SYMBOL CHR, i only put one pixel color per chr$
like this:
160 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
168 SYMBOL 248,&X11000000,&X0,&X0,&X0,&X0,&X0,&X0,&X0 'wall color
Thank'you
In your examples you're using Symbol to redefine the character set, which is always 8x8, it's possible to use multiple SYMBOL definitions to make up a larger image, or in this example above it's using Transparent Mode - PRINT CHR$(22)+CHR(1) to PRINT CHR$(245) and then PRINT CHR$(248) to PRINT another Colour on top of the main graphic, this is due to these SYMBOL definitions only allowing 2 Colours, but one of those Colours is the background, so you only have 1 colour for your character.
Earlier @Executioner (http://www.cpcwiki.eu/forum/index.php?action=profile;u=17) was suggesting replacing PRINT CHR$(248) with the POKE would be faster than using the Transparent Mode approach. For the purpose of enhancing your game in Interpreted BASIC, it's worth checking that out. What I published is merely a curiosity, gone to the point of poking a sprite to the screen. As you would notice the Locomotive BASIC version is terribly slow, the screenshot shows that. After compiling it with CPC BASIC 3, I think it's about the same speed as your game, so I think removing the Transparent Mode from it and using the POKE Executioner posted should make your program run faster than my Compiled.
It might be easier to do a screenshot of drawing the image to screen and getting the Byte information of it:
[attachimg=1]
I Used a small little program I posted earlier to get the Information, it simply works by having the Image at the top left of the screen (1,1), but works out the Bytes across and down, to let me come up with my data, the program I posted earlier looks like this:
1000 scradr=&C000:FOR loop=1 TO 8:GOSUB 1020:PRINT:scradr=scradr+&800:NEXT loop
1010 END
1020 FOR addr=scradr TO scradr+3:PRINT HEX$(PEEK(addr));" ";:NEXT addr:RETURN
So this is what I came up with, based on @Executioner (http://www.cpcwiki.eu/forum/index.php?action=profile;u=17) suggestion. In this example I've removed the Transparent Mode along with the Background SYMBOLs being defined - CHR$(248) & CHR$(249), which are no longer needed. I've taken the 464 version of the game and have modified Lines 30011 & 30021 so they are now using POKEs to Poke the White Pixel, into the Wall Block and Bonus. The Bonus one was a bit harder given it wasn't on the top of the line, so cheated and calculated it based on the Row it was on - which gets me to &D000. x% is multiplied by 4, which takes it past the spot in question, so subtracted 2 to get the right spot. Also both the formula's have been altered slightly based on Executioner's formula, mainly because their 0 based, so 1 is subtracted to get the right Row.
1 'A (simple) GAME Routine BY FABRIZIO RADICA - 2016 Retroacademy.it
10 DEFINT A-Z:MODE 0:transpOn$=CHR$(22)+CHR$(1):transpOff$=CHR$(22)+CHR$(0)
11 ON BREAK GOSUB 50000
20 BORDER 0:INK 0,0:maxx%=20:maxy%=20:lev%=0:isDown%=0:SYMBOL AFTER 240
160 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
165 SYMBOL 246,&X1111110,&X10000000,&X10000000,&X10000000,&X10000000,&X10000000,&X0,&X0 'background
166 SYMBOL 247,&X111100,&X1111110,&X11111011,&X11111111,&X11111111,&X11111111,&X1111110,&X111100 'bonus
170 SYMBOL 240,&X111100,&X1111110,&X11101011,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player right
171 SYMBOL 250,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111 'ladders
172 SYMBOL 251,&X111100,&X1111110,&X11010111,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player left
180 wa1$=CHR$(245):bg$=CHR$(246):bo1$=CHR$(247):wa2$=CHR$(248):bo2$=CHR$(249):plyr$=CHR$(240):plyl$=CHR$(251):lad$=CHR$(250)
200 DIM map%(maxy%,maxx%)
240 CLS:LOCATE 1,24:INK 1,3:PRINT "Loading"
250 ' FOR i%=2 TO 15:INK i%,0:NEXT i%
292 lev%=lev%+1
295 IF (lev%>3) THEN CLS: PRINT "YOU WIN!!" : END
310 fpen$=CHR$(15):green$=fpen$+CHR$(12):white$=fpen$+CHR$(4):bgcolor$=fpen$+CHR$(8):bgr$=bgcolor$+bg$
340 wall$=fpen$+CHR$(9)+wa1$+curLeft$+white$+wa2$:bonus$=fpen$+CHR$(7)+bo1$+curLeft$+white$+bo2$:playerr$=fpen$+CHR$(3)+plyr$:playerl$=fpen$+CHR$(3)+plyl$:ladders$=white$+lad$
345 DIM obj$(10),playerFrame$(10)
350 obj$(1)=wall$:obj$(2)=bonus$:obj$(3)=ladders$
354 frcount=1
355 pframe$(1)=CHR$(240)
356 pframe$(2)=CHR$(251)
400 FOR y%=1 TO maxy%
410 FOR x%=1 TO maxx%
420 READ a%:map%(y%,x%)=a%:LOCATE x%,y%
430 ON map%(y%,x%) GOSUB 30010,30020,30030,30000
440 NEXT x%:NEXT y%
660 CALL &BC02:BORDER 0:INK 0,0:INK 1,26:x%=2:y%=4:v%=1:sc%=0:p%=0
700 LOCATE 1,24:PRINT "Score 0 - Lev ";lev%
720 'memory &7fff:load"music.bin",&8000:call &8000
740 LOCATE 1,1 : PRINT CHR$(15);CHR$(3); : LOCATE x%,y% : PRINT pframe$(frcount):CALL &BD19
750 IF map%(y%,x%)=2 THEN map%(y%,x%)=0:LOCATE 6,24:sc%=sc%+1:PRINT sc%
780 IF NOT(INKEY(8)) AND NOT(map%(y%,x%-v%)=1) AND NOT(map%(y%+v%,x%)=0) THEN frcount=2: GOSUB 40000: x%=x%-v%
800 IF NOT(INKEY(1)) AND NOT(map%(y%,x%+v%)=1) AND NOT(map%(y%+v%,x%)=0) THEN frcount=1: GOSUB 40000: x%=x%+v%
850 IF NOT(INKEY(0)) AND NOT(map%(y%-v%,x%)=1) AND map%(y%-v%,x%)=3 THEN GOSUB 40000:y%=y%-v%
860 IF NOT(INKEY(2)) AND NOT(map%(y%+v%,x%)=1) AND map%(y%+v%,x%)=3 THEN GOSUB 40000:y%=y%+v%
880 IF map%(y%+v%,x%)=0 OR map%(y%+v%,x%)=2 THEN GOSUB 40000:y%=y%+v%
900 'if sc%>=9 then cls: goto 240
990 GOTO 740
1000 DATA 0,0,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0
1100 DATA 0,1,4,4,0,0,0,0,4,1,1,1,1,1,0,0,0,1,1,0
1200 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,3,0,1
1300 DATA 1,0,0,0,0,0,4,4,0,0,0,1,1,1,1,1,1,3,0,1
1400 DATA 1,1,1,0,3,0,0,0,0,2,0,0,0,0,0,3,0,3,0,1
1500 DATA 1,0,0,1,3,0,0,0,0,1,1,1,1,1,0,3,1,1,1,1
1600 DATA 1,0,0,0,3,0,0,0,0,1,1,1,1,1,0,3,1,1,1,1
1700 DATA 1,0,0,0,3,1,2,0,0,0,0,4,4,0,0,3,0,4,4,1
1800 DATA 1,0,0,0,3,1,1,1,0,0,3,0,2,0,0,3,0,0,0,1
1900 DATA 1,2,1,1,3,1,0,0,1,0,3,1,1,1,1,1,1,1,1,0
2000 DATA 1,0,1,1,3,1,0,0,1,0,3,1,1,1,1,1,1,1,0,0
2100 DATA 1,0,0,0,3,3,1,1,1,1,3,1,1,1,0,4,4,1,1,0
2200 DATA 1,0,0,0,1,3,3,0,0,0,3,0,2,0,0,0,0,0,0,1
2300 DATA 1,0,1,1,1,1,3,0,0,1,1,1,1,1,0,0,2,0,0,1
2400 DATA 1,0,3,0,3,0,3,0,3,0,0,0,0,0,1,1,1,0,0,1
2500 DATA 1,0,3,1,3,1,1,0,3,1,1,1,1,1,1,1,1,1,0,1
2600 DATA 1,0,3,0,3,4,1,0,3,1,1,1,1,1,0,0,1,1,0,1
2700 DATA 0,1,1,0,3,0,1,0,3,1,0,4,4,0,0,0,0,0,0,1
2800 DATA 0,0,1,0,3,0,0,0,3,0,0,0,0,0,2,0,2,0,0,1
2900 DATA 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
30000 LOCATE 1,1 : PRINT CHR$(15);CHR$(8); : LOCATE x%,y% : PRINT CHR$(246);:RETURN
30010 LOCATE 1,1:PRINT CHR$(15);CHR$(9); : LOCATE x%,y% : PRINT CHR$(245);
30011 POKE &C000+(x%-1)*4+(y%-1)*80,&30:RETURN
30020 LOCATE 1,1 : PRINT CHR$(15);CHR$(7); : LOCATE x%,y% : PRINT CHR$(247);
30021 POKE &D000+x%*4-2+(y%-1)*80,&B8:RETURN
30030 LOCATE 1,1 : PRINT CHR$(15);CHR$(4); : LOCATE x%,y% : PRINT CHR$(250);:RETURN
40000 LOCATE x%,y%:PRINT" ";:LOCATE x%,y%:PRINT obj$(map%(y%,x%));:RETURN
50000 CLEAR : CALL &BC02 : PEN 1 : MODE 2 : END
Just dropping by to say welcome, @Fabrizio Radica (http://www.cpcwiki.eu/forum/index.php?action=profile;u=1837) - great to see new guys trying stuff! I really like this thread :)
Quote from: AMSDOS on 04:33, 08 August 16
Also both the formula's have been altered slightly based on Executioner's formula, mainly because their 0 based, so 1 is subtracted to get the right Row.
How about subtracting 80 and 1 from &C000 or &D000 then you don't make BASIC have to do it. ie.
&C000 becomes &BFAF and &D000 (+2) becomes &CFB1.
I don't think you need the LOCATE 1,1 and extra LOCATE x%,y% either, eg. You can just do
PRINT CHR$(15);CHR$(8);CHR$(246);
Quote from: Executioner on 14:14, 09 August 16
How about subtracting 80 and 1 from &C000 or &D000 then you don't make BASIC have to do it. ie.
&C000 becomes &BFAF and &D000 (+2) becomes &CFB1.
I know what you mean, unfortunately I've tried this and it just wouldn't work. But feel free to make adjustments.
Quote
I don't think you need the LOCATE 1,1 and extra LOCATE x%,y% either, eg. You can just do
PRINT CHR$(15);CHR$( 8) ;CHR$(246);
Call it a precaution, I wasn't sure if it would work on a 464, though the program I posted earlier with the LOCATE Control Code demonstrates the PEN Control Code doesn't interfere, it all seems to be occurring when people are using BackSpace Control code that problems emerge on the 464.
I've updated the lines in question, and tested:
30000 PRINT CHR$(15);CHR$(8);CHR$(246);:RETURN
30010 PRINT CHR$(15);CHR$(9);CHR$(245);
30011 POKE &BFAC+x%*4+y%*80,&30:RETURN
30020 PRINT CHR$(15);CHR$(7);CHR$(247);
30021 POKE &CFAE+x%*4+y%*80,&B8:RETURN
30030 PRINT CHR$(15);CHR$(4);CHR$(250);:RETURN
hi, i'm back from holiday
now i see your posts and comment them soon :laugh:
Well I better start sweeping out the rubbish! ;D
hi folks :D
i'm back :(
Soon, i'll post a new update of my engine with some optimizations and feature.
Now, i have a little problem.
I would like to save and load an charsheet.bin (one or more chr$ SYMBOL).
For example, I've this data and i would like to save it in binary and reload like a SYMBOL
2070 data BC,3C,3C,3C
2080 data 54,FC,3C,0
2090 data 8,54,A8,C
2100 data E0,8,4,D0
2110 data 48,D0,D0,84
2120 data 4,C,C,8
2130 data 4,4,4,0
2140 data 0,4,0,0
I've seen Vampire Killer and he used:
4 CLEAR:SYMBOL AFTER 124:LOAD"VAMPIRE3.bin":POKE &A24E+4,&FB:POKE &A24E+5,&A6
5 CALL &A24E
...
240 ml$=" ê ëìà ï ö ":mr$=" ø ûúü ý ÿ "
when i PRINT ml$ (or mr$), i see new sprites..
can you help me?
tnx again :)
I'd have to see the program working from the Disk Image to make head or tail of it, the code doesn't make much sense to me.
The data you posted with 2070..2140 is Sprite Data, earlier I was using a POKE to Display that info, which wasn't very good in Interpreted BASIC. It operates differently from SYMBOL Data which only allows 2 Colours (or 1 to represent the "On" bit of your character). To get it displayed in the SYMBOL equivalent would require a number of definitions to build up the character.
Quote from: Fabrizio Radica on 16:33, 21 August 16
hi folks :D
i'm back :(
Now, i have a little problem.
I would like to save and load an charsheet.bin (one or more chr$ SYMBOL).
Take a look here: Modify the font appearance (http://www.cpcwiki.eu/forum/programming/modify-the-font-appearance/) for some hints.
Quote from: AMSDOS on 11:52, 22 August 16
I'd have to see the program working from the Disk Image to make head or tail of it, the code doesn't make much sense to me.
The data you posted with 2070..2140 is Sprite Data, earlier I was using a POKE to Display that info, which wasn't very good in Interpreted BASIC. It operates differently from SYMBOL Data which only allows 2 Colours (or 1 to represent the "On" bit of your character). To get it displayed in the SYMBOL equivalent would require a number of definitions to build up the character.
Here vampire killer DSK complete of sources
Quote from: SRS on 12:26, 22 August 16
Take a look here: Modify the font appearance for some hints.
It's a shame them darn emoji's have got in the way in @arnoldemu (http://www.cpcwiki.eu/forum/index.php?action=profile;u=122) post. Personally I setup character sets using the TXT SET M TABLE (BBAB), DE has the number of the first character in the table & HL is the address of the table. I like this approach because you can tell it (with the HL register), where you want the Character definitions to be, unlike BASIC which forces you to put it where HIMEM is minus the size of the table (and you cannot use MEMORY prior to using SYMBOL AFTER) :o
@Fabrizio Radica (http://www.cpcwiki.eu/forum/index.php?action=profile;u=1837) I've made some small programs which redefine the character set using Condensed Text which are in the Silly Programming Ideas Thread, otherwise Redefined Character programs were published in Magazines if you're looking for something like that, the only one that comes to mind is Fontastic from AA73 (http://cpcwiki.eu/index.php/Amstrad_Action_October_1991_Type-Ins).
Hi, I've made a new version of my engine with "per pixel" movement.
Obviously, i had some problems with the sprite.
How i can copy the background over the previous frame (like double buffer)?
Tnx in advanced :)
here the code:
10 mode 0:cls:border 0:ink 0,0
200 SYMBOL 240,&X111100,&X1111110,&X11101011,&X11111111,&X11111111,&X11000011,&X1100110,&X111100
210 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
220 SYMBOL 246,&X1111110,&X10000000,&X10000000,&X10000000,&X10000000,&X10000000,&X0,&X0 'background
250 maxx%=20:maxy%=11:lev%=0:DIM map%(maxy%,maxx%):transpOn$=CHR$(22)+CHR$(1):transpOff$=CHR$(22)+CHR$(0)
260 'Read Map
280 FOR y%=1 TO maxy%:FOR x%=1 TO maxx%:READ a%:map%(y%,x%)=a%:LOCATE x%,y%:ON map%(y%,x%) GOSUB 4100,4000:NEXT x%:NEXT y%
290 x%=32*4:y%=400-16*4:v%=4 'Start Sprite position
300 CALL &BD19 'Main loop
310 'Collisions
320 yct%=INT(400-y%+16+4-v%)/16:ycd%=INT(400-y%+8+v%)/16
330 xcl%=INT(x%+32+16-v%)/32:xcr%=INT(x%+16+v%)/32
400 locate 1,14: print xc%,yc%,map%(yc%,xc%) 'debug
600 IF NOT(INKEY(8)) AND NOT(map%(ycd%,xcl%-1)=1) THEN x%=x%-v%:gosub 5000
700 IF NOT(INKEY(1)) AND NOT(map%(ycd%,xcr%+1)=1) THEN x%=x%+v%:gosub 5000
800 IF NOT(INKEY(0)) AND NOT(map%(yct%-1,xcr%)=1) THEN y%=y%+v%:gosub 5000
900 IF NOT(INKEY(2)) AND NOT(map%(ycd%+1,xcr%)=1) THEN y%=y%-v%:gosub 5000
1200 goto 300
1990 'Map Data
2000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2100 DATA 1,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1
2200 DATA 1,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1
2300 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
2400 DATA 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1
2500 DATA 1,0,0,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1
2600 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
2700 DATA 1,0,0,0,0,2,1,1,1,1,1,1,1,0,0,0,0,0,0,1
2800 DATA 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1
2900 DATA 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1
3000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3990 'Tiles
4000 PRINT CHR$(15);CHR$(8);CHR$(246);:RETURN
4100 PRINT CHR$(15);CHR$(9);CHR$(245);:RETURN
4990 'Sprite
5000 tag:move x%,y%:print CHR$(240);:tagoff:RETURN
Quote from: Fabrizio Radica on 00:17, 24 August 16
Hi, I've made a new version of my engine with "per pixel" movement.
Obviously, i had some problems with the sprite.
How i can copy the background over the previous frame (like double buffer)?
Tnx in advanced
The easiest way around that is to use XOR mode, Transparent Mode no longer works when Writing to a Graphical Position. I've made the adjustments in the program below:
10 MODE 0:CLS:BORDER 0:INK 0,0
200 SYMBOL 240,&X001111,&X0111111,&X11010111,&X11111111,&X11111111,&X11000011,&X0110011,&X001111
210 SYMBOL 245,&X01111111,&X01111111,&X01111111,&X01111111,&X01111111,&X00111111,&X0,&X0 'wall
220 SYMBOL 246,&X0111111,&X00000001,&X00000001,&X00000001,&X00000001,&X00000001,&X0,&X0 'background
250 maxx%=20:maxy%=11:lev%=0:DIM map%(maxy%,maxx%):XOROn$=CHR$(23)+CHR$(1):XOROff$=CHR$(23)+CHR$(0)
260 'Read Map
280 FOR y%=1 TO maxy%:FOR x%=1 TO maxx%:READ a%:map%(y%,x%)=a%:LOCATE x%,y%:ON map%(y%,x%) GOSUB 4100,4000:NEXT x%:NEXT y%
290 x%=32*4:y%=400-16*4:v%=4 'Start Sprite position
295 PRINT XOROn$;:GOSUB 5000
300 CALL &BD19 'Main loop
310 'Collisions
320 yct%=INT(400-y%+16+4-v%)/16:ycd%=INT(400-y%+8+v%)/16
330 xcl%=INT(x%+32+16-v%)/32:xcr%=INT(x%+16+v%)/32
400 LOCATE 1,14: PRINT xc%,yc%,map%(yc%,xc%) 'debug
600 IF NOT(INKEY(8)) AND NOT(map%(ycd%,xcl%-1)=1) THEN GOSUB 5000:x%=x%-v%:GOSUB 5000
700 IF NOT(INKEY(1)) AND NOT(map%(ycd%,xcr%+1)=1) THEN GOSUB 5000:x%=x%+v%:GOSUB 5000
800 IF NOT(INKEY(0)) AND NOT(map%(yct%-1,xcr%)=1) THEN GOSUB 5000:y%=y%+v%:GOSUB 5000
900 IF NOT(INKEY(2)) AND NOT(map%(ycd%+1,xcr%)=1) THEN GOSUB 5000:y%=y%-v%:GOSUB 5000
1200 GOTO 300
1990 'Map Data
2000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2100 DATA 1,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1
2200 DATA 1,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1
2300 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
2400 DATA 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1
2500 DATA 1,0,0,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1
2600 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
2700 DATA 1,0,0,0,0,2,1,1,1,1,1,1,1,0,0,0,0,0,0,1
2800 DATA 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1
2900 DATA 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1
3000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3990 'Tiles
4000 PRINT CHR$(15);CHR$(8);CHR$(246);:RETURN
4100 PRINT CHR$(15);CHR$(9);CHR$(245);:RETURN
4990 'Sprite
5000 PRINT XOROn$;:TAG:MOVE x%,y%:PRINT CHR$(240);:TAGOFF:PRINT XOROff$;:RETURN
I've altered the Transparent On & Off variables, so it's now XOROn$ & XOROff$, Line 295 Draws the character to screen, this is to avoid leaving a character on screen. Once the controls come into Play, the 1st GOSUB 5000 removes the character from screen, adjusts the values of X or Y accordingly and prints the new position. The routine at 5000 also has XOROn$ & XOROff$ around them. This is the easiest approach to prevent writing your character on screen, but the character will blink a little bit.
Tnx Mate,
I had not thought about it. Simple (for now) solution!! :D
Why my sprite now is deformed?
Quote from: Fabrizio Radica on 08:55, 24 August 16
Tnx Mate,
I had not thought about it. Simple (for now) solution!! :D
Why my sprite now is deformed?
Sorry that's my fault. I was using Winape to transfer the BASIC program to the assembler, but what I discovered earlier was the Assembler alters the Binary Numbering used in the SYMBOL definitions. @Executioner (http://www.cpcwiki.eu/forum/index.php?action=profile;u=17) has probably corrected this by now, I noticed this earlier when I noticed the Binary Data was being compromised and was able to save the file as ASCII and used Edit Disk to get it that way.
ok, corrected.
Tnx Again :)
10 MODE 0:CLS:BORDER 0:INK 0,0
200 SYMBOL 240,&X111100,&X1111110,&X11101011,&X11111111,&X11111111,&X11000011,&X1100110,&X111100
210 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
220 SYMBOL 246,&X1111110,&X10000000,&X10000000,&X10000000,&X10000000,&X10000000,&X0,&X0 'background
250 maxx%=20:maxy%=11:lev%=0:DIM map%(maxy%,maxx%):XOROn$=CHR$(23)+CHR$(1):XOROff$=CHR$(23)+CHR$(0)
260 'Read Map
280 FOR y%=1 TO maxy%:FOR x%=1 TO maxx%:READ a%:map%(y%,x%)=a%:LOCATE x%,y%:ON map%(y%,x%) GOSUB 4100,4000:NEXT x%:NEXT y%
290 x%=32*4:y%=400-16*4:v%=6 'Start Sprite position
295 PRINT XOROn$;:GOSUB 5000
300 CALL &BD19 'Main loop
310 'Collisions
320 yct%=INT(400-y%+16+4-v%)/16:ycd%=INT(400-y%+8+v%)/16
330 xcl%=INT(x%+32+16-v%)/32:xcr%=INT(x%+16+v%)/32
400 'LOCATE 1,14: PRINT xc%,yc%,map%(yc%,xc%) 'debug
600 IF NOT(INKEY(8)) AND NOT(map%(ycd%,xcl%-1)=1) THEN GOSUB 5000:x%=x%-v%:GOSUB 5000
700 IF NOT(INKEY(1)) AND NOT(map%(ycd%,xcr%+1)=1) THEN GOSUB 5000:x%=x%+v%:GOSUB 5000
800 IF NOT(INKEY(0)) AND NOT(map%(yct%-1,xcr%)=1) THEN GOSUB 5000:y%=y%+v%:GOSUB 5000
900 IF NOT(INKEY(2)) AND NOT(map%(ycd%+1,xcr%)=1) THEN GOSUB 5000:y%=y%-v%:GOSUB 5000
1200 GOTO 300
1990 'Map Data
2000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2100 DATA 1,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1
2200 DATA 1,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1
2300 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
2400 DATA 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1
2500 DATA 1,0,0,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1
2600 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
2700 DATA 1,0,0,0,0,2,1,1,1,1,1,1,1,0,0,0,0,0,0,1
2800 DATA 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1
2900 DATA 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1
3000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3990 'Tiles
4000 PRINT CHR$(15);CHR$(8);CHR$(246);:RETURN
4100 PRINT CHR$(15);CHR$(9);CHR$(245);:RETURN
4990 'Sprite
5000 PRINT XOROn$;:TAG:MOVE x%,y%:PRINT CHR$(240);:TAGOFF:PRINT XOROff$;:RETURN
Quote from: AMSDOS on 09:33, 24 August 16
Sorry that's my fault. I was using Winape to transfer the BASIC program to the assembler, but what I discovered earlier was the Assembler alters the Binary Numbering used in the SYMBOL definitions. @Executioner (http://www.cpcwiki.eu/forum/index.php?action=profile;u=17) has probably corrected this by now,
Thanks for finding that, just corrected it for 2.0B3.
You can overcome the flickery text (and XOR) method by using the Draw command. Drawing a line with colour zero, one pixel behind/above below etc as the text character moves. You could even shrink the text character...
00000000
000**000
00****00
0******0
0******0
00****00
000**000
00000000
...and then use the black border area around it to draw in the line.
Of course, this means that your backgrounds have to also remain colour zero.
Quote from: rk last on 11:33, 25 August 16
You can overcome the flickery text (and XOR) method by using the Draw command. Drawing a line with colour zero, one pixel behind/above below etc as the text character moves. You could even shrink the text character...
00000000
000**000
00****00
0******0
0******0
00****00
000**000
00000000
...and then use the black border area around it to draw in the line.
Of course, this means that your backgrounds have to also remain colour zero.
I try :)
(https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR7pWTw19g0Rj5ZQrRrVS4L2rwUkhnJwzyuCIjbtFrwcMRrSrxG)
As for platformers, the line method will bring forth an issue with ladders. The line could be XORed and the parts of the ladder that change colour (due to the line ink as they cross through) could be solved by assigning the same ink colour as the ladder to the XORed bits.
I hope that makes sense. Just an idea :)
I'd not recommend FORTH for games. The FORTH may not be with you. :P
Quote from: rk last on 21:35, 25 August 16
(https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR7pWTw19g0Rj5ZQrRrVS4L2rwUkhnJwzyuCIjbtFrwcMRrSrxG)
As for platformers, the line method will bring forth an issue with ladders. The line could be XORed and the parts of the ladder that change colour (due to the line ink as they cross through) could be solved by assigning the same ink colour as the ladder to the XORed bits.
I hope that makes sense. Just an idea :)
yes! I did the same thinked with ladders. ;)
i've tried also to copy first the background and then the sprite, but it's too slow with basic :(
This suggestion comes with a severe cost but it will also turbo charge you onscreen movement. Using the OUT commands to reduce the size of the screen. The demo below (thankfully found for me by Egotrip) will severely reduce the number of pixels on screen and in this case gives you a new MODE. But toying with the OUT commands usually just gives you a thicker border and less onscreen display.
10 MODE 0
20 OUT &BC00,0:OUT &BD00,127
30 OUT &BC00,4:OUT &BD00,18
40 OUT &BC00,5:OUT &BD00,15
50 OUT &BC00,6:OUT &BD00,15
60 OUT &BC00,7:OUT &BD00,17
70 WINDOW #0,1,20,1,15
80 ORIGIN 0,160
Quote from: rk last on 00:06, 26 August 16
This suggestion comes with a severe cost but it will also turbo charge you onscreen movement. Using the OUT commands to reduce the size of the screen. The demo below (thankfully found for me by Egotrip) will severely reduce the number of pixels on screen and in this case gives you a new MODE. But toying with the OUT commands usually just gives you a thicker border and less onscreen display.
10 MODE 0
20 OUT &BC00,0:OUT &BD00,127
30 OUT &BC00,4:OUT &BD00,18
40 OUT &BC00,5:OUT &BD00,15
50 OUT &BC00,6:OUT &BD00,15
60 OUT &BC00,7:OUT &BD00,17
70 WINDOW #0,1,20,1,15
80 ORIGIN 0,160
erhm.. i no longer see the sprite XORed with new MODE (WONDEFUL!!!!), why?
EDIT: i've modify ORIGIN 0,160 in ORIGIN 0,0 and works fine.P.s. at line 6000, you can see DRAW routines but i don't know how to set the black color for it and other color for the sprite.
10 MODE 0:CLS:BORDER 0:INK 0,0
20 OUT &BC00,0:OUT &BD00,127
30 OUT &BC00,4:OUT &BD00,18
40 OUT &BC00,5:OUT &BD00,15
50 OUT &BC00,6:OUT &BD00,15
60 OUT &BC00,7:OUT &BD00,17
70 WINDOW #0,1,20,1,15
80 ORIGIN 0,160
200 SYMBOL 240,&X111100,&X1111110,&X11101011,&X11111111,&X11111111,&X11000011,&X1100110,&X111100
210 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
220 SYMBOL 246,&X1111110,&X1,&X1,&X1,&X1,&X1,&X0,&X0 'background
250 maxx%=20:maxy%=11:lev%=0:DIM map%(maxy%,maxx%):XOROn$=CHR$(23)+CHR$(1):XOROff$=CHR$(23)+CHR$(0)
260 'Read Map
280 FOR y%=1 TO maxy%:FOR x%=1 TO maxx%:READ a%:map%(y%,x%)=a%:LOCATE x%,y%:ON map%(y%,x%) GOSUB 4100,4000:NEXT x%:NEXT y%
290 x%=32*4:y%=400-16*4:v%=8 'Start Sprite position
295 PRINT XOROn$;:GOSUB 5000
300 'Main loop
310 'Collisions
320 yct%=INT(400-y%+24-v%)/16:ycd%=INT(400-y%+4+v%)/16
330 xcl%=INT(x%+48-v%)/32:xcr%=INT(x%+8+v%)/32
400 'LOCATE 1,14: PRINT yct%,ycd%,map%(ycd%,xcr%+1) 'debug
600 IF NOT(INKEY() AND NOT(map%(ycd%,xcl%-1)=1) THEN GOSUB 5000:x%=x%-v%:GOSUB 5000
700 IF NOT(INKEY(1)) AND NOT(map%(ycd%,xcr%+1)=1) THEN GOSUB 5000:x%=x%+v%:GOSUB 5000
800 IF NOT(INKEY(0)) AND NOT(map%(yct%-1,xcr%)=1) THEN GOSUB 5000:y%=y%+v%:GOSUB 5000
900 IF NOT(INKEY(2)) AND NOT(map%(ycd%+1,xcr%)=1) THEN GOSUB 5000:y%=y%-v%:GOSUB 5000
1200 GOTO 300
1990 'Map Data
2000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2100 DATA 1,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1
2200 DATA 1,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1
2300 DATA 1,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,1
2400 DATA 1,0,0,0,0,1,1,1,0,0,0,1,0,1,0,0,0,0,0,1
2500 DATA 1,0,0,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1
2600 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
2700 DATA 1,0,0,0,0,2,1,1,1,1,1,1,1,0,0,0,0,0,0,1
2800 DATA 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1
2900 DATA 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1
3000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3990 'Tiles
4000 PRINT CHR$(15);CHR$(3);CHR$(246);:RETURN
4100 PRINT CHR$(15);CHR$(9);CHR$(245);
4110 POKE &BFAC+x%*4+y%*80,&60:RETURN
4990 'Sprite
5000 CALL &BD19:PRINT XOROn$;:TAG:MOVE x%,y%:PRINT CHR$(240);:TAGOFF:PRINT XOROff$;:RETURN
6000 'plot x%,y%:draw x%,-16+y%:draw 32+x%,-16+y%:draw 32+x%,-1+y%:draw x%,-1+y%:RETURN
DRAW x,y,colour
That new mode does remind me of those very old games consoles :)
You may need this too when drawing lines.
MOVE x,y [[,i1][,i2]] Moves the graphic cursor to position x,y. The parameter i1 may be used to change the pen (drawing) colour. The parameter i2 specifies the logical colour, as in DRAW. 4 drawing styles:
i2 = 0 normal colour i2 = 1 XOR colour i2 = 2 AND colour i2 = 3 OR colour
Quote from: rk last on 01:21, 26 August 16
DRAW x,y,colour
That new mode does remind me of those very old games consoles :)
yeah! I really love the new mode!!!
tnx :)
Or even this.
MOVER xr,yr[,[i1][,i2]] moves the graphic cursor (relative) from current position to current cursor x position + xr, current cursor y position + yr. i1 and i2 as in MOVE.
Quote from: Fabrizio Radica on 01:26, 26 August 16
yeah! I really love the new mode!!!
tnx :)
And its all done in basic too. I dare say that you could easily code a Donkey Kong clone easily with that display and its increase in power.
Quote from: rk last on 01:30, 26 August 16
And its all done in basic too. I dare say that you could easily code a Donkey Kong clone easily with that display and its increase in power.
goooood idea!!!
Donkey Kong, Mr. Do, Space Invaders and Frogger :D
With hardware scrolling and tilemaps with fast pooling routines, we can make a Super Mario Clone also...
Quote from: rk last on 01:26, 26 August 16
You may need this too when drawing lines.
MOVE x,y [[,i1][,i2]] Moves the graphic cursor to position x,y. The parameter i1 may be used to change the pen (drawing) colour. The parameter i2 specifies the logical colour, as in DRAW. 4 drawing styles: i2 = 0 normal colour i2 = 1 XOR colour i2 = 2 AND colour i2 = 3 OR colour
Not very 464 friendly though.
Quote from: AMSDOS on 10:32, 26 August 16
Not very 464 friendly though.
Exactly :(
I'm back to XOR sprite with background.
It has flicker, but works fine for now... (waiting for new ideas)
Quote from: Fabrizio Radica on 13:55, 26 August 16
Exactly
I'm back to XOR sprite with background.
It has flicker, but works fine for now... (waiting for new ideas)
It's possible to draw a box (in background colour), which reduces flicker to the edge of the character, but then you've got the background blocks that are at risk of being deleted as your character passes over it.
To make it work your character has to move up or down by a factor of 2 (not 4), to prevent the top or bottom of your character messing up the screen like earlier. Though for Left/Right Motion 4 is used in MODE 0 as each Pixel is 4 co-ordinates along: e.g. PLOT 0,398,1 PLOT 4,398,2 (for Top-Left of Screen).
Anyway, I'll post what I wrote, but I think the XOR version is better (it doesn't destroy the scenery), when it comes to BASIC though, reducing/eliminating the flicker will either involve Compiling the code in a BASIC compiler or setting up a Second Screen to draw the scenery on that screen and alternate, which involves using OUT commands.
10 MODE 0:CLS:BORDER 0:INK 0,0
200 SYMBOL 240,&X111100,&X1111110,&X11101011,&X11111111,&X11111111,&X11000011,&X1100110,&X111100
210 SYMBOL 245,&X1111111,&X1111111,&X1111111,&X1111111,&X1111111,&X111111,&X0,&X0 'wall
220 SYMBOL 246,&X111111,&X1,&X1,&X1,&X1,&X1,&X0,&X0 'background
250 maxx%=20:maxy%=11:lev%=0:DIM map%(maxy%,maxx%)
260 'Read Map
280 FOR y%=1 TO maxy%:FOR x%=1 TO maxx%:READ a%:map%(y%,x%)=a%:LOCATE x%,y%:ON map%(y%,x%) GOSUB 4100,4000:NEXT x%:NEXT y%
290 x%=32*4:y%=400-16*4:v%=2:v2%=4 'Start Sprite position
295 GOSUB 5100
300 CALL &BD19 'Main loop
310 'Collisions
320 yct%=INT(400-y%+16+4-v%)/16:ycd%=INT(400-y%+8+v%)/16
330 xcl%=INT(x%+32+16-v%)/32:xcr%=INT(x%+16+v%)/32
400 LOCATE 1,14: PRINT xc%,yc%,map%(yc%,xc%) 'debug
600 IF NOT(INKEY(8)) AND NOT(map%(ycd%,xcl%-1)=1) THEN GOSUB 5000:x%=x%-v2%:GOSUB 5100
700 IF NOT(INKEY(1)) AND NOT(map%(ycd%,xcr%+1)=1) THEN GOSUB 5000:x%=x%+v2%:GOSUB 5100
800 IF NOT(INKEY(0)) AND NOT(map%(yct%-1,xcr%)=1) THEN GOSUB 5000:y%=y%+v%:GOSUB 5100
900 IF NOT(INKEY(2)) AND NOT(map%(ycd%+1,xcr%)=1) THEN GOSUB 5000:y%=y%-v%:GOSUB 5100
1200 GOTO 300
1990 'Map Data
2000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2100 DATA 1,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1
2200 DATA 1,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1
2300 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
2400 DATA 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1
2500 DATA 1,0,0,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1
2600 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
2700 DATA 1,0,0,0,0,2,1,1,1,1,1,1,1,0,0,0,0,0,0,1
2800 DATA 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1
2900 DATA 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1
3000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3990 'Tiles
4000 PRINT CHR$(15);CHR$(8);CHR$(246);:RETURN
4100 PRINT CHR$(15);CHR$(9);CHR$(245);:RETURN
4990 'Sprite
5000 MOVE x%,y%:DRAW x%+28,y%,0:DRAW x%+28,y%-14:DRAW x%,y%-14:DRAW x%,y%:RETURN
5100 PLOT -2,-2,1:TAG:MOVE x%,y%:PRINT CHR$(240);:TAGOFF:RETURN
Even a sprite routine would display a small amount of flicker - and even more if a mask was incorporated too (in Basic).
So the only solution I can see is to store the screen in memory (very expensive in terms of bytes) and then re-display it at the start of the game loop. Using this approach would dismiss the need for XOR or lines that erase the previous x%/Y% location. (Im pretty sure that there was a 464 type in that allowed you to store the display off screen. )
Anyhows, the program flow would be something like...
Draw the map
grab screen and store in memory
GAME LOOP
display chr$(240)
check controls -update x or y position, call the stored image to back to the screen
LOOP
Quote from: rk last on 12:16, 27 August 16
Even a sprite routine would display a small amount of flicker - and even more if a mask was incorporated too (in Basic).
So the only solution I can see is to store the screen in memory (very expensive in terms of bytes) and then re-display it at the start of the game loop. Using this approach would dismiss the need for XOR or lines that erase the previous x%/Y% location. (Im pretty sure that there was a 464 type in that allowed you to store the display off screen. )
Anyhows, the program flow would be something like...
Draw the map
grab screen and store in memory
GAME LOOP
display chr$(240)
check controls -update x or y position, call the stored image to back to the screen
LOOP
yes, this is the best solution.
when i was writing games for amiga in asm, i used the same method (double buffer). where i can find all the CPC memory addresses?
- grab memory stored in &c000 (16kb) in &8000?
game loop
- display and move the sprites, ok
- restore from &8000 to &c000?
loop
tnx :)
Quote from: Fabrizio Radica on 14:59, 27 August 16
...
- grab memory stored in &c000 (16kb) in &8000?
game loop
- display and move the sprites, ok
- restore from &8000 to &c000?
...
If you have firmware active (e.g. from basic or you are using firmware functions), then ~&a600-&bfff is used by firmware.
&0000-&0040 is used by firmware. Basic starts at &170.
HIMEM (highest for basic) is around &a600 (depending on roms), and ~&b000-&bfff is firmware and stack. &c000-&ffff is normal screen location.
So you are restricted where you want to have this other buffer.
If you are using hardware direct you can turn off firmware and use any address you want (e.g. &8000-&bfff), but you don't have this control with BASIC. BASIC needs firmware.
This leaves &4000-&7fff but now your BASIC free space is much less because BASIC memory is continuous.
You could use "bank manager" (bankman). It is on the CPM system discs. It allows you to copy screens and if you are writing for 128KB machine you can store basic data in the extra ram.
The information is in the 6128 manual.
You can make double buffer this way but it will not be fast. To be faster you need to use assembler or c or other language that gives you easier access to firmware then you can use the hardware direct or firmware functions to set the screen location and do hardware double buffer.
Maybe you could try asm or c on the cpc?
Quote from: Fabrizio Radica on 13:55, 26 August 16
Exactly :(
I'm back to XOR sprite with background.
It has flicker, but works fine for now... (waiting for new ideas)
Normally CPC sprites are drawn:
- AND pixels (removing the screen pixels we don't want to show through)
- OR pixels (to add our sprite pixels).
Both draw modes can be used in BASIC. You may end up having less symbols to use and it may flicker, but the colours will be correct and you will need to redraw the background if the sprite moves.
This describes control characters and their parameters and they are executed. You can change colours, draw mode and more.
http://cpctech.cpc-live.com/docs/manual/s158ap07.pdf (http://cpctech.cpc-live.com/docs/manual/s158ap07.pdf)
So the crazy idea:
- setup a long string in basic with lots of spaces.
a$=" "
or perhaps
a$=SPACE$(30)
Now you can find the memory address of the string "descriptor" with @. String descriptor is 1 byte length, 2 bytes address.
e.g. desc=@a$:straddr=peek(desc+1)+(peek(desc+2)*256)
Now you can poke the values into the string.
poke straddr+0,23:poke straddr+1,24:poke straddr+2,'A'
and poke the length in desc+0.
The print a$ to do the whole lot.
Maybe you can "chain" operations and this will reduce flicker?
It would take BASIC time to do the pokes and it would take BASIC time to maintain the string, so maybe you don't win, but it may be possible to use.
EDIT: You can put control characters direct into strings. Using CTRL+letter/number. It produces a symbol which is the drawable version of the control-code.
Heres a screen grab routine that Ive borrowed from an Amstrad Action art program. Hope it helps.
1 restore 5
2 memory 24549
3 for n=24550 to 24574:read a:poke n,a:next
4 view=24550:store=24559
5 data &f3,33,00,96,17,00,192,&18,8,&f3,33,00,192,17,00,96,0,0,1,00,64,&ed,&b0,&fb,201
6 rem Use Call store to capture screen
7 rem and Call view to display it
Quote from: Fabrizio Radica on 14:59, 27 August 16
yes, this is the best solution.
when i was writing games for amiga in asm, i used the same method (double buffer).
tnx :)
Or even use the amigas dual playfield to draw your tiles in the background and sprites/bobs in front :) Happy memories
Quote from: rk last on 16:56, 27 August 16
Heres a screen grab routine that Ive borrowed from an Amstrad Action art program. Hope it helps.
1 restore 5
2 memory 24549
3 for n=24550 to 24574:read a:poke n,a:next
4 view=24550:store=24559
5 data &f3,33,00,96,17,00,192,&18,8,&f3,33,00,192,17,00,96,0,0,1,00,64,&ed,&b0,&fb,201
6 rem Use Call store to capture screen
7 rem and Call view to display it
Ok, Ive tried this method and although its works your left with even worse flickering.
So the only solution I can see worth using is ESD Advanced (http://www.sean.co.uk/books/amstrad/amstrad8.shtm). Create your 8x8 player sprite and another sprite 8x1 and also 1x8. The latter two will be used for deleting(dont forget to use the OUTPUT option to obtain each sprites memory address). Save the sprites and then load up the ESD 2 driver. Now remove the demo at the end of the code and add something like this.
A far more visually rewarding method340 Memory &44FF:Load "filename.ADD",&9D4F;load "filename.BNK",&4500
350 x%=100:y%=200
400 rem * Movement Routine *
410 if not(inkey(8)) then x%=x%-1:call 40000,(1x8 Sprites memory address),x%+8,y%: rem draw the 1x8 sprite to the right of the player to kill its trail
450 call 40000,(players sprite address),x%,y%:rem Stamp the player sprite on screen
460 goto 410
ESD 2 offers XOR sprites but you end up with a similar result to chr$. It also includes two other display methods but I`ll let you toy with them :)
Quote from: rk last on 12:16, 27 August 16
Even a sprite routine would display a small amount of flicker - and even more if a mask was incorporated too (in Basic).
We've had a few examples of where a second screen has been used to draw the next sequence, I wrote a game a couple of years ago in BASIC which had sprite driver as well as a small assembly routine to partially save the screen which seemed to work, even though the program wasn't really meant for complicated games. @HAL 6128 (http://www.cpcwiki.eu/forum/index.php?action=profile;u=365) posted a bouncing ball program in the Hisoft Pascal 4T thread (http://www.cpcwiki.eu/forum/programming/hisoft-pascal-4t/msg51548/#msg51548) which also made use of a second screen, depending on what version of BASIC you were using, the code needed altering (http://www.cpcwiki.eu/forum/programming/hisoft-pascal-4t/msg51640/#msg51640) to work in BASIC 1.0.
One program (that I mentioned elsewhere (http://www.cpcwiki.eu/forum/games/game-programmers-hall-of-fame-the-amstrad-elite/msg132339/#msg132339)) which I think is worthwhile studying is Quack a Jack, which is a mixture of BASIC 14Kb & M/C 12Kb. I say study because some of the BASIC is dealing with the Internals of the game, the name of the Levels and I even found a BASIC array being defined to match the size of the Playing area (20x11), the graphics are handled by the Binary, though some of those are being called from the BASIC. So I find it impressive that game shows no sign of flicker, it was coded in 1984 on a 464, your main Duck character removes the tiles, though the nasties just move all over it without issue. I thought what Paul Shirley might of done was work out the phase of the tile in relation to his sprite, but when I was watching the demo in the game, when the nasty moves over the duck, a blank square is revealed, which means the nasty hasn't put one in that spot.
Quote from: rk last on 23:39, 27 August 16
Ok, Ive tried this method and although its works your left with even worse flickering.
Unfortunately that screen grab routine is using LDIR on both accounts to Store and View a screen. It's perfectly fine for within an Art program, though begins to show for a game.
This thread (http://www.cpcwiki.eu/forum/programming/more-silly-programming-using-graphics/msg106268/#msg106268) I made last year explores using Sprite Graphics and handling Backdrops and also talks about flickering. The link I provided there was the last version I did which looks at using ESD2 along with my routine to Restore the backdrop. In that situation I was able to reduce the amount of flicker by using LDI to fill in an area around the graphic.
Sprites and keyboard control for the duck are drawn using the asm code.
KL TIME PLEASE and KL TIME SET are used. Seems to be some kind of delay loop. These count the 300hz raster interrupts.
Sprites drawn using AND and then XOR. Seems basic is mostly used for "glue" logic.
ok, are the last BASIC tests... i'll be back to ASM :(
When i was 15, my dream was to program a game for CPC in Basic.
So, After 26 years i wanted to try :)
But first, i would make a complete game... in Basic.
Thanks for your precious help :)
(and i'm sorry for my very bad english :( )
Hi :D
I'm back with my new CPC6128, the other is broken, unfortunatly...
Now i would like to implement new functionality and make a Bomberman clone.. always in Locomotive Basic :)
Quote from: Fabrizio Radica on 22:30, 28 December 16
Hi :D
I'm back with my new CPC6128, the other is broken, unfortunatly...
Now i would like to implement new functionality and make a Bomberman clone.. always in Locomotive Basic :)
It might help study a Bomberman clone thats been written in BASIC. I found this one which is written in QBASIC, but it's up to 4 players, I'm not sure if there's an 1 player option. The site I found it on mentioned it lacking Sound FXs & Music which is good I guess, as they are more system specific things to add later. Only problem with QBASIC is the layout of it, which makes it look a little bit more like Pascal. GWBASIC tends to look at bit more like Locomotive BASIC.
Quote from: AMSDOS on 05:37, 29 December 16
It might help study a Bomberman clone thats been written in BASIC. I found this one (http://neozones.quickbasic.com/basfiles/bombman.zip) which is written in QBASIC, but it's up to 4 players, I'm not sure if there's an 1 player option. The site I found it on (http://www.angelfire.com/il/QBasicSourcePage/filegames.html) mentioned it lacking Sound FXs & Music which is good I guess, as they are more system specific things to add later. Only problem with QBASIC is the layout of it, which makes it look a little bit more like Pascal. GWBASIC tends to look at bit more like Locomotive BASIC.
404 - File or directory not found.The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.
:([/font][/color][/size]
Quote from: Fabrizio Radica on 09:52, 29 December 16
404 - File or directory not found.The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.
:(
Sorry, but it looks like the site I provided was a dodgy one! :( This one look legit (http://www.antonis.de/qbdown/qbspiele.htm), I downloaded the SBM which looks legit, the comment inside the BAS file look a bit dodgy though, it looks like a 2 player Bomberman though, as does the one on this site (http://www.qbasic.net/en/qbasic-downloads/games/action-1.htm).
This site (http://www.qb45.org/files.php?cat=3&p=1) also has a few Bomberman clones on it, I downloaded the first one boombss2, but the source code was all weird. ::) It may need QuickBASIC 4.5 to view it properly.
uhm... ok, i'm tired and old :D
but.. what i wrong in this code? O_o
i've problems with the wall collisions and bonus
Lines 320 and 330
i forgot something?
tnx :)
10 clear:MODE 0:CLS:BORDER 0:INK 0,0
20 OUT &BC00,0:OUT &BD00,127
30 OUT &BC00,4:OUT &BD00,18
40 OUT &BC00,5:OUT &BD00,15
50 OUT &BC00,6:OUT &BD00,15
60 OUT &BC00,7:OUT &BD00,17
70 WINDOW #0,1,20,1,15
80 ORIGIN -1,-1
200 SYMBOL 240,&X111100,&X1111110,&X11101011,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player right
205 SYMBOL 251,&X111100,&X1111110,&X11010111,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player left
210 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
220 SYMBOL 246,&X1111110,&X1,&X1,&X1,&X1,&X1,&X0,&X0 'background
222 SYMBOL 247,&X111100,&X1111110,&X11111011,&X11111111,&X11111111,&X11111111,&X1111110,&X111100 'bonus
230 SYMBOL 250,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111 'ladder
250 maxx%=20:maxy%=11:lev%=0:DIM map%(maxy%,maxx%):XOROn$=CHR$(23)+CHR$(1):XOROff$=CHR$(23)+CHR$(0)
260 'Read Map
280 FOR y%=1 TO maxy%:FOR x%=1 TO maxx%:READ a%:map%(y%,x%)=a%:LOCATE x%,y%:ON map%(y%,x%) GOSUB 4100,4200,4300:NEXT x%:NEXT y%
290 x%=32*4:y%=400-16*4:vx%=8:vy%=4:walk=0:frcount=1:pframe$(frcount)=CHR$(240):pframe$(frcount+1)=CHR$(251) 'Start Sprite position
295 PRINT XOROn$;:GOSUB 5000
300 'Main loop
310 'Collisions
320 yct%=INT(400-y%+20)/16:ycd%=INT(400-y%+8)/16
330 xcl%=INT(x%+32)/32:xcr%=int(x%+16)/32
400 'LOCATE 1,14: PRINT walk 'debug
600 IF NOT(INKEY(8)) AND NOT(map%(ycd%,xcl%-1)=1) THEN GOSUB 5000:frcount=2:x%=x%-vx%:GOSUB 5000
700 IF NOT(INKEY(1)) AND NOT(map%(ycd%,xcr%+1)=1) THEN GOSUB 5000:frcount=1:x%=x%+vx%:GOSUB 5000
800 IF NOT(INKEY(0)) AND NOT(map%(yct%-1,xcl%)=1) and walk=1 THEN GOSUB 5000:y%=y%+vy%:GOSUB 5000
900 IF NOT(INKEY(2)) AND NOT(map%(ycd%+1,xcl%)=1) THEN GOSUB 5000:y%=y%-vy%:GOSUB 5000
950 IF map%(ycd%+1,xcl%)=0 THEN walk=0:GOSUB 5000:y%=y%-vy%:GOSUB 5000 else walk=1
1000 IF map%(ycd%,xcl%)=3 THEN map%(ycd%,xcl%)=0:locate xcl%,ycd%:locate 1,12:sc%=sc%+1:print sc%
1200 GOTO 300
1990 'Map Data
2000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2100 DATA 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1
2200 DATA 1,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,1
2300 DATA 1,0,0,0,0,0,0,1,0,0,2,1,1,0,0,0,0,0,0,1
2400 DATA 1,0,0,0,0,1,1,1,0,0,2,1,0,0,0,3,0,2,0,1
2500 DATA 1,0,0,0,1,1,1,0,0,0,2,0,0,1,1,1,1,2,0,1
2600 DATA 1,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,2,0,1
2700 DATA 1,0,0,0,0,2,1,1,1,1,1,1,1,0,0,0,0,2,0,1
2800 DATA 1,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,2,0,1
2900 DATA 1,0,0,0,0,2,0,0,3,0,0,0,1,0,0,3,0,2,0,1
3000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3990 'Tiles
4100 PRINT CHR$(15);CHR$(9);CHR$(245);
4110 POKE &BFAC+x%*4+y%*80,&60:RETURN
4200 PRINT CHR$(15);CHR$(4);CHR$(250);:RETURN
4300 PRINT CHR$(15);CHR$(7);CHR$(247);:RETURN
4990 'Sprite
5000 CALL &BD19:PRINT XOROn$;:TAG:MOVE x%,y%:PRINT pframe$(frcount);:TAGOFF:PRINT XOROff$;:RETURN
Quote from: Fabrizio Radica on 00:19, 31 December 16
uhm... ok, i'm tired and old :D
but.. what i wrong in this code? O_o
i've problems with the wall collisions and bonus
Lines 320 and 330
i forgot something?
tnx :)
The main problem I had was when your character was moving through the Bonuses. A LOCATE command to position for removing the Bonus was present, but nothing to delete. I've inserted a space to delete the character, but then part of my character gets deleted, so I'm deleting my character and then redrawing which is Line 1000.
The Collision Checks to check and see if you're colliding with the Walls are not adequate enough because the main character is now graphically moving around the screen. If your main character was moving based on the Text position, then yes, checks with the Array would be sufficient. For graphics "test(x-coordinate,y-coordinate)" is your best option. I've altered lines 600-900 and have tried placing the test checks in the best spots, it's not totally foolproof, but at least your character isn't travelling through Walls now.
Also I didn't know what the deal was with the OUT commands and have removed them (it was doing some weird Interlaced Effect), as I was testing everything so much I added a "key 128,"call &bc02:ink 1,26:mode 2"+chr$(13); to reset the inks/mode. When I exit out of your program I can use 0 on the numeric keypad to reset everything. Initially your character was slightly offset of the text-cursor position, I changed line 290 which simply adds 4 to the rest of x%
10 CLEAR:CALL &BC02:MODE 0:CLS:BORDER 0:INK 0,0
70 WINDOW #0,1,20,1,15
80 ORIGIN -1,-1
200 SYMBOL 240,&X111100,&X1111110,&X11101011,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player right
205 SYMBOL 251,&X111100,&X1111110,&X11010111,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player left
210 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
220 SYMBOL 246,&X1111110,&X1,&X1,&X1,&X1,&X1,&X0,&X0 'background
222 SYMBOL 247,&X111100,&X1111110,&X11111011,&X11111111,&X11111111,&X11111111,&X1111110,&X111100 'bonus
230 SYMBOL 250,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111 'ladder
250 maxx%=20:maxy%=11:lev%=0:DIM map%(maxy%,maxx%):XOROn$=CHR$(23)+CHR$(1):XOROff$=CHR$(23)+CHR$(0)
260 'Read Map
280 FOR y%=1 TO maxy%:FOR x%=1 TO maxx%:READ a%:map%(y%,x%)=a%:LOCATE x%,y%:ON map%(y%,x%) GOSUB 4100,4200,4300:NEXT x%:NEXT y%
290 x%=4+(32*4):y%=400-16*4:vx%=8:vy%=4:walk=0:frcount=1:pframe$(frcount)=CHR$(240):pframe$(frcount+1)=CHR$(251) 'Start Sprite position
295 PRINT XOROn$;:GOSUB 5000
300 'Main loop
310 'Collisions
320 yct%=INT(400-y%+20)/16:ycd%=INT(400-y%+8)/16
330 xcl%=INT(x%+32)/32:xcr%=INT(x%+16)/32
400 'LOCATE 1,14: PRINT walk 'debug
600 IF NOT(INKEY(8)) AND ((TEST(x%-8,y%-6)<>9) AND (TEST(x%-8,y%-14)<>9)) THEN GOSUB 5000:frcount=2:x%=x%-vx%:GOSUB 5000
700 IF NOT(INKEY(1)) AND ((TEST(x%+32,y%-6)<>9) AND (TEST(x%+32,y%-14)<>9)) THEN GOSUB 5000:frcount=1:x%=x%+vx%:GOSUB 5000
800 IF NOT(INKEY(0)) AND ((TEST(x%,y%+2)<>9) AND (TEST(x%+28,y%+2)<>9)) AND walk=1 THEN GOSUB 5000:y%=y%+vy%:GOSUB 5000
900 IF NOT(INKEY(2)) AND ((TEST(x%,y%-18)<>9) AND (TEST(x%+20,y%-18)<>9)) THEN GOSUB 5000:y%=y%-vy%:GOSUB 5000
950 IF map%(ycd%+1,xcl%)=0 THEN walk=0:GOSUB 5000:y%=y%-vy%:GOSUB 5000 ELSE walk=1
1000 IF map%(ycd%,xcl%)=3 THEN map%(ycd%,xcl%)=0:LOCATE xcl%,ycd%:PRINT" ";:MOVE x%,y%:TAG:PRINT" ";:TAGOFF:GOSUB 5000:LOCATE 1,12:sc%=sc%+1:PRINT sc%
1200 GOTO 300
1990 'Map Data
2000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2100 DATA 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1
2200 DATA 1,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,1
2300 DATA 1,0,0,0,0,0,0,1,0,0,2,1,1,0,0,0,0,0,0,1
2400 DATA 1,0,0,0,0,1,1,1,0,0,2,1,0,0,0,3,0,2,0,1
2500 DATA 1,0,0,0,1,1,1,0,0,0,2,0,0,1,1,1,1,2,0,1
2600 DATA 1,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,2,0,1
2700 DATA 1,0,0,0,0,2,1,1,1,1,1,1,1,0,0,0,0,2,0,1
2800 DATA 1,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,2,0,1
2900 DATA 1,0,0,0,0,2,0,0,3,0,0,0,1,0,0,3,0,2,0,1
3000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3990 'Tiles
4100 PRINT CHR$(15);CHR$(9);CHR$(245);
4110 POKE &BFAC+x%*4+y%*80,&60:RETURN
4200 PRINT CHR$(15);CHR$(4);CHR$(250);:RETURN
4300 PRINT CHR$(15);CHR$(7);CHR$(247);:RETURN
4990 'Sprite
5000 CALL &BD19:PRINT XOROn$;:TAG:MOVE x%,y%:PRINT pframe$(frcount);:TAGOFF:PRINT XOROff$;:RETURN
Quote from: AMSDOS on 07:02, 31 December 16
The main problem I had was when your character was moving through the Bonuses. A LOCATE command to position for removing the Bonus was present, but nothing to delete. I've inserted a space to delete the character, but then part of my character gets deleted, so I'm deleting my character and then redrawing which is Line 1000.
The Collision Checks to check and see if you're colliding with the Walls are not adequate enough because the main character is now graphically moving around the screen. If your main character was moving based on the Text position, then yes, checks with the Array would be sufficient. For graphics "test(x-coordinate,y-coordinate)" is your best option. I've altered lines 600-900 and have tried placing the test checks in the best spots, it's not totally foolproof, but at least your character isn't travelling through Walls now.
Also I didn't know what the deal was with the OUT commands and have removed them (it was doing some weird Interlaced Effect), as I was testing everything so much I added a "key 128,"call &bc02:ink 1,26:mode 2"+chr$(13); to reset the inks/mode. When I exit out of your program I can use 0 on the numeric keypad to reset everything. Initially your character was slightly offset of the text-cursor position, I changed line 290 which simply adds 4 to the rest of x%
10 CLEAR:CALL &BC02:MODE 0:CLS:BORDER 0:INK 0,0
70 WINDOW #0,1,20,1,15
80 ORIGIN -1,-1
200 SYMBOL 240,&X111100,&X1111110,&X11101011,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player right
205 SYMBOL 251,&X111100,&X1111110,&X11010111,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player left
210 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
220 SYMBOL 246,&X1111110,&X1,&X1,&X1,&X1,&X1,&X0,&X0 'background
222 SYMBOL 247,&X111100,&X1111110,&X11111011,&X11111111,&X11111111,&X11111111,&X1111110,&X111100 'bonus
230 SYMBOL 250,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111 'ladder
250 maxx%=20:maxy%=11:lev%=0:DIM map%(maxy%,maxx%):XOROn$=CHR$(23)+CHR$(1):XOROff$=CHR$(23)+CHR$(0)
260 'Read Map
280 FOR y%=1 TO maxy%:FOR x%=1 TO maxx%:READ a%:map%(y%,x%)=a%:LOCATE x%,y%:ON map%(y%,x%) GOSUB 4100,4200,4300:NEXT x%:NEXT y%
290 x%=4+(32*4):y%=400-16*4:vx%=8:vy%=4:walk=0:frcount=1:pframe$(frcount)=CHR$(240):pframe$(frcount+1)=CHR$(251) 'Start Sprite position
295 PRINT XOROn$;:GOSUB 5000
300 'Main loop
310 'Collisions
320 yct%=INT(400-y%+20)/16:ycd%=INT(400-y%+8)/16
330 xcl%=INT(x%+32)/32:xcr%=INT(x%+16)/32
400 'LOCATE 1,14: PRINT walk 'debug
600 IF NOT(INKEY() AND ((TEST(x%-8,y%-6)<>9) AND (TEST(x%-8,y%-14)<>9)) THEN GOSUB 5000:frcount=2:x%=x%-vx%:GOSUB 5000
700 IF NOT(INKEY(1)) AND ((TEST(x%+32,y%-6)<>9) AND (TEST(x%+32,y%-14)<>9)) THEN GOSUB 5000:frcount=1:x%=x%+vx%:GOSUB 5000
800 IF NOT(INKEY(0)) AND ((TEST(x%,y%+2)<>9) AND (TEST(x%+28,y%+2)<>9)) AND walk=1 THEN GOSUB 5000:y%=y%+vy%:GOSUB 5000
900 IF NOT(INKEY(2)) AND ((TEST(x%,y%-18)<>9) AND (TEST(x%+20,y%-18)<>9)) THEN GOSUB 5000:y%=y%-vy%:GOSUB 5000
950 IF map%(ycd%+1,xcl%)=0 THEN walk=0:GOSUB 5000:y%=y%-vy%:GOSUB 5000 ELSE walk=1
1000 IF map%(ycd%,xcl%)=3 THEN map%(ycd%,xcl%)=0:LOCATE xcl%,ycd%:PRINT" ";:MOVE x%,y%:TAG:PRINT" ";:TAGOFF:GOSUB 5000:LOCATE 1,12:sc%=sc%+1:PRINT sc%
1200 GOTO 300
1990 'Map Data
2000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2100 DATA 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1
2200 DATA 1,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,1
2300 DATA 1,0,0,0,0,0,0,1,0,0,2,1,1,0,0,0,0,0,0,1
2400 DATA 1,0,0,0,0,1,1,1,0,0,2,1,0,0,0,3,0,2,0,1
2500 DATA 1,0,0,0,1,1,1,0,0,0,2,0,0,1,1,1,1,2,0,1
2600 DATA 1,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,2,0,1
2700 DATA 1,0,0,0,0,2,1,1,1,1,1,1,1,0,0,0,0,2,0,1
2800 DATA 1,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,2,0,1
2900 DATA 1,0,0,0,0,2,0,0,3,0,0,0,1,0,0,3,0,2,0,1
3000 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3990 'Tiles
4100 PRINT CHR$(15);CHR$(9);CHR$(245);
4110 POKE &BFAC+x%*4+y%*80,&60:RETURN
4200 PRINT CHR$(15);CHR$(4);CHR$(250);:RETURN
4300 PRINT CHR$(15);CHR$(7);CHR$(247);:RETURN
4990 'Sprite
5000 CALL &BD19:PRINT XOROn$;:TAG:MOVE x%,y%:PRINT pframe$(frcount);:TAGOFF:PRINT XOROff$;:RETURN
Thanks you!
Yes, this "new" engine, move the sprite in different mode from the previous routine because i would like to try best ways.
I did don't know the TEST command. How does it work?
Tnx and Happy New Year :)
Quote from: Fabrizio Radica on 14:04, 31 December 16
Thanks you!
Yes, this "new" engine, move the sprite in different mode from the previous routine because i would like to try best ways.
I did don't know the TEST command. How does it work?
Tnx and Happy New Year :)
Okay, so all the BASIC Commands/Operators/Functions are documented here on the CPCWiki (http://www.cpcwiki.eu/index.php/Locomotive_BASIC). TEST is a function that returns an INK value found at the specified graphical co-ordinates. In this case when a key is pressed to move your character, 2-points are tested which are just outside your character relevant to the side your character is most likely to trigger a Collision event, if one is found, which in this case is pen 9 for the wall, your character stops short. Probably where I've gone wrong in my 2-point Collision Test, is I'm using the operator "AND", which is telling BASIC to find a PEN 9 here & there, but if it's a PEN 0 or the edge of the Wall which is using another colour, that condition is not being met, causing the character to fall ever so slightly into the Wall until it finds PEN 9. The whole point of the 2-point test is to check another position in case your character is over a gap or a different colour, essentially in the opposite end of your character, so in this case it might be better using "OR" in-between the TEST checks so for example:
600 IF NOT(INKEY() AND ((TEST(x%-8,y%-6)<>9) AND (TEST(x%-8,y%-14)<>9)) THEN GOSUB 5000:frcount=2:x%=x%-vx%:GOSUB 5000
becomes:
600 IF NOT(INKEY() AND ((TEST(x%-8,y%-6)<>9) OR (TEST(x%-8,y%-14)<>9)) THEN GOSUB 5000:frcount=2:x%=x%-vx%:GOSUB 5000
EDIT:Sorry no, I'm getting my logic all mixed up and "AND" is the one you need to use with the 2 point TEST.
Is the INT in lines 320-330 really necessary, as the result is going into an integer variable anyway?
No, it's not necessary :)
The INT isn't necessary, but I was getting a Subscript out of range error if the brackets were also removed.
if you like, i've created a Github repository of my project :)
https://github.com/FabrizioRadica/amstrad-platform-basic
I was going through a BASIC technical guide on the Wiki last night and discovered using logic conditioning within an IF statement is bad, so made some adjustments to your game:
600 IF NOT(INKEY(8)) THEN IF (TEST(x%-8,y%-6)<>9) THEN IF (TEST(x%-8,y%-14)<>9) THEN GOSUB 5000:frcount=2:x%=x%-vx%:GOSUB 5000
700 IF NOT(INKEY(1)) THEN IF (TEST(x%+32,y%-6)<>9) THEN IF (TEST(x%+32,y%-14)<>9) THEN GOSUB 5000:frcount=1:x%=x%+vx%:GOSUB 5000
800 IF NOT(INKEY(0)) THEN IF (TEST(x%,y%+2)<>9) THEN IF (TEST(x%+28,y%+2)<>9) THEN IF walk=1 THEN GOSUB 5000:y%=y%+vy%:GOSUB 5000
900 IF NOT(INKEY(2)) THEN IF (TEST(x%,y%-18)<>9) THEN IF (TEST(x%+20,y%-18)<>9) THEN GOSUB 5000:y%=y%-vy%:GOSUB 5000
I've replaced all the ANDs within the IF statements and made a nested IFs out of it all (as suggested in the guide) and tested this which is definitely faster than a single IF with all the conditioning in it.
Quote from: AMSDOS on 21:17, 04 January 17
I was going through a BASIC technical guide on the Wiki last night and discovered using logic conditioning within an IF statement is bad, so made some adjustments to your game:
600 IF NOT(INKEY() THEN IF (TEST(x%-8,y%-6)<>9) THEN IF (TEST(x%-8,y%-14)<>9) THEN GOSUB 5000:frcount=2:x%=x%-vx%:GOSUB 5000
700 IF NOT(INKEY(1)) THEN IF (TEST(x%+32,y%-6)<>9) THEN IF (TEST(x%+32,y%-14)<>9) THEN GOSUB 5000:frcount=1:x%=x%+vx%:GOSUB 5000
800 IF NOT(INKEY(0)) THEN IF (TEST(x%,y%+2)<>9) THEN IF (TEST(x%+28,y%+2)<>9) THEN IF walk=1 THEN GOSUB 5000:y%=y%+vy%:GOSUB 5000
900 IF NOT(INKEY(2)) THEN IF (TEST(x%,y%-18)<>9) THEN IF (TEST(x%+20,y%-18)<>9) THEN GOSUB 5000:y%=y%-vy%:GOSUB 5000
I've replaced all the ANDs within the IF statements and made a nested IFs out of it all (as suggested in the guide) and tested this which is definitely faster than a single IF with all the conditioning in it.
WOW Fantastic!!!!
Quote from: AMSDOS on 21:17, 04 January 17
I was going through a BASIC technical guide on the Wiki last night and discovered using logic conditioning within an IF statement is bad, so made some adjustments to your game:
600 IF NOT(INKEY() THEN IF (TEST(x%-8,y%-6)<>9) THEN IF (TEST(x%-8,y%-14)<>9) THEN GOSUB 5000:frcount=2:x%=x%-vx%:GOSUB 5000
700 IF NOT(INKEY(1)) THEN IF (TEST(x%+32,y%-6)<>9) THEN IF (TEST(x%+32,y%-14)<>9) THEN GOSUB 5000:frcount=1:x%=x%+vx%:GOSUB 5000
800 IF NOT(INKEY(0)) THEN IF (TEST(x%,y%+2)<>9) THEN IF (TEST(x%+28,y%+2)<>9) THEN IF walk=1 THEN GOSUB 5000:y%=y%+vy%:GOSUB 5000
900 IF NOT(INKEY(2)) THEN IF (TEST(x%,y%-18)<>9) THEN IF (TEST(x%+20,y%-18)<>9) THEN GOSUB 5000:y%=y%-vy%:GOSUB 5000
I've replaced all the ANDs within the IF statements and made a nested IFs out of it all (as suggested in the guide) and tested this which is definitely faster than a single IF with all the conditioning in it.
Sorry AMSDOS, where i find the Basic techical guide?
Tnx ^_^
Yes I found a small segment called "Speeding up BASIC programs (http://www.cpcwiki.eu/index.php/Technical_information_about_Locomotive_BASIC#Speeding_up_BASIC_programs)" within the Technical information about Locomotive BASIC (http://www.cpcwiki.eu/index.php/Technical_information_about_Locomotive_BASIC), apart from the one I made changes to, the other which may apply in your code is the variable after the NEXT. As the article points out though, this can have the disadvantage of compromising good programming style, which I tend to agree strongly about.
Quote from: AMSDOS on 22:18, 04 January 17
Yes I found a small segment called "Speeding up BASIC programs (http://www.cpcwiki.eu/index.php/Technical_information_about_Locomotive_BASIC#Speeding_up_BASIC_programs)" within the Technical information about Locomotive BASIC (http://www.cpcwiki.eu/index.php/Technical_information_about_Locomotive_BASIC), apart from the one I made changes to, the other which may apply in your code is the variable after the NEXT. As the article points out though, this can have the disadvantage of compromising good programming style, which I tend to agree strongly about.
uhm, i've found this:
[...] Often recurring subroutines (if necessary) should be at the beginning of RAM to speed up things.so... should i put line 5000 (for example) at the start?
Quote from: Fabrizio Radica on 22:49, 04 January 17
uhm, i've found this:
[...] Often recurring subroutines (if necessary) should be at the beginning of RAM to speed up things.
so... should i put line 5000 (for example) at the start?
Unfortunately I don't understand that 1st point, which starts by talking about Avoiding Loops or a Branching program structure if possible, but this last point you're referring to sounds like something different again. I can follow all the other points except this 1st one which is confusing ??? I've checked with Kevin's original Published article, but it hasn't got the section about Speeding up BASIC Programs, this has been tacked on since by @HAL 6128 (http://www.cpcwiki.eu/forum/index.php?action=profile;u=365) :D
@Fabrizio
This is looking great!
Just one little thing I noticed... when you drop off a platform and then hold the down arrow key, you'll end up partly stuck in the platform below after landing.
Quote from: ervin on 23:17, 04 January 17
@Fabrizio
This is looking great!
Just one little thing I noticed... when you drop off a platform and then hold the down arrow key, you'll end up partly stuck in the platform below after landing.
yes i know... seems to be the "TEST" inside the "IF" at line 900...
it's a little bug and i'm going to correct it soon ;)
Quote from: ervin on 23:17, 04 January 17
@Fabrizio
This is looking great!
Just one little thing I noticed... when you drop off a platform and then hold the down arrow key, you'll end up partly stuck in the platform below after landing.
Yes that was ME! I tried correcting it, but don't know what I was doing wrong! :D