41. Zrážky
Rozšírenie action26; programy začínajú riadkom ;@modern (kapitola 35). Nadväzuje na kapitolu 40.
Na čo to je
Hra potrebuje vedieť, či strela trafila, či loď narazila do steny alebo do nepriateľa. Atari to vie samo: obvod GTIA si pri kreslení každého obrazu zapisuje, ktorý hráč alebo strela sa prekryl s ktorým hráčom a s ktorou farbou obrázka. Program tieto zrážky (collisions) len prečíta.
Druhá možnosť je spočítať zrážku v programe z polôh a rozmerov objektov. Obe majú svoje výhody – tento program ukazuje obe naraz.
Program: kameň padá na loď
Súbor examples/pm-hit.act:
;@modern
; A rock falls on a ship: a collision from the hardware and from PMOverlap
BYTE ARRAY ship=[$18 $3C $7E $FF $FF $DB $81 $81],
rock=[$3C $7E $FF $FF $FF $FF $7E $3C]
PROC Main()
BYTE y, hw=[0], sw=[0]
PMGraphics(1)
PMCreate(0, ship, 8, 1, 120, 180) ; the ship at the bottom
PMCreate(1, rock, 8, 1, 120, 100) ; the rock above it
PMColor(0, 1, 12)
PMColor(1, 2, 6)
PMWait()
HitClr()
FOR y=101 TO 190
DO
PMWait() ; the rock at y-1 is on the screen now
IF hw=0 AND PMHitPM(1)&1 THEN ; player 1 met player 0
hw=y-1
FI
HitClr()
PMVPos(1, y) ; the rock one row lower
IF sw=0 AND PMOverlap(0, 1) THEN ; the rectangles overlap at once
sw=y
FI
OD
Print("PMOverlap: the rock hit the ship at y=")
PrintBE(sw)
Print("Hardware: the rock hit the ship at y=")
PrintBE(hw)
RETURNPreklad a spustenie
action26 pm-hit.act --simPMOverlap: the rock hit the ship at y=173
Hardware: the rock hit the ship at y=0Simulátor nemá obvod GTIA, preto hardvér v ňom zrážku nehlási (0). V emulátore (--run) vypíše program oba riadky s y=173: kameň v riadkoch 173–180 sa dotkne lode v riadku 180.
Ako to funguje
Zrážky z hardvéru:
| Rutina | Vráti |
|---|---|
PMHitPM(n) | bity 0–3: s ktorými hráčmi sa objekt n zrazil (bit 0 = hráč 0, hodnota 1; bit 1 = hráč 1, hodnota 2 …) |
PMHitPF(n) | bity 0–3: s ktorými farbami obrázka (playfield 0–3) sa objekt n zrazil |
PMHit(n, c) | 1 alebo 0: c 0–3 je hráč, 4–7 farba obrázka 0–3 (ako v Tool Kite) |
HitClr() | všetky zrážky vynuluje |
PMHitPM(1)&1 je teda „hráč 1 narazil do hráča 0“. Rovnako by platilo PMHitPM(0)&2 – zrážku hráčov hlási hardvér u oboch.
Dve pravidlá hardvérových zrážok:
- Bity sa len pridávajú. Raz nastavený bit ostane, kým program nezavolá
HitClr(). Bez neho by jeden náraz platil navždy. - Zrážka sa zistí až pri kreslení. Hneď po
PMVPosregistre ešte hovoria o starej polohe. Preto slučka robí vždy to isté: počkaj na obraz (PMWait) → prečítaj →HitClr→ pohni. Program si preto pamätáy-1– zrážku našiel obraz, v ktorom bol kameň ešte o riadok vyššie.
Zrážka z programu: PMOverlap(a, b) vráti 1, keď sa prekrývajú obdĺžniky dvoch objektov (poloha, šírka a počet riadkov tvaru, ktoré si runtime pamätá). Funguje hneď po pohybe, aj pre neviditeľný objekt a aj pre dve strely (hardvér zrážku strely so strelou nepozná). Je to však len obdĺžnik: prázdne rohy tvaru sa rátajú tiež. Hardvér naopak hlási len skutočne nakreslené body.
Zrážky s obrázkom a strely
PMHitPF(n) hlási, do ktorej farby obrázka objekt narazil. Pozor na textový režim: písmená v GRAPHICS 0 sa hlásia ako farba 2 (hodnota 4), hoci ich farbu nastavuje SetColor(1, …):
IF PMHitPF(4)&4 THEN ; strela 0 (objekt 4) narazila do textu
PMClear(4)
FIStrely sú objekty 4–7. Tvar strely sú dva spodné bity každého bajtu ([1 1 1] – úzka, [3 3 3] – široká) a strela má farbu svojho hráča:
BYTE ARRAY shot=[1 1 1 1]
PMCreate(4, shot, 4, 1, x+3, 170) ; strela 0 z lode
PMVPos(4, sy) ; letí hore
IF PMHitPM(4)&2 THEN … ; strela 0 trafila hráča 1
Celá hra so strelou, textom a životmi je lekcia examples/modern/collide.act.
Na čo si dať pozor
- Zrážka strely so strelou neexistuje – na to je
PMOverlap. - Hráč s farbou rovnakou ako pozadie sa stále zráža (kolízia nepozerá na farbu, len na body).
- Pri piatom hráčovi (
PMPriority(1+16)) sa strely stále hlásia ako strely. - V simulátore (
--sim) sú zrážky z hardvéru vždy nesprávne alebo nulové – skúšaj ich v emulátore.
Časté chyby
| Čo sa stalo | Prečo |
|---|---|
| zrážka platí stále, aj keď sa objekty už rozišli | chýba HitClr() |
| zrážka sa nezistí, hoci sa objekty prekrývajú | čítaš hneď po pohybe, nie po PMWait() |
zrážka s textom sa nehlási pri PMHitPF(n)&2 | text v GRAPHICS 0 je farba 2: &4 |
PMOverlap hlási zrážku o kúsok skôr | ráta obdĺžniky, nie body |
Vyskúšaj si
- Posuň kameň v programe na
x=126(len dva stĺpce nad pravým okrajom lode). Kedy nahlási zrážkuPMOverlapa kedy hardvér? - Daj lodi strelu:
PMCreate(4, shot, 4, 1, 123, 175)a v slučke ju posúvaj hore. Kedy ju zastavíPMHitPM(4)&2? - Vypíš na obrazovku riadok textu a nechaj kameň padať cez neho. Zistí to
PMHitPF(1)?
Zhrnutie
PMHitPM,PMHitPF,PMHitčítajú zrážky z hardvéru,HitClrich vynuluje.- Poradie v slučke:
PMWait→ čítaj →HitClr→ pohni. - Text v
GRAPHICS 0je farba obrázka 2 (bit s hodnotou 4). PMOverlapporovná obdĺžniky hneď, aj pre strely a skryté objekty.
Podrobnejšie: lekcia 46 examples/modern/collide.act, ukážka examples/pmgM.act.
Späť: 40. Hráči a strely · Ďalej: 42. Viac objektov, banky a menu