Játékfejlesztésem
története
Az Emberkétől a Hungry
Creature-ig
A 80-as évek vége felé írtam első „játékprogramomat”, amely
az Emberke volt. A program négyszög alakú karaktereket véletlenszerűen szétszórt a
képernyőn, az emberke alakú karaktert pedig a belső botkormánnyal lehetett
mozgatni. Egy percünk volt, hogy minél több négyszöget összeszedjünk. A program
még a négyszöggel való ütközést sem érzékelte, és ha kimentünk a játéktérből,
hibaüzenettel leállt. De azért így is jól el lehetett szórakozni vele. Egy
picit mindig szépítettem rajta, így idővel lett Emberke 10 is. Később nagyon
megörültem, hogy a Hetedhéten túl című Enterprise-os könyvben a Hamikában volt
ütközésérzékelés, így onnan el tudtam lopni a GET #102:A$ elvét, ami lekérdezi
a kurzor pozíciójában lévő karaktert. Így már számolta az összegyűjtött
négyszögeket, és a játéktér körül keretkarakterek (ez a szó visszafele olvasva
is ugyanúgy van!) is voltak, a játéktéren belül pedig falak.
Hála a Zzzip-nek,
rájöttem, hogy ebből még többet is ki lehet hozni, így megjelentek a pályán a
szörnyek is. Innen egy kicsit komolyabbra fordult a programozás. A játék
pályáit DATA sorokban tároltam. Hogy gyorsabb legyen, azt találtam ki, hogy a
pálya kirajzolása után a program a képernyő tartalmát, az összes karaktert a
képernyőről végignézi, és beolvassa egy tömbbe (a KEP$(X,Y) tömbbe), így a
pálya falai abban a tömbben voltak benne. A szörnyek így nem a képernyőről
olvasták ki, hogy hol van fal és merre lehet menni, hanem a tömbből, ez
gyorsabb volt. Így csak azt kellett a képernyőről kiolvasni, hogy az emberkénk
hova lép, szóközre, bogyóra, netalán a szörny karakterére.
Addig még csak-csak elvoltam a PRINT #102,AT utasítással, a GET
#102:A$-gel, a JOY és az RND függvénnyel, viszont a szörnyek mozgása kicsit más
volt. A pacman játékokban megfigyelhetjük, hogy a szörnyek általában egy adott
irányba mozognak, amíg kereszteződéshez nem érnek, és ott újra felvesznek
valamilyen irányt. Ezt próbáltam én is megvalósítani valahogy. Négy szörny volt
a pályán, mindegyiknél figyelni kellett, hogy kereszteződéshez vagy zsákutcához
érnek-e, és akkor új irányt kellett nekik meghatározni. Ezt először, kisebb küzdelmek
árán így sikerült elérnem valamikor 1995 őszén, ha jól emlékszem:
3750 LET UT,FEL,LE,JO,BA=03760 IF KEP$(SZO1(A)-1,SZO2(A))=" " THEN LET UT=UT+1:LET FEL=13770 IF KEP$(SZO1(A)+1,SZO2(A))=" " THEN LET UT=UT+4:LET LE=13780 IF KEP$(SZO1(A),SZO2(A)-1)=" " THEN LET UT=UT+8:LET BA=13790 IF KEP$(SZO1(A),SZO2(A)+1)=" " THEN LET UT=UT+2:LET JO=13800 IF UT=5 OR UT=10 THEN GOTO 39703810 IF FEL+LE+JO+BA=0 THEN LET I1(A),I2(A)=0:GOTO 39703820 IF FEL+LE+JO+BA=1 THEN LET I1(A)=I1(A)*(-1):LET I2(A)=I2(A)*(-1):GOTO 39703830 SELECT CASE RND(4)3840 CASE 03850 IF FEL=1 THEN LET I1(A)=-1:LET I2(A)=0:GOTO 39603860 LET I1(A)=1:LET I2(A)=03870 CASE 13880 IF LE=1 THEN LET I1(A)=1:LET I2(A)=0:GOTO 39603890 LET I1(A)=-1:LET I2(A)=03900 CASE 23910 IF JO=1 THEN LET I1(A)=0:LET I2(A)=1:GOTO 39603920 LET I1(A)=0:LET I2(A)=-13930 CASE 33940 IF BA=1 THEN LET I1(A)=0:LET I2(A)=-1:GOTO 39603950 LET I1(A)=0:LET I2(A)=13960 END SELECT3970 RETURN
Addig módosítgattam ezt az eljárást, amíg úgy nem működött,
ahogy elképzeltem, utána meg már nem foglalkoztam vele, csak örültem, hogy
működik. Pedig ez eléggé szedett-vedett, és lehetne rajta szépíteni. A
3760-3790-es sorokban megnézi a program, hogy az adott szörny alatt, fölött,
tőle jobbra és balra szóköz van-e, azaz nincs-e fal, és ha szabad a pálya,
akkor az UT változó értékét módosítja, és a túlbiztosítás érdekében a FEL, LE,
JO, BA változók értékét is értelemszerűen 1-re módosítja 0-ról. Ezzel eltárolja
a gép, hogy merre van lehetséges útirány a szörny számára. A 3800-as sorban
megvizsgáljuk, hogy esetleg pont csak függőlegesen mindkét irányba, vagy csak
vízszintesen mindkét irányba tudunk-e mozogni, és ha igen, akkor nem történik
semmi, hanem tartjuk az irányt, tehát egyirányú folyosón tovább megyünk arra,
amerre addig is tartottunk. A 3810-es sorban azt biztosítjuk, hogy ha a szörny
mind a négy oldalról körül van véve fallal, akkor semerre ne mozduljon el. A
3820-as sorban azt ellenőrizzük, hogy zsákutcában vagyunk-e, vagyis csak
egyetlen irányba mozoghatunk-e. Ilyenkor feltételezzük, hogy az egyetlen
lehetséges irányból jöttünk, így az irányt megváltoztatjuk. Ez az irányváltás,
és az előbb említett folyosón haladás is csak akkor lehetséges, ha már adott
volt egy irány, tehát rögtön a játék indulásakor, amikor az irányt
meghatározzuk, ez még nem működik. A pálya indulásakor mindig meg kellett
határozni az irányt egy külön eljárással. A 3830-as sortól pedig akkor adunk
egy véletlenszerű irányt a lehetséges irányok közül a szörnynek, ha se nem
folyosón haladunk, se nem zsákutcába nem értünk, se nem volt a szörny körülvéve
minden oldalról fallal.
Egy probléma volt ezzel a pacman típusú játékkal: a
képernyőn lévő bogyókat a szörnyek felülírták a mozgásukkal. Bonyolultnak
láttam megcsinálni, hogy a szörnyek megjegyezzék, hogy bogyóra vagy szóközre
léptek-e rá, és azt rakják ki maguk után. Emlékeztem, hogy általános iskolában
talán számítógépes szakkör keretében, vagy ki tudja, mikor, előkerült a Plus/4-es Squirm című játék, ahol a pacmanhez hasonlóan bogyókat kell gyűjteni, a
pályán kígyók mozognak, melyekkel nem szabad összeütközni. Ott úgy működött a
játék, hogy az egyik kígyó mindig bogyókat hagyott maga után, a többi kígyó
pedig szóközt, és 200 bogyót kellett összegyűjteni a pálya teljesítéséhez.
https://www.youtube.com/watch?v=aBVo64iLZn4
Innen jött az ötletem, hogy a Hungry Creature játékban két szörny mindig
bogyókat, a másik kettő pedig mindig szóközöket hagyjon maga után, és bizonyos
mennyiségű bogyó összeszedése kellett a szint teljesítéséhez. Ezt sokkal
könnyebbnek láttam megvalósítani, mint hogy a szörnyek megjegyezzék, hogy
bogyóra vagy szóközre léptek-e.
Nagy örömömre összejött ebből a Hungry Creature című játék,
ami Zzzippel lefordítva pont játszható sebességgel működik. Igaz, az egész
képernyő egyszínű, mert karakteres képernyőn fut a program, így csak egy
tintaszín és egy háttérszín van, de legalább pályánként változik a paletta.
Szerettem zenéket komponálni DATA sorokba írt számok
segítségével, így volt néhány szerzeményem. Ezek közül az egyiket betettem a
menübe háttérzenének.
Gondoltam, toplista is kellene, hogy beírhassuk játék után a
nevünket, a program pedig beillessze pontszámunk alapján a nevünket a megfelelő helyre a rangsorban. Ennek megvalósításáról nem sok
fogalmam volt, viszont eszembe jutott, hogy a Felhasználói kézikönyvben volt
egy példaprogram, amely 10 számot rendez nagyság szerint sorba:
140 NUMERIC TOMB(1 TO 10)
150 NUMERIC VALT,SZAM,MAX
…
250 LET VEG=10
260 FOR X=1 TO 10
270 LET MAX=0
280 FOR Y=1 TO VEG
290 IF TOMB(Y)>MAX THEN LET MAX=TOMB(Y)
300 IF TOMB(Y)=MAX THEN LET SZAM=Y
310 NEXT Y
320 LET VALT=TOMB(VEG)
330 LET TOMB(VEG)=MAX
340 LET TOMB(SZAM)=VALT
350 LET VEG=VEG-1
360 NEXT X
370 FOR X=1 TO 10
380 PRINT TOMB(X)
390 NEXT X
Ezt a programot addig módosítgattam, amíg el nem értem, hogy
a 10 legjobb pontszámot rendezze sorba a pontszámokhoz tartozó névvel együtt.
Így névbeírás után a megfelelő helyre kerültünk a toplistában. Itt is számokat
kellett sorba rendezni, de ez annyiból nehezebb volt, hogy a számokhoz
(pontszámokhoz) nevek is tartoznak, és a pontszámokat a nevekkel együtt kell
mozgatni, a nevek pedig már nem számokként, hanem sztringként tárolhatók:
140 STRING * 15 N$(1 TO 10),MAX$,VALT$
150 NUMERIC SZAM
6080 LET VEG=106090 FOR X=1 TO 106100 LET MAX$="99999AAAAAAAAAA"6110 FOR Y=1 TO VEG6120 IF N$(Y)<MAX$ THEN LET MAX$=N$(Y)6130 IF N$(Y)=MAX$ THEN LET SZAM=Y6140 NEXT Y6150 LET VALT$=N$(VEG)6160 LET N$(VEG)=MAX$6170 LET N$(SZAM)=VALT$6180 LET VEG=VEG-16190 NEXT X6200 LET MINPONT=VAL(N$(10))
Ahogy a MAX$ változóból látható, a pontszámok és a nevek
egymáshoz kapcsolását úgy oldottam meg, hogy egyetlen sztringbe írtam bele a
pontszámot és a nevet, elöl a pontszámmal.
Sztringeket is nagyság szerint sorba lehet rendezni, mint
számokat, de ez kicsit máshogy működik. Sztringeknél elsősorban azt nézi a gép, hogy
melyik hosszabb, és az lesz a nagyobb. Ha egyforma hosszúak a sztringek, akkor
aszerint dönti el, melyik legyen a nagyobb, hogy az első karaktereknek a kódja melyiknek nagyobb. Hogy
egyforma hosszúak legyenek a pontszámot és nevet tároló sztringek, azt találtam
ki, hogy az első öt karakter a pontszámot, a következő tíz karakter pedig a
nevet tárolja. Ha a pontszám ötnél kevesebb számjegyből áll, az elejére annyi
nullát kell lenni, hogy meglegyen az öt számjegy. Ha pedig a név rövidebb tíz
karakternél, a végére szóközöket, vagy esztétikai célból inkább pontokat kell
tenni. Ezekkel a módosításokkal már a sztringekbe fűzött pontszám+név együttest
is a pontszám nagysága szerinti sorrendbe lehet rendezni. A pontszámtábla
képernyőre írásakor pedig először a neveket írjuk ki egymás alá, azaz
a sztringet az ötödiktől a tizenötödik karakteréig, utána akár színt váltunk,
és az új színnel a nevek után a pontszámokat, amelyek nullákkal az elejükön
szebben is mutatnak.
A MINPONT változóra azért volt szükség, mert csak akkor
ugrott a program a névbeírás részhez, ha az addigi legkisebb pontszámot
meghaladta az új eredmény.
Pályaszerkesztőt is készítettem a játékba, a készített pályákat
el lehet menteni, és választhatunk, hogy a beépített vagy a kimentett pályákkal
akarunk-e játszani. Ez magnós gépnél nem annyira jó, floppys gépnél elmegy,
SD-s gépnél pedig akár egészen előnyös is lehet.
Nagyjából így állt össze a Hungry Creature.
https://www.youtube.com/watch?v=-ck2h2ih6fo
A Dot Collector is bejön
a képbe!
Egyszer valamikor, én se tudom, mikor, talán a 90-es évek
második felében eszembe jutott a Dot Collector játék, hogy az milyen rövid,
magnóról betöltődik két füttyre a fejléc után, és hogy az is valamiféle karakteres
képernyőn fut, legalábbis karakterekből épül fel a képernyő, hiszen a mozgás is
karakteres.
http://www.ep128.hu/Ep_Games/Pic/Dot_2.gif
Arra gondoltam, mivel rövid program, talán nem lesz nehéz benne megtalálni azokat a részeket, ahol a pályák tárolódnak. Meg is találtam, ASMON-nal átírva a kód megfelelő részét a pálya is módosult, aminek ugyancsak nagyon megörültem. Persze így kissé nehéz lenne áttervezni a pályát. Mivel a program rövid, arra gondoltam, egy basic programmal beolvasom magát az egész játékot, egy tömbben letárolom bájtonként, és onnan megjelenítem a pályákat és megcsinálom, hogy lehessen a pályákat szerkeszteni. Biztos eltartott egy darabig, mire ez meglett, de már nem emlékszem a részletekre.
http://www.ep128.hu/Ep_Games/Pic/Dot_2.gif
Arra gondoltam, mivel rövid program, talán nem lesz nehéz benne megtalálni azokat a részeket, ahol a pályák tárolódnak. Meg is találtam, ASMON-nal átírva a kód megfelelő részét a pálya is módosult, aminek ugyancsak nagyon megörültem. Persze így kissé nehéz lenne áttervezni a pályát. Mivel a program rövid, arra gondoltam, egy basic programmal beolvasom magát az egész játékot, egy tömbben letárolom bájtonként, és onnan megjelenítem a pályákat és megcsinálom, hogy lehessen a pályákat szerkeszteni. Biztos eltartott egy darabig, mire ez meglett, de már nem emlékszem a részletekre.
Azonban sajnos
tragédia történt. Nem sok floppylemezem ment tönkre, de amin a Dot Collector
pályaszerkesztő volt, az pont tönkrement, így elveszett minden. Nem hagyott
azonban nyugodni a dolog, és a 21. században újra nekiálltam megírni a Dot
Collector pályaszerkesztőt, ami szép lassan kész is lett. Így aztán lett Dot
Collector 2, Dot Collector 3, Dot Collector 4, többé-kevésbé újszerű pályákkal. (Az ep128.hu
oldalról letölthető a Dot Collector 2., 3., 4. része, és a pályaszerkesztő is: http://ep128.hu/Ep_Games/Leiras/Dot_Games.htm)
http://www.ep128.hu/Ep_Games/Pic/Dotdes.gif
A Dot Collector pályaszerkesztője
http://www.ep128.hu/Ep_Games/Pic/Dotdes.gif
A Dot Collector pályaszerkesztője
Szöget ütött a fejembe az is, hogy ha már ki tudom nyerni a
Dot Collector pályáit, akár fel is használhatnám azokat basic programban, így
akár a Hungry Creature-höz hasonló játékot lehetne írni úgy, hogy a szörnyek a
Dot Collector pályáin mozognának. A Dot Collectorban a szörnyek mozgása
meglehetősen egyszerűen van megoldva: mindig az emberkénk irányába próbálnak
mozogni, arra, ahol éppen nincsen fal. Ezért a Dot Collector némiképp logikai
jellegű játék, a szörnyek nem mozognak folyamatosan, ahogy általában a pacman
típusú játékokban. Nem tudni, a játék készítői miért így oldották meg, hiszen a
véletlenszerű, pacman játékokból ismert szörnymozgás megvalósítása sem lett
volna annyira bonyolult, ha már nagy nehezen én is meg tudtam csinálni. De
lehet, hogy direkt írták meg így a programot, bár dobhatott volna rajta, ha
dinamikusabb a játék. A lényeg, hogy elhatároztam, összeeresztem a Dot
Collector pályáit a dinamikusan mozgó szörnyekkel. Ki is cseréltem a Hungry
Creature játékban a pályákat a Dot Collector pályáira. Sajnos sokáig nem tudtam
folytatni a nagy művet, mert valami probléma volt valamelyik szörny
koordinátáival, hiszen a játéktér kb. feleakkora, mint amekkora az egész
képernyőn elférne, és a Hungry Creature pályáiban más volt a szörnyek
startpozíciója. Sokáig nem jöttem rá, miért nem tudom átírni a szörnyek
startpozícióját, hogy most már az új pályákon mozogjanak. De elhatároztam, hogy
ha addig élek is, megcsinálom. Emlékszem, valamikor a 2010-es évek közepén lett
laptopom, amire természetesen az EP128Emu-t is feltettem. Időnként Pestre
utaztam, ami majdnem egy óra vonatozás, és kipróbáltam, milyen lehet
utazás közben programozgatni Enterprise-on az emulátorral. A mai napig
emlékszem, hogy ott a vonaton sikerült megvalósítani, hogy a szörnyek a Dot
Collectorból kiszedett pályán mozogjanak. Nagyon boldog voltam, de a kalauznak
nem számoltam be a sikeremről, hiszen nem értette volna, mit jövök én
Enterprise emulátorokkal. (Igaz, ki tudja, akár neki is lehetett régen Enterprise-a.) A lényeg, hogy meglett végül a Dot Collector Turbo
Edition becenévre keresztelt játék, ahol a szörnyek dinamikusan mozognak, bár a
képernyőn még mindig csak két szín volt, az egyik a háttér színe. A Dot
Collector pályáin varázstabletták is vannak, melyek egy kis időre
sérthetetlenséget adnak, és egy számláló jelzi (a jobb oldali kijelzőn a HELP mellett), hogy meddig tart
a hatása. Ezt elsőre bonyolultnak gondoltam megcsinálni. Helyette azt találtam
ki, hogy plusz energiát adnak a varázstabletták, így a szörnyek nem nyiffantják
ki egyből hősünket. Ahogy a program fejlesztésével
haladtam, mindig feltöltöttem az újabb verziót az Enterprise Forever fórumra.
Ott Ferro73 fórumtárs is elkezdett foglalkozni a programmal, javaslatokat tett
a módosításokra, több részt át is írt benne. Tett bele többek között karakteres
animációt, a varázstabletták már villogtak. Javaslatára már nem mentette el
tömbbe a játékteret a program, hanem a képernyőről olvasta be a karaktereket, a
szörnyek mozgásához. A karakterek beolvasásához már nem GET #102:A$, hanem
SPEEK került bevetésre, valamint a szörnyek és az emberkénk képernyőre írása is
már nem PRINT AT, hanem SPOKE segítségével történt:
Régi módszer:PRINT #102,AT oszlop,sor:;GET #102:A$IF A$=blablablaÚj módszer:IF SPEEK(255,VM+(sor*36)+oszlop)=blablablaLET VM=(SPEEK(255,14644)+((SPEEK(255,14645)-128)*256))-35
Ez persze még csak 128-as gépen működik, Enterprise 64-en nem. Az új módszer programozásánál arra is figyelni kell, hogy a kép videomemória-beli helye nagyon sok mindentől megváltozhat. Ezért fixre nem szabad állítani, ki kell olvasni az LPT táblából, csak úgy lesz jó mindenhol. Ehhez én persze nem értek, Ferro73-ék megoldották ezt is a programban:
5515 LET LPBADDL=SPEEK(255,16372):LET LPBADDH=SPEEK(255,16373)
5516 LET LPBADDH=LPBADDH-128:LET LPBSZ=255
5517 LET LPBADD=LPBADDL+(256*LPBADDH)
...
5530 OPEN #102:"VIDEO:"
...
5555 LET CIM=LPBADD+(3*16) !
5556 LET GETAH=SPEEK(LPBSZ,CIM+5)-128
5557 LET VM=SPEEK(LPBSZ,CIM+4)+(256*GETAH)-35
Így a Dot Collector Turbo Edition már egy feljavított
változata lett a Hungry Creature-nek, azon túl, hogy új pályákat tartalmazott.
Az új pályák többé-kevésbé eltértek a Dot Collector eredeti pályáitól, mivel az
újfajta szörnymozgás bezavarhat ebbe: vagy pillanatok alatt
végigszáguld a szörny egy folyosón, vagy pedig egy nagyobb, üres részen
szöszmötöl sokáig.
A képernyő jobb oldalát a kijelzők foglalják el (pontszám,
életek száma, stb.) Ennek az alsó részén van egy kis hely, ahol eredetileg csak
egy árva Dot Collector felirat virított. Pihenésképpen megpróbáltam ide más
szöveget írni, vagy a játéktéren belülihez hasonló falakat rajzolni. Láttam,
hogy ezek a falak akár a játéktér meghosszabbításai is lehetnének, és azt találtam
ki, hogy a negyedik varázstabletta felvételekor megnyílik ott egy kapu, vagyis
szóközt rak a gép a játéktér jobb alsó részén a falba, és át lehet menni a
kijelzők alá. Ezt a lehetőséget SlashNet, ukrán fórumtársunk először bugnak
nézte. A későbbi fejlesztéseknél nagy szerepe lesz még ennek a kapunak, ugyanis
csak így juthatunk majd el a pálya bizonyos részeire, de ne rohanjunk még
annyira előre!
Tervben volt, hogy attribútum képernyősre átírjuk ezt a
játékot, ez azonban elmaradt, mert nagyon sok mindent másképp kellene
megcsinálni benne, ráadásul attribútum képernyőn a karakteres animációtól is érzékeny búcsút kellene venni.
Egy kis kitérő: a Hamika
kígyós játék is berobban a színpadra
Valamikor a 2010-es évek második felében előkerült a téma a
fórumon a karakteres-grafikus (Endi által GraCha-nak nevezett) videomódokról.
Eltartott egy darabig, mire felfogtam, hogy ez mi is tulajdonképpen, amiről a
fórumban a profik írnak. (Erről az Enterpress 2019/3-4. számában már volt egy
cikk.) Tehát, a háttér színével együtt egyszerre 4 szín lehet a
karakteres képernyőn, egyetlen karakteren belül is lehet variálni a színeket,
viszont a karakterek 8 pixel helyett csak 4 pixel szélesek. Ha még
karaktersoronként külön videolapokat nyitunk, mindegyiken külön-külön
beállíthatunk más palettát, így látványos programokat lehet írni, hiszen a 256 színből van mit válogatni. Születtek is
ilyen játékok, a Bricky Prise és a Treasure Cave (by Geco), profi, gépi kódban
írt játékok. Engem pedig nem hagyott nyugodni a gondolat, hogy ha már kiderült,
hogy van ilyen karakteres-grafikus üzemmód, meg lehetne csinálni a Hamikát is
így és akár sok más játékot is. A Hamikát végül megcsináltam, ez lett az Entersnake,
erről már volt szó, ugyancsak az Enterpress 2019/3-4 számában.
Volt egyszer egy ismeretlen szerzőtől származó, fel-le scrollozó, karakteres képernyőn futó
basic játék, ahol egy labirintusból kellett kitalálni. A neten sehol nem
találtam, csak nekem volt meg, még anno egy cserepartnerem küldte. Előástam nagy
nehezen valahonnan a süllyesztőből ezt a játékot, de érdemben nem is
foglalkoztam vele. Inkább az ütött szöget a fejembe, hogy milyen érdekes ez a
függőleges scroll basicben, ilyet még máshol nem igazán láttam (kivéve Endi Mega Pac Man, Zzzippel lefordított játéka), pedig egészen egyszerű
megcsinálni, és ehhez négyszínű karakteres lapot is lehetne használni. Elég
nagy videolapot létre lehet hozni basicből, többszörösét annak, mint ami a
képernyőre egyszerre kifér, és könnyen, gyorsan lehet állítani, hogy ebből mi látsszon
éppen. Így egészen egyszerű megcsinálni, hogy egy függőlegesen scrollozó pályán
kóvályogjon az emberkénk. Az emberkének középen kell lennie, és mindig fölötte
és és alatta is kb. 10 karakternyit kell mutatni a képernyőből a DISPLAY
utasítás segítségével, akkor is, ha fel-le mozgunk. Ezen az egyszerű ötleten
felbuzdulva megcsináltam a Hamikának a scrollos változatát, amikoris a kígyóval
egy nagyobb pályán kell bolyonganunk, mint ami a képernyőn egyszerre látszik.
Pontosabban csak az első három pályát csináltam meg ebből, a többi még várat
magára, ez lenne majd az Entersnake 2.
Vissza a Pacmanhez!
2020 eleje felé valamiért nem nagyon hagyott nyugodni a dolog, hogy kéne egy olyan pacman játékot írni, ahol a szörnyek dinamikusan mozognak, és jó nagy a pálya, scrollozik fel-le. Érdekes volt belegondolni, hogy a szörnyek talán a labirintus másik felében lófrálnak, amit mi nem is látunk, majd egyszer csak odatévednek a képernyőbe. Fogtam hát a Dot Collector Turbo Edition-t és elkezdtem átalakítani. Az első talán az volt, hogy a videomódot átállítottam karakteresről karakteres-grafikus (4 színű) módra. Így a karakterek eléggé értékelhetetlenül néztek ki eleinte. A pályát vízszintesen kibővítettem egy kicsit a kijelzők alatt, és az egész pályát kb. 15 karakterrel lejjebb toltam. Utóbbira azért volt szükség, mert az emberke mindig függőlegesen a képernyő közepén van akkor is, ha a játéktér legtetejére megyünk, és még ilyenkor is látszik még kb. 10 karaktersornyi terület fölötte - ha pedig ott vége a videolapnak, nincs mit megjeleníteni, hibaüzenetet kapunk. Nagyon egyszerű megoldani, hogy függőlegesen mindig a játéktér közepén maradjon az emberke és fel-le mozgásnál scrollozzon a képernyő, egyszerűen csak minden fel-le mozgatásnál ki kell adni a DISPLAY AT 1 FROM X-10 TO X+10 utasítást, ahol X az emberke függőleges koordinátája.
2020 eleje felé valamiért nem nagyon hagyott nyugodni a dolog, hogy kéne egy olyan pacman játékot írni, ahol a szörnyek dinamikusan mozognak, és jó nagy a pálya, scrollozik fel-le. Érdekes volt belegondolni, hogy a szörnyek talán a labirintus másik felében lófrálnak, amit mi nem is látunk, majd egyszer csak odatévednek a képernyőbe. Fogtam hát a Dot Collector Turbo Edition-t és elkezdtem átalakítani. Az első talán az volt, hogy a videomódot átállítottam karakteresről karakteres-grafikus (4 színű) módra. Így a karakterek eléggé értékelhetetlenül néztek ki eleinte. A pályát vízszintesen kibővítettem egy kicsit a kijelzők alatt, és az egész pályát kb. 15 karakterrel lejjebb toltam. Utóbbira azért volt szükség, mert az emberke mindig függőlegesen a képernyő közepén van akkor is, ha a játéktér legtetejére megyünk, és még ilyenkor is látszik még kb. 10 karaktersornyi terület fölötte - ha pedig ott vége a videolapnak, nincs mit megjeleníteni, hibaüzenetet kapunk. Nagyon egyszerű megoldani, hogy függőlegesen mindig a játéktér közepén maradjon az emberke és fel-le mozgásnál scrollozzon a képernyő, egyszerűen csak minden fel-le mozgatásnál ki kell adni a DISPLAY AT 1 FROM X-10 TO X+10 utasítást, ahol X az emberke függőleges koordinátája.
A pálya tehát kb. 15 sorral lejjebb kezdődött (bár talán 10 is elég lett volna, de a túlbiztosításból gond sose lehet), így az
emberke függőleges startpozíciójához is 15-öt kellett hozzáadni. A szörnyekéhez
is ennyit kellett volna elméletileg, gyakorlatilag azonban SPOKE-kal lett
definiálva már korábban a startpozíciójuk, és emiatt valamiért automatikusan ők
is lejjebb kerültek, amikor a pályát lejjebb kezdtem kirajzoltatni a géppel. Sokáig agyaltam, miért nem jó, ha 15-öt hozzáadok az ő startpozíciójukhoz is, de az LPT-vel bűvészkedés nem hétköznapi embereknek való.
Tehát, a Dot Collector Turbo Editiont továbbfejlesztettem,
karakteres helyett grafikus-karakteres képernyőt kapott, scrollozósra
megcsináltam a pályát, és nagyobb pályát rajzoltam hozzá DATA sorokba, ahol
lefele tovább lehet menni. Ebből lett a Dots and Gems című játék. A játék a
nevét onnan kapta, hogy egyrészt bogyókat (dots) kell gyűjtenünk, másrészt a
Dot Collectorban varázstabletták szerepét betöltő karakterek itt most új szerepet
kaptak, drágakövek (Gems) lettek belőlük. A feladatunk most is az, hogy össze
kell gyűjtenünk 200 bogyót, de ezen kívül a drágaköveket is össze kell
gyűjtenünk mind. Az utóbbinál már egy kicsit elővigyázatosnak kell lenni. Ahogy
már előre utaltam rá a Dot Collector Turbo Edition-ben, a varázstabletták
kinyitnak egy kaput, így a pálya újabb részeibe is beléphetünk. A
varázstabletták energiánkat növelik, és ha elérjük a 4 egységnyi energiát, a
kapu kinyílik. Újabb varázstabletta felvételekor azonban a kapu becsukódik, még
újabb felvételekor kinyílik, és így tovább. Ha energiát vesztünk, akkor 4-nél
kevesebb lesz az energiánk, így a kaput már nem fogjuk tudni egyből kinyitni,
és ha nem jól taktikázunk, nem tudunk bejutni a kapu mögötti részbe. Az első
pályákon a kapu mögötti részen csak egy varázstabletta van, amit ha azonnal
felvennénk, ahogy a kapu kinyílt, a kapu bezáródna, és nem tudnánk visszajutni
a többi varázstablettát felvenni.
Először valamiért nehézkesnek tűnt megoldani, hogy a program
figyelje a bogyók és a drágakövek felvételekor is, hogy megvan-e a 200 bogyó és
az összes drágakő, hogy átmehessünk a következő szintre. Ehhez ki kellett volna
ugrani egy ciklusból, ami nem túl szép. Ezért azt találtam ki, hogy a
szörnyekkel való érintkezésnél nézze meg a program, hogy összeszedtünk-e már
mindent, és ha igen, akkor engedjen a következő szintre, hiszen a szörnyekkel
érintkezés és esetleges életvesztés amúgy is kiugrasztja a ciklusból a játékot.
Így hát úgy alakult, hogy miután mindent összeszedtünk, neki kell mennünk egy
szörnynek. Viszont a scrollozás miatt a kijelző, mely azt is jelzi,
összeszedtünk-e mindent, néha kikerült a képernyőről. Ezt a problémát már az
elején is láttam és tudtam, hogy ezzel csinálni kellene valamit, és a kijelzőt
máshol, a játéktéren kívül kellene elhelyezni a képernyőn. Végül azonban úgy
tűnt, érdekesebb úgy a játék, ha fel kell menni a játéktér tetejére, hogy
lássuk, összeszedtünk-e mindent és nyugodtan nekimehetünk a szörnynek.
Ferro73 az Entersnake fejlesztését is aktívan figyelemmel
kísérte, sőt több javaslattal, módosítással is hozzájárult a végleges
verzióhoz. Többek között rámutatott arra, hogy a Hungry Creature-ből átvett,
pontszámokat sorba rendezős részt egyszerűbben is meg lehet csinálni. Ugyanis a
pontszámok alapból is nagyság szerinti sorba vannak rendezve, nem kell az új
pontszám miatt az egészet újra sorba rendezni, csak az új pontszámnak
megkeresni a megfelelő helyet, és az alatta levő pontszámokat eggyel lejjebb
kell tolni. Arra is felhívta a figyelmem, hogy nem kell a nevet és pontszámot
tartalmazó sztringben az elejére tenni a pontszámot, mert a sztring adott
karakterétől nézve is sorba lehet rendezni a pontszámokat. Így a pontszámokat
sorba rendező rész egyszerűsödött:
3890 FOR X=9 TO 1 STEP-1
3900 IF VAL(N$(X)(12:15))>=SCO THEN 3940
3910 LET CS$=N$(X)
3920 LET N$(X)=N$(X+1)
3930 LET N$(X+1)=CS$
3940 NEXT X
3950 LET MINPONT=VAL(N$(9)(12:15))
CLOSE #103 ! sound: eszköz bezárása
OPEN #103:"gems.env" ACCESS OUTPUT
ENVELOPE NUMBER 1;........
CLOSE #103
OPEN #103:"sound:"
A játék, betöltés után beolvassa ezeket:
OPEN #106:"gems.env" ACCESS INPUT
COPY FROM #106 to #103
CLOSE #106
https://www.youtube.com/watch?v=H8Jna7vn0bY
Endi régebben megtervezte a nagybetűket és a számokat a négyszínű karakteres módhoz. Így tehát ilyen üzemmódban is lehet feliratokat kiírni a képernyőre, a betűk és számok mindössze négy pixel szélesek, ebből egy pixelnyi hely üres kell, hogy legyen, hogy a betűk ne folyjanak egybe. Endi gondoskodott arról is, hogy mind a három szín előforduljon egy karakteren belül esztétikusan. Ezeket a karaktereket már az Entersnake-ben is felhasználtam mindenféle szöveg kiírására. Ugyanezt a karakterkészletet használja a Dots and Gems is, erre feltétlen szükség is van, hiszen a kijelző a játéktérrel egy videolapon van, ahogy az a Dot Collectorban is volt eredetileg, ott pedig az eredeti, kétszínű karakterek krikszkrakszként jelennének meg.
A négyszínű módhoz való betűk és számok karakterdefiníciói sok helyet foglalnak el egy basic programban, így az egyébként is terjedelmes játékhoz azt találtuk ki már az Entersnake-nél közösen a fórumon, hogy elmentjük egy fájlba a karakterkészletet, amit a program egyszerűen visszatölt. Volt egy korábbi program, amely így töltötte be a karaktermátrixot:
1 ALLOCATE 92 CODE CHAR=HEX$("3E,01,01,80,04")3 CODE =HEX$("EB,F7,06,C9")4 LET FONT=(SPEEK(255,16372)+SPEEK(255,16373)*256)-11525 OPEN #1:"CHRSET.BIN" ACCESS INPUT6 CALL USR(CHAR,FONT)7 CLOSE #1
A játékban ez nem bizonyult működőképesnek. Hogy miért nem, annak az okát azóta is kutatjuk. Helyette a rafinált fórumtársak a következő módszert dolgozták ki a karaktermátrix betöltésére (assembly rajongók előnyben):
11 ALLOCATE 4012 CODE LDCHAR=HEX$("DB,B2,F5,3E,FF,D3,B2,2A")13 CODE =HEX$("F4,BF,3E,06,85,6F,5E,23")14 CODE =HEX$("56,06,07,CB,13,CB,12,10")15 CODE =HEX$("FA,CB,B2,01,80,04,3E,6A")16 CODE =HEX$("F7,06,F1,D3,B2,C9,00,00")…4850 OPEN #106:"GEMS.CHR" ACCESS INPUT4860 CALL USR(LDCHAR,0)4900 CLOSE #106
Felmerült, hogy a szűk folyosókon nehéz betalálni, hogy karakterre pontosan oda kell állni, hogy tovább tudjunk menni. Ez egyébként a Dot Collectorban is így volt még. Tomato77 (aki a Banana 1-2 szerzője) és ergoGnomik (aki gyakran ír hasznos, programozással kapcsolatos tanácsokat mindenkinek) fórumtársak javaslatai alapján megcsináltam, hogy ha egy karakterpozícióval arrébb van az emberkénk és úgy akarunk bemenni a kapun, akkor egy karaktert arrébb ugorjon, és menjen be. A módszer lényege, hogy ha nem tudunk menni az adott irányba, mert fal van ott, meg kell nézni a két szomszédos pozíciót is, hogy ott is fal van-e, és ha nem, akkor arra menni. A fórumtársakkal közösen sikerült ezt a részt úgy megírni, hogy ne legyen minden irány vizsgálatánál hatalmas terjedelmű programrész, hanem csak a lehetséges irányokat írja be egy-két változóba, és egy későbbi programrész megvizsgálja, hogy azokban az irányokban mi a helyzet, és aszerint mozgassa az emberkénket. Így sokkal játszhatóbb a játék, és ez a módszer jól fog jönni még esetleges későbbi pacman-típusú játékok írásakor.
A szörnymozgást 1995-ben a Hungry Creature-ben meglehetősen toldozott-foldozott módszerrel oldottam meg, a lényeg csak az volt, hogy működjön. (Lásd feljebb.) Szúrta a szemem, hogy az ahhoz képest szép színes, scrollozó játékban még mindig ez van. Többféleképpen is meg lehetett volna oldani más módszerrel ezt, végül Tomato77 ismertetett a fórumon egy frappáns módszert arra, hogyan vizsgálja meg a program, merre mozoghatnak a szörnyek, és milyen irányba menjenek. A MERRE() tömbben az 1 és -1 a vízszintes mozgást jelenti, a 34 és -34 pedig a függőlegest, mivel 34 karakter széles a játéktér:
NUMERIC MERRE(0 TO 3),LEHET(0 TO 3) MERRE(0)=-1:MERRE(1)=1:MERRE(2)=-34:MERRE(3)=34 ... LEHETDB=0 ! Ez mutatja, hány irány lehet ! Körbenézi négy irányból, ami jó, beteszi a LEHET tömbbe FOR J=0 TO 3 IF SPEEK(255,SZOR(A)+MERRE(J))<46 OR SPEEK(255,SZOR(A)+MERRE(J))=112 THEN LEHET(LEHETDB)=J ! Ide teszi, hogy mely irányok jók LEHETDB=LEHETDB+1 END IF NEXT J ! Itt már megvan, melyik irányokba mehet, válasszon ki egyet I(A)=MERRE(LEHET(RND(LEHETDB)))
Módszeremet lecseréltem az ő módszerére. A program ugyanazt csinálja, mint eddig, ugyanúgy működik, de mégis csak elegánsabb ez a módszer.
Ha felkerülünk a pontszámtáblára, a program elmenti az eredményünket. Belegondoltam, hogy magnós gépnél erre talán nincs szükség. Geco azt mondta, Spectrum és CPC átiratoknál a pontszámtábla csak akkor kerül elmentésre, ha lemezes a gép. Volt egy kis tanakodás, hogyan lehetne megvizsgálni, hogy lemezes vagy magnós-e a gép. Például, egy WHEN blokkon belül kiadunk egy EXDOS parancsot, és ha nincs EXDOS a gépben, az hibát okoz, a hibakezelő pedig megváltoztatja egy változó értékét - ez kicsit hosszadalmas. Végül Zozosoft mondta meg a tuti módszert:
ASK 3 XDOS
Az XDOS változó értékének függvényében tehát a gép eldönti, mentse-e a ponttáblát vagy ne.
A játék fut Enterprise 64-en is, de lassabban. Alapból a sebesség túl gyors lenne, ezért a játék állandóan meghív egy lassító ciklust. A megoldás, hogy 64-es gépen ez a ciklus kevesebbet lassítson, mint 128-on. Ehhez a programnak tudnia kell, milyen gépen fut. Ezt az IN(176) értékének segítségével ellenőrzi. Másik lehetőség lenne a VERNUM változó vizsgálata, mely a BASIC verziószámát tárolja (EP64-en 2.0, EP128-on 2.1). Azonban a Zzzip ezt nem szereti, mivel csak egész számokat kezel. Viszont ott van még a VER$ szöveges változó, amiben szintén benne van a BASIC verziószáma, a string részeként, és az is kiolvasható.
A játékba kerültek karakteres animációk. Nem csak a drágakövek villognak, hanem a bogyók is, és a szörnyek is változtatják kicsit az alakjukat. A vízszintes vonalakra is készítettem karakteres animációt. Ezeket nem a SET CHARACTER paranccsal írja át a program, hanem SPOKE-kal, az gyorsabb. Ehhez természetesen figyelembe veszi azt is, hogy 64-es vagy 128-as-e a gép (EXOS kompatíbilis), ami már nem is nehéz, mert a karaktermátrix betöltéséhez is szükség van ezekre a címekre. „Természetesen" sem a karakterek alakja, sem az LPT kezdőcíme nem ugyanott van 64-es és 128-as gépen.
Végezetül egy kis érdekesség: A szörnyekkel ütközéskor a program a LOST nevű eljárást hívja meg. Ha ezt akarjuk kilistázni, a LIST LOST parancsot kell kiadni. Ha az utolsó sort akarjuk a programból kilistázni, ahhoz a LIST LAST kell. Ha a LOST eljárás és az utolsó sor is kell: LIST LOST,LAST.

















