Az Entersprite animátor
File-név: Enterspr.COM Program neve: EnterSprite |
"a" Studio- 1985 Sprite-kezelő BASIC bővítés |
Amikor az ENTERPRISE "ellenségei" kifogásolták
a gép adottságait, akkor leginkább a hardverből támogatott spritekezelés hiányát
hangoztatták. Teljesen igazuk van, a gépben tényleg nincsenek beégetett sprite-ok
úgy, mint mondjuk a C64nél. Csakhogy...
Egy 128 KB-nyi RAM-mal rendelkező gépre olyan sprite kezelő készíthető, amilyen
csak tetszik! Ha a gép ráadásul olyan ügyesen kezeli a bővítéseket, mint az
ENTERPRISE, akkor tényleg semmi akadálya nincs a dolognak. Helyzetünket még
könnyebbé teszi, hogy az "a" Studio programozói már elkészítették
saját sprite-animátorukat, az "EnterSPRITE"-ot. A Basic bővítőként
inicializálódó program a sprite-ok kezelését, irányítását rendkívül leegyszerűsíti.
Az első ENTERPRISE programok egyike volt az EnterSPRITE, amely 8 sprite kezelését
támogatja Basic-ben 11 utasítással és 2 függvénnyel. Az $$REL fejlécű, felhasználói
áthelyezhető modulként inicializálódó programot eredetileg kazettán árusították,
de lemezről is elindul. Az animátor 8 sprite vezérlését végzi el a "háttérből".
Ráadásul egy sprite 8 fázisra tagolódik, így aztán még látványosabb és főleg
gyorsabb programokat írhatunk Basic-ben. Kár, hogy az animátor alatt megáll
az óra, ami játékprogramoknál igencsak gyakran használatos. A program az USER_ISR
mutatón "lóg", így saját rutinunkat ez elé, korrekt módon kell beillesztenünk.
A kezelendő sprite-okat egy másik programmal, a FINE
PEN-nel kell elkészíteni.
A Basic bővítő parancsai, függvényei a következők:
SLOAD <sorszám>, <$név> | |
sprite betöltése. A programban a sprite-okhoz egy-egy
sorszámot kell rendelni, ez alapján hivatkozhatunk rájuk, a <sorszám>
1 és 8 között lehet. A <$név> azt a nevet jelenti, amellyel a
sprite-ot a tervezés után rögzítettük. Természetesen itt megadható az
eszköznév, a meghajtó, és az elérési útvonal is.
Példa: SLOAD 4, "B:\SPRED\UMBRELLA.SPR" |
|
ANIMATE <sorszám>, [fázis_1], [fázis_2], ...[fázis_15]: | |
egy sprite-on belül az animáció során megjelenítendő
fázisok sorrendjének megadása. A fázisok tetszőleges sorrendben követhetik
egymást, megadásuk nem kötelező. A sprite tehát 8 fázist tartalmaz,
ezzel a paranccsal a fázisok megjelenési sorrendjét állíthatjuk be.
Ha az animátor az utolsóhoz ért, akkor elölről kezdi a fázisok kirakását.
Példa: ANIMATE 4,5,4,8,6,4,3,1,6 |
|
SPEEDAN <sorszám>, <sebesség> | |
az animáció sebességének megadása egy sprite-ra vonatkozóan.
A értékét egy 0-tól 255-ig terjedő számmal adhatjuk meg. A leggyorsabb
mozgást az 1-es érték adja, a 0 gyakorlatilag leállítja az animációt.
Figyelembe kell venni, hogy az animáció sebessége erősen függ a betöltött
sprite-ok számától.
Példa: SPEEDAN 4,10 |
|
ANIMON <sorszám> | |
elindítja az adott sprite animációját. Példa: ANIMON 4 |
|
ANIMOFF <sorszám> | |
leállítja az adott sprite animációját. Példa: ANIMOFF 4 |
|
DIRECTION <sorszám> ,<$irány> | |
az adott sprite mozgásirányának megadása. A mozgás 8 irányba történhet, az <$irány> az égtájak angol neveinek kezdőbetűjét jelenti:
Példa: DIRECTION 4,"NE" |
|
SPEEDSPR <sorszám>, <sebesség> | |
egy sprite sebességének megadása a mozgáshoz. A értéke
itt is egy 0 és 255 közötti szám, az 1-es eredményezi a leglassabb mozgást,
0-ra megáll a sprite.
Példa: SPEEDSPR 4,5 |
|
POSITION <sorszám>, <xpos>, <ypos> | |
adott sprite adott pozícióra helyezése. A képernyő bal
felső sarka az origó. A paraméterek lehetséges értékei: 0<=xpos<=71,
0 < =ypos < =147.
Példa: POSITION 4,71,147 |
|
SPRON <sorszám> | |
adott sprite láthatóvá tétele. A parancs kiadása után a
beállított jellemzőknek megfelelően megjelenik a sprite. Példa: SPRON 4 |
|
SPROFF <sorszám> | |
adott sprite eltüntetése. Példa: SPROFF 4 |
|
INIT | |
inicializálja a kezelőt (kiiktatja a megszakítási rutinját). Példa: INIT |
|
XPOS(<sorszám>) | |
visszaadja az adott sprite X irányú pozícióját. A
visszaadott érték illeszkedik a POSITION parancsnál közölt tartományhoz.
Példa: X4=XPOS(4) |
|
YPOS(<sorszám>) | |
visszaadja az adott sprite Y irányú pozícióját. A
visszaadott érték illeszkedik a POSITION parancsnál közölt tartományhoz.
Példa: Y4=YPOS(4) |
Az
EnterSPRITE inicializációja után elsőként az előzőleg már megtervezett sprite-okat
kell betölteni (SLOAD). A sprite paraméterek (ANIMATE, SPEEDAN, ANIMON, DIRECTION,
SPEEDSPR, POSITION) beállítását követően a GRAPHICS HIRES 16 parancs kiadása,
majd a sprite-ok bekapcsolása (SPRON) következik. Ha a kezelőt ki akarjuk
kapcsolni, akkor adjuk ki az INIT parancsot, és minden más "sprite-független"
műveletet csak ezután végezzünk el.
Szerencsés lett volna egy sprite definiáló utasítást is beépíteni a parancsok
közé. Valószínűleg a fejlesztők azért nem tették meg ezt, mert a színek kezelése
a felhasználó szempontjából nehézkes lett volna (a sprite-ot alkotó összes
pontról meg kellene mondani, hogy milyen színű legyen). Ilyen formán viszont
az sprite animátor a FINE PEN nélkül nem használható. (Ügyes árukapcsolás!)
Az EnterSPRITE tehát csak a GRAPHICS HIRES 16 parancs hatására keletkező képernyőn
működik helyesen. Sajnos hiába definiáljuk át a 101-es csatornát más méretűre,
a program ezt nem képes lekezelni, marad hát a 40*20-as méret. A két-, négy-,
kétszázötvenhat-színű képernyőkön pedig szemetet jelenít meg. Érdekes látvány
az is, amikor bekapcsolt kezelő mellett 80 karakteres szöveges képernyőre
váltunk át, ahol a szövegeken időnként "szöszmöszök" úsznak át.
A parancsoknál is tapasztalható némi inkorrektség. Az INIT például nem állítja
alaphelyzetbe a sprite változókat, csupán a megszakítási rutint iktatja ki.
Az INIT-nek ez a hiányossága előnynek is felfogható, hiszen ha egyszer beállítottuk
a sprite-okat, majd valamilyen okból kikapcsoljuk a kezelőt, akkor a fáradságos
munkával beállított paraméterek megőrződnek. Nagyobb baj a felhasználói megszakítási
rutinnal való "garázdálkodása": ha valaki a Basic programja mellett
még saját IT rutint is szeretne használni, akkor először le kell kezelnie
az EnterSPRITE rutinját. Nem kellően átgondolt a sebességértékek jelentése
sem: a SPEEDAN-nél az 1-es érték a leggyorsabb, ugyanez a SPEEDSPR-nél a leglassabb
mozgást eredményezi. A POSITION az x és y pozíciónak a valóságban 16 bites
értékeket vesz át, csak az MSB-t nem veszi figyelembe. Így aztán origónak
a 256 többszörösei is megfelelnek. A POSITION ,65351,65427 hatására például
a jobb alsó sarokba áll be a sprite.
A FINE_PEN ismertetésénél már említettem, hogy az EnterSPRITE működése közben
megáll az óra. Hiába adjuk ki később az INIT parancsot, az óra ekkor sem indul
el, a TIME$ konstans értéket szolgáltat! Mivel az EnterSPRITE-ot leginkább
játékprogramok "alá" készítették, az ilyen programokban pedig gyakran
van szükség az idő mérésére, az óra kikapcsolása súlyos hibája az EnterSPRITE-nak.
Az animátor nem kellően intelligens, csak meglehetősen egyedi környezetben
működik. Célszerűbb lett volna rendszerbővítőként, vagy perifériakezelőként
megírni, így sokkal univerzálisabban lehetne használni. Jó lenne, ha a kezelő
a főprogramtól teljesen függetlenül figyelne bizonyos előre beállítható eseményeket
(pl. sprite ütközés), és azt az esemény bekövetkezésekor szoftver interrupton
keresztül értesítené. Hiányzik a sprite prioritás beállíthatósága is.
A program kezelésének megértését megkönnyíti, ha a mellékelt BASIC bemutató
programot (DEMO.BAS) áttanulmányozzuk, valamint érdemes kísérletezni a mellékelt
sprite-okkal is (SPR kiterjesztésű file-ok).
Már ismerjük a sprite tervezés menetét, a sprite-kezelő lehetőségeit,
nincs más hátra, minthogy egy példaprogramot lássunk. A program 110-es és
120-as soraiban történik a sprite-ok betöltése. Ide tehát azokat a sprite
neveket kell beírnunk, amelyeken rögzítettük azokat. Fontos tudnivaló, hogy
elég csak egyszer betöltenünk a sprite-okat, azok a RUN vagy a START, de még
a meleg reset hatására sem törlődnek. Tehát ha betöltöttük a sprite-okat,
akkor a SLOAD utasításokat tartalmazó sorok elé nyugodtan kitehetjük a felkiáltójelet
(REM).
A program semmi különlegeset nem csinál. A betöltést követben beállítja a
sprite környezetet, bekapcsolja a HIRES 16 típusú képernyőt. Ekkor egy mozgó
és egy időnként a mozgóra ugró sprite-ot láthatunk. A program egyébként azt
akarja demonstrálni, hogy az ugráló sprite miért nem ugrik minden olyan esetben,
amikor kellene neki.
Az álldogáló sprite akkor ugrik (ugrana) a másik sprite-ra, amikor X vagy
Y pozíciójuk megegyezik. A program elindítását követben azonban azt tapasztaljuk,
hogy jónéhány ilyen esetben nem történik semmi, az álló sprite nem hajlandó
az ugrásra.
Mi lehet ennek az oka? A magyarázat egyszerű: a Basic programunk alatt futó
sprite-kezelő sokkal gyorsabb, mint a főprogram. Így hiába egyezik meg a két
sprite X vagy Y pozíciója, a Basic program ezt nem veszi észre, mert a pozícióegyezés
pillanatában éppen mással foglalkozik. A program jól példázza két, aszinkron
módon futó program nehéz összehangolhatóságát. A sprite-kezelőt beállítjuk,
a sprite-okat elindítjuk, és igazából már el is veszítettük felettük az uralmunkat,
az animátor csak fut, és fut... A példában csak két sprite-ot kezelünk, és
már egy egyszerű pozícióegyeztetés is komoly problémákat okoz. Ha a sprite-ok
ütközését szeretnénk figyelni, akkor még ennél is több bajunk lenne, hiszen
ott több irányból kellene pozíciótartományokat figyelnünk. És mi történne,
ha mind a nyolc sprite-ot egyszerre akarnánk kezelni...?
100 PROGRAM "SPRMINTA.BAS"
110 SLOAD 5,"SPR1"
120 SLOAD 6,"SPR2"
130 INIT :RANDOMIZE :SET 26,1
140 STRING EX$(0 TO 3)
150 LET EX$(0)="ne":LET EX$(1)="nw"
160 LET EX$(2)="se":LET EX$(3)="sw"
170 REM 5.sprite
180 ANIMATE 5,1,3,5,7:SPEEDAN 5,9
190 POSITION 5,36,72:SPEEDSPR 5,0
200 REM 6.sprite
210 ANIMATE 6,2,4,6,8:SPEEDAN 6,10
220 POSITION 6,71,0:SPEEDSPR 6,1
230 DIRECTION 6,"ne"
240 REM start
250 GRAPHICS HIRES 16
260 SET £102:SCROLL ON
270 ANIMON 5:ANIMON 6
280 SPRON 5:SPRON 6
290 WHEN EXCEPTION USE BUMMM
300 DO
310 IF XPOS(5)=XPOS(6) THEN CAUSE EXCEPTION 100
320 IF YPOS(5)=YPOS(6) THEN CAUSE EXCEPTION 100
330 LOOP
340 END WHEN
350 HANDLER BUMMM
360 IF EXTYPE=9229 THEN
370 INIT
380 END
390 END IF
400 IF EXTYPE=100 THEN
410 POSITION 5,XPOS(6),YPOS(6)
420 DIRECTION 6,EX$(RND(4))
430 RETRY
440 END IF
450 END HANDLER