40. Hráči a strely: Player/Missile grafika

Rozšírenie action26; programy začínajú riadkom ;@modern (kapitola 35).

Na čo to je

Pohyblivé postavičky v hrách na Atari väčšinou nie sú nakreslené do obrázka. Kreslí ich zvlášť obvod GTIA navrch obrazovky – hráči (players) a strely (missiles). Atari ich má osem:

Hráč sa hýbe bez toho, aby pokazil obrázok pod sebou, a počítač sám povie, či do niečoho narazil (kapitola 41). Tomu, čo sa takto kreslí, sa hovorí Player/Missile grafika, skrátene PMG.

V pôvodnom Action! sa PMG robí zápismi do registrov (PMBASE, SDMCTL, GRACTL, HPOSP0 …) a treba vedieť, kde a ako zarovnať pamäť – ukážka examples/pmg.act. Action26 má na to rutiny, ktoré sa volajú rovnako ako v Action! Tool Kite.

Program 1: loď cez obrazovku

Súbor examples/pm-ship.act:

Action!
;@modern
; A ship that flies across the screen: player 0

BYTE ARRAY ship=[$18 $3C $7E $FF $DB $FF $24 $42]

PROC Main()
  BYTE x, y=[120]

  PrintE("A ship made of player 0")
  PMGraphics(1)                       ; players on, one line per byte
  PMCreate(0, ship, 8, 1, 48, y)      ; player 0: 8 rows, width 1, x=48
  PMColor(0, 1, 10)                   ; yellow
  Print("Its shape lives at ")
  PrintCE(PMAdr(0)+y)

  FOR x=48 TO 200
  DO
    PMWait()                          ; one step per frame
    IF x&16 THEN y==+1 ELSE y==-1 FI  ; up and down in steps of 16
    PMMove(0, x, y)
  OD

  Print("The ship stopped at x=")
  PrintB(PMX(0))
  Print(", y=")
  PrintBE(PMY(0))
RETURN

Preklad a spustenie

action26 pm-ship.act --run

V emulátore preletí žltá loď cik-cak zľava doprava (asi 3 sekundy) a program skončí. Simulátor hráčov nevidí, ale program v ňom prebehne a vypíše:

action26 pm-ship.act --sim
A ship made of player 0
Its shape lives at 11384
The ship stopped at x=200, y=127

Ako to funguje

Tvar je pole bajtov, jeden bajt na riadok. Bit s hodnotou 1 je bod hráča, 0 je priehľadné miesto. Loď vyzerá takto ($18 = 00011000):

$18  ...XX...
$3C  ..XXXX..
$7E  .XXXXXX.
$FF  XXXXXXXX
$DB  XX.XX.XX
$FF  XXXXXXXX
$24  ..X..X..
$42  .X....X.
RutinaČo robí
PMGraphics(1)zapne hráčov a strely; 1 = jeden riadok obrazovky na bajt, 2 = dva riadky (bajt je dvakrát vyšší), 3 = ako 2, ale y v riadkoch obrazovky, 0 = vypne
PMCreate(n, tvar, riadky, šírka, x, y)nakreslí tvar do hráča n (0–3) alebo strely (4–7): riadky = počet bajtov tvaru, šírka 1, 2 alebo 4
PMColor(n, odtieň, jas)farba hráča – rovnako ako SetColor (kapitola 27)
PMMove(n, x, y)presunie objekt na nové miesto
PMWait()počká, kým sa nakreslí ďalší obraz (50 alebo 60-krát za sekundu)
PMX(n), PMY(n)funkcie – kde objekt je
PMAdr(n)funkcia – adresa pamäte hráča n

Súradnice sú tie, ktoré pozná hardvér, nie body obrazovky:

RozsahViditeľné
x0–255asi 48–200 (hráč šírky 1); 48 je ľavý okraj textu
y pri PMGraphics(1) a (3)0–255asi 32–223; riadok textu r začína na 32 + 8*r
y pri PMGraphics(2)0–127asi 16–111

Mimo viditeľnej časti je objekt jednoducho skrytý – tak sa dá aj „schovať“.

Prečo PMWait. Obraz sa kreslí 50-krát za sekundu (v Amerike 60). Bez čakania by slučka prebehla celú obrazovku skôr, než by sa stihla ukázať.

Pamäť. Tvary hráčov číta obrazový čip z pamäte, ktorá musí začínať na násobku 2 KB (pri PMGraphics(2) a (3) 1 KB). Prekladač ju vyhradí sám za koniec programu – PMAdr(0) ukáže, kde je. --memory-map ju vypíše ako PMG. Kto ju chce mať inde (napr. v banke, kapitola 42), povie to pred PMGraphics rutinou PMMemory(pole).

Koniec programu hráčov vypne sám – aj keď program skončí chybou alebo klávesom RESET. Inak by loď ostala svietiť na obrazovke DOS-u.

Program 2: vták mávajúci krídlami

Súbor examples/pm-bird.act:

Action!
;@modern
; A bird that flaps its wings and glides down: PMShape and mode 3

BYTE ARRAY bird=[$81 $C3 $E7 $7E $3C $18 $00 $00  ; wings up
                 $00 $18 $3C $7E $E7 $C3 $81 $00] ; wings down

PROC Main()
  BYTE frame

  PMGraphics(3)                       ; two lines per byte, y in lines
  PMCreate(0, bird, 8, 2, 100, 40)    ; double width
  PMColor(0, 15, 10)                  ; orange

  FOR frame=0 TO 119
  DO
    PMWait()
    IF (frame&7)=0 THEN               ; another picture every 8 frames
      PMShape(0, bird+(frame&8), 8)
    FI
    PMVPos(0, 40+frame)               ; one line down every frame
  OD

  Print("The bird landed on line ")
  PrintBE(PMY(0))
RETURN
action26 pm-bird.act --sim
The bird landed on line 159

Ako to funguje

Ďalšie rutiny

RutinaČo robí
PMWidth(n, w)šírka 1, 2 alebo 4
PMClear(n)zmaže objekt (strela len svoje 2 body)
PMPriority(p)kto je vpredu: 1 hráči nad všetkým, 4 obrázok nad hráčmi; +16 štyri strely ako piaty hráč, +32 viacfarebné hráče
PMMemory(pole)vlastné miesto pre pamäť hráčov
PMGraphics(0)vypne hráčov a strely

Mená čísel. Súbor examples/modern/HARDWARE.ACT (INCLUDE) má pre ne mená: PM_SINGLE, PM_DOUBLE, PM_WIDE, PRI_PLAYFIELD …

Graphics nechá hráčov zapnutých. Obrazový režim sa dá zmeniť aj počas hry; hráči ostanú na mieste.

Program si hráčov kreslí aj sám. Do pamäte z PMAdr(n) sa dá zapisovať ako do poľa (BYTE POINTER). Objekt, ktorý nemá tvar z PMCreate, sa potom pri PMMove posúva tak, že sa celý pás pootočí (ako v Tool Kite) – pomalšie, ale funguje.

Na čo si dať pozor

Časté chyby

Čo sa staloČo sa stane
program bez ;@modernerror ACT008: undeclared name 'PMGraphics'
PMMemory s poľom, ktoré nezačína na celej stránke ($xx00)Err: 107
PMMemory s poľom, ktoré nie je na násobku 2 KB (1 KB pri PMGraphics(2))Err: 107 pri PMGraphics
hráč „zmizne“x alebo y mimo viditeľnej časti, alebo chýba PMColor (farba 0 = čierna)
loď preletí obrazovku hneďchýba PMWait() v slučke

Vyskúšaj si

  1. Ovládaj loď joystickom: v slučke s=Stick(0) a podľa bitov zmeň x a y (kapitola 29). Hotové je to v examples/modern/players.act.
  2. Zmeň v prvom programe PMGraphics(1) na PMGraphics(2) a y=[120] na y=[60]. Ako sa zmenil tvar lode?
  3. Daj vtákovi tretí obrázok (krídla rovno) a striedaj tri.

Zhrnutie

Podrobnejšie: lekcia 4 examples/modern/players.act, opis všetkých rutín v docs/runtime.md.

Späť: 39. Dáta zo súboru a kompresia · Ďalej: 41. Zrážky