11. 9. 2021

Husenica (wurmi) - 3. ZX Spectrum verzia

Po prepísaní, pochopení a odladení na PMD85 a PP01 som sa rozhodol prepísať húsenicu na ZX Spectrum. Síce jeho Basic nepozná BPLOT funkciu, ale pri 8x8 bitových znakoch je výhodné použiť "PRINT AT y,x" a vykresľovať húsenicu cez používateľom definované znaky (UDG).

Základom pre prepis je PP01 verzia a bude odladená na menej riadkov obrazovky (0-21 miesto 0-31).


User Defined Graphics

Pre vlastné obrázky sa dá použiť UDG, PP01 verzia používa rovnako 8x8 pre BPLOT a teda preberiem grafiku z nej pre zachovanie autenticity.

Na nastavenie sa používa príkaz POKE USR, kde si zvolím písmeno pod ktorým v grafickom režime vykreslím daný obrázok.

23 FOR i=0 TO 7:READ a			# UDG plot
24 POKE USR "P"+i,a:NEXT i
25 DATA 85,170,85,170,85,170,85,170

Čísla v DATA sú opäť po riadkoch skonvertované na jednotlivé bity. Cyklus môžem zopakovať pre každý znak a aj jeho písmeno načítať z bloku dát. Takto sa skráti veľkosť nastavenia UDG, ktoré potrebujeme pre plot, hlavu, telo, jed, list.

Ďalej samozrejme použijem pole Z pre uloženie rozmiestnenia obrazu. Vykreslím najskôr plot, potom húsenicu a na náhodné pozície vykreslím listy a jedy.

Po zinicalizovaní kruhového buffera prvými súradnicami húsenice čakám na stlačenie klávesy pre prvotný smer húsenice a následne skočím do hlavného cyklu.

Hlavný cyklus

Hlavný cyklus dekóduje stlačený kláves na posuny súradníc v premenných A, B pre os X a Z. Takto zároveň húsenica pokračuje jedným smerom kým sa nestlačí iný kláves. Cyklus pre načítanie opakujem 3 krát ako pokusmi zistený rozumný počet opakovaní pre rýchlu reakciu a malé zdržanie programu. Nastaví sa tak väčší pomer času čítania klávesy voči zvyšku (posunu a analýze kolízie).

Po snímaní klávesnice nachystáme do premennej z1 novú polohu v bufferi pozície. Pozrieme, či na danej novej pozícií nekoliduje húsenica s niečím v bufferi obrazovky Z. Ak tam nič nie je, prekreslíme húsenici hlavu, odmažeme jej chvost a vrátime sa na čítanie klávesnice.

Ak narazíme na list, v podstate sa situácia zopakuje ale predĺžime dĺžku húsenice (premenná cm), prekreslíme len hlavu bez odmazania chvosta a vrátime sa.

V ostatných prípadoch hra končí a to je riešené v sekcií "koniec", kde podľa prípadu oznámime najskôr čo sa stalo a ak ide o rekord aj zahráme "fanfáry".

Záver

Kým hra je relatívne pomalá a vhodná tak pre Basic, je zaujímavá z hľadiska optimálneho používania premenných (napr. kruhový buffer, premenné pre smer pohybu) a minimalizácie vykresľovania.
Pri testovaní hrateľnosti donúti aj experimentovať a napríklad zväčšením času čítania klávesnice výrazne zlepšiť pocit z hrania.

Motivuje tak k vylepšovaniu, zároveň však ostáva učebnou pomôckou.

Čo je však nutné dodať, iné zadávanie príkazov ako po jednotlivých znakoch mierne spomalilo zápis programu a bolo nutné držať si otvorený obrázok klávesnice ZX spectra kvôli popiskom. Po PMD a PP01 emulátoroch to je menej príjemná skúsenosť. Je to však realita Basicu tohto počítača.


1 REM ** HUSENICA ** WI-1 **
2 REM ** Steiner,Wirdzek  **
3 REM ** ZX version BK2   **
4 REM
5 GO SUB 1000				# vypiseme nadpis (ovladanie a autor)
6 GO SUB 1020				# vypiseme zvysok uvodnej stranky
15 CLEAR				# reset premennych
18 LET rc=0				# rekord
20 LET z=3: LET aa=1000		        # dlzka husenice, pola
21 DIM x(1000): DIM y(1000): DIM z(22,32)
22 GO SUB 1000				# nadpis
24 FOR n=0 TO 4: READ p$
25 FOR i=0 TO 7: READ a
26 POKE USR p$+i,a:NEXT i
27 NEXT n
30 DATA "P",85,170,85,170,85,170,85,170	# UDG P plot
31 DATA "T",8,28,62,127,127,62,28,8		# UDG T telo
32 DATA "H",65,62,65,85,73,73,34,28		# UDG H hlava
33 DATA "N",0,132,72,48,48,72,132,0		# UDG N jed
34 DATA "J",0,12,18,33,51,12,31,0		# UDG J list
45 INK 2
47 PAPER 4: PRINT AT 21,0;" Q-hore A-dole O-vlavo P-vpravo  ": PAPER 7
50 FOR i=0 TO 31				# vrch a spod plota
51 PRINT AT 1,i;"[P]";AT 20,i;"[P]"
52 LET z(1,i+1)=1: LET z(20,i+i)=1
55 NEXT i
60 FOR i=2 TO 19				# boky plota
61 PRINT AT i,0;"[P]";AT i,31;"[P]"
62 LET z(i,1)=1: LET z(i,32)=1
63 NEXT i
75 INK 0					# najskor husenicu
140 PRINT AT 10,15;"[H]";AT 11,15;"[T]";AT 12,15;"[T]"
142 LET z(10,16)=3: LET z(11,16)=3: LET z(12,16)=3
145 GO TO 200
150 LET x=RND*30: LET y=RND*17+3		# nahodne umiestnenie
160 IF z(y,x+1)>0 THEN GO TO 150		# na prazdne miesto
170 PRINT AT y,x;: RETURN
200 LET li=45: LET kr=30			# listov 45, jedov 30
209 INK 4: FOR i=1 TO li: GO SUB 150: PRINT "[J]": LET z(y,x+1)=4: NEXT i
210 INK 3: FOR i=1 TO kr: GO SUB 150: PRINT "[N]": LET z(y,x+1)=2: NEXT i
215 INK 0					# pole umiestnenia husenice
220 FOR i=1 TO 3: LET y(i)=13-i: LET x(i)=16: NEXT i: LET cm=2
229 PAPER 4
230 PRINT AT 21,0;cm;AT 21,5;"REKORD ";rc
231 PAPER 7					# cakame prvu klavesu
270 IF INKEY$<>"p" AND INKEY$<>"o" AND INKEY$<>"a" AND INKEY$<>"q" THEN GO TO 270
274 PAPER 4: PRINT AT 21,0;"                             "
275 LET a=0: LET b=0
276 PRINT AT 21,0;cm;AT 21,5;"REKORD ";rc
277 PAPER 7
300 REM --hlavny cyklus--
302 FOR i=1 TO 3				# citanie klaves a dekodovanie na posun
305 IF INKEY$="p" THEN LET a=0: LET b=1
306 IF INKEY$="o" THEN LET a=0: LET b=-1
307 IF INKEY$="q" THEN LET a=-1: LET b=0
308 IF INKEY$="a" THEN LET a=1: LET b=0
309 NEXT i
310 LET q=z-cm: IF q<1 THEN LET q=q+aa		# zaciatok a koniec v bufferi
340 LET z1=z+1: IF z1>aa THEN LET z1=z1-aa
350 LET x(z1)=x(z)+b: LET y(z1)=y(z)+a		# buduca pozicia
351 IF z(y(z1),x(z1))=2 THEN GO TO 501		# je tam jed
352 IF z(y(z1),x(z1))=1 THEN GO TO 515		# plot
353 IF z(y(z1),x(z1))=3 THEN GO TO 529		# kusnem do seba
355 IF z(y(z1),x(z1))=4 THEN GO TO 380		# list
356 IF q>500 THEN LET x(q)=1: LET y(q)=1
359 LET z(y(q),x(q))=0				# kreslime hlavu, zmazeme chvost
360 PRINT AT y(z),y(z)-1;"[T]";AT y(z1),y(z1)-1;"[H]";AT y(q),x(q)-1;" "
365 LET z=z1
370 LET z(y(z),x(z))=3: GO TO 300
380 PRINT AT y(z),x(z)-1;"[T]"			# zjem list
382 LET z=z1
385 PRINT AT y(z),y(z)-1;"[H]"
387 LET z(y(z),x(z))=3
390 LET cm=cm+1: PAPER 4: PRINT AT 21,0;cm: PAPER 7
400 INK 4: GO SUB 150: PRINT "[J]": LET z(x,y)=4: INK 0
410 IF cm<>50 THEN GO TO 300
430 FOR i=1 TO 10: NEXT i
460 GO TO 300
500 REM --koniec--
501 GO SUB 1220					# sekcia pre kazdy koniec
502 PRINT AT 21,0;"       NAZRAL SOM SA JEDU       "
508 GO SUB 1220
510 PAUSE 300: GO TO 530
525 PRINT AT 21,0;"     HLAVOU MUR NEPRERAZIM      ": GO SUB 1220: PAUSE 300: GO TO 530
529 PRINT AT 21,0;"       SAM SEBA NEZERIEM        ": PAUSE 300
530 IF cm<rc THEN GO TO 850
535 PAUSE 20: CLS
600 REM -fanfary-
610 BEEP .2,20: BEEP .18,25: BEEP .2,26: BEEP .5,30
620 PRINT AT 12,10;"ZOZRAL SI"
640 PRINT AT 14,12;cm;" LISTOV"
670 IF cm>rc THEN PRINT AT 16,7;"TO JE NOVY REKORD !!": LET rc=cm: GO TO 920
680 PRINT AT 20,0;"  DOBRE, ALE DNES UZ SOM ZOZRAL "
690 PRINT AT 21,10;rc;" LISTOV"
920 PRINT AT 21,0;"       CHCES HRAT ZNOVU ?       "
925 IF INKEY$<>"a" AND INKEY$<>"n" THEN GO TO 925
930 IF INKEY$="n" THEN GO TO 1300		# pri hrani znovu vycisti obraz
940 FOR i=1 TO 20: PRINT "================================": NEXT i
950 FOR i=1 TO 20: PRINT "                                ": NEXT i
980 RESTORE
998 GO TO 20
999 REM --intro--
1000 BORDER 4: PAPER 4: INK 0			# horna hlavicka
1002 PRINT AT 0,0;"HUSENICA    KME EF 1984, BK 2021"
1004 PAPER 7
1005 RETURN
1020 PRINT AT 9,9;"   /"			# zvysny obsah uvodnej obrazovky
1021 PRINT AT 10,9;"||||/-|-|\|/-/\"
1022 PRINT AT 11,9;"H||\\|-|||| ||"
1023 PRINT AT 12,9;"||U-/|-|||\-H"
1100 PRINT AT 21,10;"stlacte klaves"
1150 PAUSE 0
1210 RETURN
1220 REM --zvucka--				# ked nieco zakusnem co nemam
1230 FOR i=15 TO 30: BEEP .01,i: NEXT i
1240 FOR i=10 TO 30: BEEP .015,i: NEXT i
1250 FOR i=0 TO 30: BEEP .02,i: NEXT i
1270 RETURN
1300 REM END					# sem skocime ked uz mame dost
1310 BORDER 7: PAPER 7: INK 0

Možno by stálo za to nakuknúť aj do možností assemblera na tomto stroji. Cez malé rýchle podporné rutiny až po nejakú tú hru.

Žiadne komentáre:

Zverejnenie komentára