Ako naprogramovať shmup pre Apple Watch

Návod na shmup pre Apple Watch: virtuálne rozlíšenie, ovládanie korunkou, kolízie obdĺžnikmi, pooling, levely ako tabuľka časov a generátor vĺn.

Pixelová scéna na zelenom displeji: loď vľavo strieľa na kométy, rakety a bossa vpravo

Shmup (shoot 'em up, strieľačka, v ktorej loď letí proti vlnám nepriateľov) na Apple Watch naráža na tri veci: malý displej, prst, ktorý zakryje polovicu hry, a rôzne veľkosti hodiniek. Riešia sa tromi rozhodnutiami: celá hra beží v pevnej mriežke 84 × 48 bodov, kolízie sa počítajú ručne obdĺžnikmi a levely sú tabuľky s časmi, nie kód. Loď sa ovláda korunkou Digital Crown a strieľa sama.

Postup ukazujeme na hre Space Impact Watch, remaku strieľačky Space Impact z telefónu Nokia 3310 z roku 2000, ktorá beží na hodinkách aj na iPhone a iPade. Príklady sú zo SpriteKitu, 2D herného frameworku od Apple, ale princípy platia pre každý shmup na malú obrazovku.

Pevné virtuálne rozlíšenie 84 × 48

Najprv sa rozhodnite, v akých jednotkách bude hra počítať. Ak použijete body obrazovky, svet bude na každej veľkosti hodiniek inak veľký. Lepšie je zvoliť malé virtuálne rozlíšenie a všetko počítať v ňom. V našej hre je to 84 × 48, presne ako mal displej Nokie 3310. Pozície, rýchlosti, veľkosti spritov aj dráhy nepriateľov sú v týchto jednotkách. Pri štarte scény sa raz vypočíta, koľko bodov obrazovky má jeden virtuálny pixel (šírka scény deleno 84), a všetko sa ním len vynásobí.

Herná scéna s viditeľnou mriežkou 84 × 48 virtuálnych pixelov
Level na mriežke 84 × 48. Každý štvorček je jeden virtuálny pixel, hodinky ho vykreslia ako blok niekoľkých skutočných bodov.

Čo tým získate:

  • Rovnaký vzhľad na každom zariadení. Hra vyzerá rovnako na každej veľkosti hodiniek aj na iPade, mení sa len veľkosť bloku.
  • Level dizajn v malých celých číslach. Nepriateľ letí vo výške 13, raketa zatáča v bode x = 20.
  • Jednoduchú grafiku. Sprity sú jednofarebné a kreslené v desaťnásobnej veľkosti, jeden virtuálny pixel je v zdrojovom obrázku blok 10 × 10. Farbu dostanú až v hre. Na svetlých leveloch sú čierne na zelenom pozadí, na tmavých sa to otočí.

Ovládanie korunkou a automatická streľba

Na hodinkách prst zakryje polovicu hry, preto sa loď neovláda dotykom. Pohyb rieši Digital Crown: otočenie korunky posunie loď hore alebo dole. Pridajte nastavenie citlivosti a možnosť otočiť smer.

Streľba je automatická, v našej hre každých 0,4 sekundy, od štvrtého levelu každých 0,3. Displej slúži len na jedno gesto: potiahnutím doprava hráč použije jednu z troch špeciálnych zbraní.

Tri špeciálne zbrane: zvislá čiara, navádzaná raketa a laser zasahujúci bossa
Tri špeciálne zbrane: čiara, ktorá prejde celou výškou plochy, navádzaná raketa a laser.

Na hodinkách je vibrácia pri zásahu rovnako dôležitá ako animácia, malý výbuch na displeji si hráč ľahko nevšimne. Haptiku volajte cez jedno rozhranie (zásah, smrť nepriateľa, porazený boss), ktoré každá platforma vykoná po svojom: hodinky vibráciou, iPhone vlastným spôsobom. Verzia pre telefón nemá korunku, namiesto nej má tlačidlá na displeji, ktoré používajú rovnaké nastavenie citlivosti aj smeru.

Screenshot hry v simulátore Apple Watch, loď proti bossovi
Hra v simulátore Apple Watch: loď proti bossovi.

Herná slučka v jednej scéne

Celá hra môže byť jedna scéna s jednou slučkou:

každý snímok:
    posuň všetky objekty
    skontroluj kolízie
    podľa času v leveli pridaj nových nepriateľov

Veci pridávajte v poradí, v ktorom sa dajú čo najskôr testovať:

  • Streľba a pohyb hráča. Bez nich sa nedá nič otestovať.
  • Nepriatelia a kolízie. Prvému nepriateľovi stačí letieť rovno doľava a zomrieť po jednom zásahu.
  • Vibrácie a animácie zásahu. Na malom displeji bez nich hráč nevie, že zasiahol.
  • Pozadie a HUD. Životy, skóre, počet špeciálnych zbraní. Ak HUD na niektorom leveli prekáža, presuňte ho dole.

Na konci máte hrateľnú slučku so životmi, skóre, výbuchmi, pozadím a respawnom hráča. Ak hernú logiku držíte oddelene od vykresľovania a vstupu, môžu ju zdieľať verzie pre hodinky aj telefón.

Kolízie obdĺžnikmi namiesto fyzikálneho enginu

SpriteKit má fyzikálny engine a ponúka sa použiť ho aj na kolízie. Každý objekt dostane fyzikálne telo vytvorené z obrysu spritu, presnú detekciu kolízií a kategóriu (hráč, nepriateľ, strela, špeciálna zbraň) a engine sám hlási dvojice, ktoré sa dotkli. Apple v dokumentácii k fyzikálnym telám uvádza, že telá z alfa kanála textúry sú najpresnejšie a zároveň výpočtovo najdrahšie. V našej hre sme to skúsili a vrátili sme sa k ručnej kontrole.

Ručná kontrola je jedna funkcia, ktorá po sebe prejde dvojice skupín a porovná obdĺžniky:

pre každú dvojicu skupín:
    (hráč a nepriatelia, hráč a strely, strely a nepriatelia, strely a strely)
    pre každý objekt A z prvej skupiny a objekt B z druhej:
        ak sa obdĺžnik A prekrýva s obdĺžnikom B:
            vyrieš zásah
Dve dvojice spritov s vyznačenými obdĺžnikmi kolízie, vľavo sa prekrývajú len rohy obdĺžnikov
Vľavo: obdĺžniky sa prekrývajú, pixely nie, hra to počíta ako zásah. Vpravo: skutočný zásah.

Výhody: poradie kontrol máte pod kontrolou a celé pravidlo „čo sa stane pri zásahu“ je na jednom mieste. Nepresnosť je malá, lebo na mriežke 84 × 48 sú sprity také drobné, že obdĺžnik a skutočný obrys sa líšia len o pár virtuálnych pixelov.

Pooling len tam, kde sa oplatí

Pooling znamená, že objekt po zániku nezmažete, len ho skryjete a nabudúce použijete znova. Je lákavé poolovať všetko vrátane výbuchov a power-upov. Má to však cenu: každá kolízia a každý update musí najprv overiť, či je objekt vôbec živý. Stačí jedna zabudnutá kontrola a skrytý nepriateľ zabije hráča alebo skrytá strela zostrelí raketu. Keď sme v našej hre pooling zo všetkého odstraňovali, mazali sme hlavne tieto kontroly.

Jednoduché pravidlo: poolujte to, čoho je veľa a vzniká to stále rovnako. Hráč si pri štarte vytvorí 21 striel a potom ich len recykluje. Nepriatelia a ich strely sa tiež znovu používajú, výbuchy a power-upy vznikajú a zanikajú normálne.

Levely ako tabuľka časov

Level nemusí byť kód, stačí zoznam záznamov. Každý záznam hovorí, čo sa objaví, v ktorej sekunde, v akej výške a ako sa pohybuje. Pohyb je zoznam bodov, cez ktoré nepriateľ letí rovnakou rýchlosťou. Voliteľne pribudnú časy výstrelov, výpad bossa alebo generátor menších nepriateľov.

každý snímok:
    čas = teraz - začiatok levelu - čas v pauze
    pre každý záznam v tabuľke levelu:
        ak záznam ešte nebol použitý a čas > záznam.čas:
            vytvor objekt podľa záznamu
            označ záznam ako použitý
Časová os prvého levelu: zľava doprava sekundy, výška ikon zodpovedá výške, v ktorej sa nepriateľ objaví
Prvý level: 39 záznamov za 67 sekúnd. Kométy, potom vlny rakiet, power-upy (červené) a na konci boss.

Takto zapísaný level sa ľahko ladí: posunúť vlnu o pol sekundy znamená zmeniť jedno číslo. Na časovej osi je vidno aj rytmus, o ktorý ide: krátka vlna, pauza, iný typ nepriateľa, power-up pred ťažším úsekom.

Raketa letiaca cik-cak cez hernú plochu, body zlomu dráhy sú vyznačené
Dráha rakety z prvého levelu: šesť bodov, cez ktoré letí rovnakou rýchlosťou.

Nevýhodu cítiť pri väčších zmenách. Najhustejší level našej hry má 71 riadkov a taká tabuľka sa bez editora číta zle. Výhodnejšie je zapisovať levely ako vlny (skupina nepriateľov s jedným vzorom pohybu), nie ako jednotlivé lode.

Nekonečný režim z jedného pseudonáhodného čísla

Pre rebríček (v našej hre Game Center) potrebujete režim, ktorý nekončí. Ručne písanú tabuľku v ňom nahradí generátor, ktorý ju vyrába za behu. Vyrobí 20-ciferné pseudonáhodné číslo a jednotlivé dvojice číslic rozhodnú o jednej vlne:

číslo = ďalšie pseudonáhodné 20-ciferné číslo
typ = power-up, ak číslice 4 až 5 > 90, inak nepriateľ
sprite = číslice 1 až 2 modulo počet druhov nepriateľov
pauza pred vlnou = číslica 3 / 2 sekundy (aspoň 1)
výška = číslica 7, prepočítaná na výšku plochy
vzor pohybu = číslice 10 až 11 modulo 10
počet lodí vo vlne = číslica 17 / 2 + 1
rýchlosť = číslica 13 × (1 + poradie vlny / 10), v rozsahu 20 až 50
každá tridsiata vlna = boss, generovanie stojí, kým boss žije

Seed generátora (počiatočná hodnota) nechajte v hre pevný. Každý hráč potom dostane rovnaké poradie vĺn a skóre v rebríčku sa dá porovnávať.

Desať malých hracích plôch, na každej jeden vzor pohybu nepriateľa vyznačený prerušovanou čiarou
Desať vzorov pohybu z generátora. Konkrétny tvar závisí od výšky, v ktorej sa vlna objaví.

Ako sa takýto režim vyvíja, ukazuje simulácia generátora mimo hry (300 vĺn, rovnaký seed ako v hre). Prvý boss príde po 29 vlnách, teda po 74 nepriateľoch a 3 power-upoch, zhruba po 130 sekundách. Prvých 30 vĺn letí minimálnou rýchlosťou 20, lebo jedna číslica je ešte menšia ako dolná hranica. Priemerná rýchlosť potom rastie na 28,5, 37,5 a 41, od 120. vlny je väčšina nepriateľov na maxime. Power-up je približne každá jedenásta vlna.

Časová os prvých 135 sekúnd nekonečného režimu s ikonami nepriateľov a bossom na konci
Prvých 135 sekúnd nekonečného režimu podľa simulácie generátora. Vlny sú dlhšie a nepravidelnejšie než v ručne písanom leveli.

Slabina je, že generátor nepozná rytmus. Ručný level strieda tlak a oddych, generátor nie. Čiastočne to rieši pauza počas bossa a rast rýchlosti, ale ručne písané levely sa hrajú lepšie.

Limity tohto prístupu

  • Žiadne automatické testy. Všetko sa overuje ručne v simulátore a na hodinkách.
  • Globálny stav. Väčšina stavu hry sú globálne premenné jednej scény. Pre hru len na hodinky je to pohodlné, pri pridaní verzie pre iPhone už nie.
  • Levely bez editora. Tabuľka časov sa dobre ladí po malých krokoch, pri väčších zmenách by si zaslúžila editor.

Ak robíte hru na hodinky alebo inú malú obrazovku a chcete s niečím pomôcť, napíšte nám. Ako generujeme hlavolamy v ďalšej našej aplikácii, sme opísali v článku o generátore sudoku.

← Ďalšie v kategórii Space Impact Watch