Tagad — arī ar iespēju komentēt!

Par Binding of Isaac uz ZX Spektruma

Karoč, es te pagāšgad fonā sāku vienu mazu retroprojektu, kurš sasprūda, tapēc šis ir terapeitisks raksts par to — ja arī rakstīšanas gaitā es neatsprūdīšu un tas tā arī paliks pusratā, vismaz paliks kāda pēdiņa manā internetā.

Īsā versija

Es netiku galā ar spraitu mirgošanu savam Binding of Isaac ZX Spektruma demeikam, kuru var pataustīt te — https://spicausis.lv/isaac/ — un bez tā atrisināšanas neredzu jēgu turpināt.

Pre

The Binding of Isaac ir lipīga datorspēle par mazulīti Īzaku, kurā es savā mūžā esmu iegāzis iespaidīgi daudz laika.

Kaut kad 2022. gada sākumā, tērzējot ar draugiem par datorspēļu demeikiem, populāru spēļu reducētām versijām, kuras fani ir izveidojuši priekš nesalīdzināmi vājākām iekārtām — senām konsolēm utml, es uzgāju “Inding of Baasic” — īzaka versiju ZX Spektrumam. Akdies, divas lietas, kuras silda manu sirdi vienā iepakojumā? Ekselenti!

The Binding of Isaac Rebirth uz PC.
Attēls no pushsquare
The Inding of Baasic uz ZX.

Eh, nē, ne pārāk. Šī spēles versija ar baigo estētiku neizceļas. Kaut arī spēles koncepcija ir lieliska — tas IR īzaks uz spektruma — to spēlēt nav kaifīgi un pats Īzaka mazulītis izskatās pēc slima citplanētieša. “ES VARĒTU LABĀK” doma riņķoja man galvā visu laiku, cik es to gāju cauri spektruma emulatorā, lādēdamies uz šāvieniem, kuri lido ne tur, kur vajag, neglītumu un citām kaitinošām lietām.

Tad nu es ķēros klāt misijai uztaisīt tik feinu Īzaku, cik nu ļaus manas prasmes to iestūķēt 48K spektrumā. Dažiem retroistabas biedriem ir īsta, dzīva iekārta, tapēc ir ekspektācija, ka kaut cik jēdzīga rezultāta gadījumā varēs to padzenāt arī uz īstas iekārtas.

Spektruma grafika

Grafika ir šis iekārtas posts. Spektrumam teorētiski ir 256x192 pikseļu ekrāns, kas atbalsta 16 krāsas taču, kas graujoši, tas ir sadalīts 8x8 pikseļu lauciņos, un katrā šādā lauciņā var būt tikai divas dažādas krāsas. Tehniski, ekrāns atmiņā sastāv no divām daļām — 256x192/8=6144 baitiem, kur attēls ir melnbaltā bitu formā, vienā baitā turot astoņus pikselīšus, un 32x24=768 baitu krāsu apraksta. Šis ir galvenais iemesls, kapēc lielākā daļa spektruma spēļu cieš no kantainības, jocīgiem krāsu pleķiem vai cenšas spēles laukumu attēlot divkrāsainu.

Par cik katrā kvadrātiņā var būt tikai divas krāsas, novērtē kā savlaik meistari ir ķimerējušies, šis ir tāds īpaši rūpīgs piemērs. Uzklikšķinot, bildītes atvērsies milzīgākas, bet šis ir 1:1 viss, ar ko šī iekārta strādā, vairāk pikseļu tolaik nebija:

Es sāku darbu grafiskajā editorā, ķēpādamies, līdz panācu kaut kādu skaidrību par to, kā varētu izskatīties dažādi spēles elementi un vispār guvu pārliecību, ka varēšu mazajā punktiņu daudzumā attēlot savas vēlmes. Grafisko ierobežojumu dēļ kurš katrs grafiskais editors neder, pat pikseļu grafikai piemērots, tapēc es biju priecīgs atrast Koloratoru, kurš rakstīts javā un tā autors lieliski saprot, kas šādam editoram nepieciešams. Lūk, unikāls behind the scenes:

Spraiti

Labām konsolēm ir spraitu procesori. Spraitu procesors ir atsevišķa mašinērija konsolē, kura ļauj spēļu autoriem iedot tiem gabaliņu grafikas un pateikt “lūdzu, šis te ir spraits, tā zīmēšana ir tavā ziņā kthx”, un pēc tam, daudz nedomājot, operēt ar šo spraitu kā abstraktu vienību, “pabīdi to pa labi, pa kreisi, utt”, un pašu zīmēšanu, to pārklāšanos uz ekrāna etc dzelži ņem savā ziņā.

Spektrumam nekā tāda nav. Spektrumam nav spraitu procesora, spektrumam ir tikai ekrānam veltīts atmiņas apgabals. Ierakstīsi atmiņas adresē 16384 skaitli “64” — un pirmajā rindā pirmie astoņi pikseļi izskatīsies šitā: “◦•◦◦◦◦◦◦” (jo 64 formātā paskatā ir 01000000), un tas ir vienīgais veids kā darboties ar ekrānu.

Netriviāli, bet ne pārāk sarežģīti ir galu galā uzrakstīt funkciju, kura paņems, teiksim, 2x24 baitu (16x24 pikseļu) spraitu un uzzīmēs to noteiktās koordinātēs. Ja rakstīt asemblerī, tā var būt pat tīri žigla.

Lai īpaši daiļi izskatītos spraiti, kuri mēdz pārklāties, tiem mēdz veidot maskas, un spraitu zīmē divos piegājienos: ar masku notīra zīmējamo vietu, un tad zīmē pašu spraitu, šādi:

Spraits un tā maska
Ja vienkārši zīmēt spraitu pa virsu akmenim, sanāk miskaste
Tapēc, pirms zīmēt spraitu, notīrām maskas vietu. Daile!

Tas viss ir daiļi un jauki. Bet, ja tu atvērsi lapu, kur pārlūka emulatorā ir svaigākā mana rezultāta versija — https://spicausis.lv/isaac/ — tu vari ievērot, ka, kaut arī ķēmiņi apkārt skraida tīri gludi, tomēr tie ļoti mirgo. Tie mirgo tik daudz, ka reizēm mošķi ekrāna augšmalā var pat pilnīgi pazust.

Problēma ir tajā, ka tad, kad ķēmiņi pārvietojas, uz ekrāna kaut kā ir “jāatliek atpakaļ” vieta, kur tie atradās. Skaitļotāja jaudas ne tuvu nepietiek, lai varētu pārzīmēt visu ekrānu no nulles un saglabāt gludu kustību, tapēc jārisina, kā lai panāk rezultātu ar iespējami maz darbībām iespējami ātrākā laikā. Ja kaut ko var nepārzīmēt, tad labāk to arī nepārzīmēt — filozofija, pilnīgi nepiemērota tādai ašai un dinamiskai spēlei, kā īzakam.

Es atjaunoju ar fona attēlu to vietu, kur stāvēja vecais spraits, un zīmēju jaunajā vietā jauno. Nav tā, ka tas būtu lēnu, bet attiecīgā ekrāna vieta var parādīties uz ekrāna tajā brīdī, kad jaunais spraits vēl nav uzzīmēts. Nu fak.

Ko tālāk

Es nez. Es redzu vairākus ceļus, kurus es negribu izvēlēties, jo tas neatbildīs manai kvalitātes vīzijai. Teiksim:

  • samazināt spraitu izmērus, padarot darbības ar tiem krietni ātrākas,
  • neļaut kustīgajiem spraitiem pārklāties ar akmeņiem u.c statisko drazu, lai fons ir pilnīgi tukšs — tas saknē atrisinātu fona atjaunošanu, bet īzaks, kurš stāv akmenim priekšā, ir ikonisks un piedod visam telpiskumu.

Vēl varētu ārkārtīgi sarežģīt spraita zīmēšanas funkciju, lai tā vienlaicīgi, līniju pa līnijai dzēstu spraitu no senās vietas un jauno spraitu zīmētu jaunajā vietā. Tas neatrisinātu problēmu pilnībā, bet panāktu to, ka nav neviena brīža, kad spraits ir pilnībā novākts no ekrāna. Velns, tas ir baigi komplicēti. Es labāk ierakstīšu šito blogā.

***

Oh, ironija par "not dead".

Pētnieciskai interesei, svaigākais eksperimentālais rezultāts pārlūkā pataustāms te: https://spicausis.lv/isaac/