KILDU, egy aranyos, jóságos kis házi-kobold lány. Az Alföldön élt egy kis tanyasi házban, egy idős néninél. A néni idővel meghalt. Örökösei eladták a tanyát egy nagy építési cégnek. Ez a cég lerombolta a tanyát, hogy modern lakóparkokat, ipari parkot, nagy plázákat építsenek a helyére. Így, szegény kis KILDU otthon nélkül maradt.
Elhatározta, hogy útra kél és új otthont keres. De nem ám itt, a nyüzsgő nagyvárosban, hanem felmegy a csendes, nyugodt, jó levegőjű mátrai hegyekbe, s keres egy kis erdei házikót. Az út nagy részét már megtette, el is érte a hegy lábait. Utazása során nagyon elfáradt. Többször el is tévedt, és meg is betegedett.
Segíts neki megtalálni az új otthonát. Az erdei házikóhoz vezető út még rejteget magában kihívásokat, akadályokat. Segíts neki leküzdeni azokat. Az út során szedj össze mindent, amit találsz. Járj nyitott szemmel, találj rá a rejtett utakra, keresd meg a továbbjutáshoz szükséges tárgyakat. Keress neki élelmet és elixírt, hogy meggyógyulhasson és erősen érkezhessen meg az új otthonába. A bejutáshoz szükséges, az erdőben elrejtett kulcsot is keresd meg hozzá.
KILDU már nagyon szeretne egy új otthont.
Sok sikert hozzá!
Ezt meg hogyan?
Merült fel bennetek a kérdés, tudván, hogy a Homelab 2-es a maga 16 kB-jával labdába sem rúghat a C64, vagy Spectrum, TVC... minimum 32, 48, 64 kB-os, "hatalmas" tárolókapacitásával.
Ami tovább nehezíti a dolgot, hogy a grafikus terület ebből csípi le a neki kellő 8000 bájtot. Viszont, a karakteres képernyő 1 kB-os video RAM-ja pluszban jön az alap 16 kB-hoz. Nos... Ebben a 16+1 kB-ban kell elférnie mindennek, de hogyan?
A másik "hogyan?" kérdés, idézem: "Engem mindig ez érdekelt, hogy lehet ezeket a különálló alkotóelemeket előállítani, és retro gépen egybe gyúrni!"
Egyszer volt, hol nem volt, volt egyszer egy... ???
Mint minden játéknál, kell valami ötlet, történet, megoldandó feladat, leküzdendő akadály. Főleg igaz ez az RPG stílusú játékokra.
Mindig is szerettem az RPG játékokat. Akik netán nem tudnák mi fán terem az RPG, azoknak segítek. Az RPG, az angol roleplaying game szó rövidítése. Magyarul szerepjátékot jelent. A számítógépes kalandjátékok mind ide tartoznak. Jó-jó, tudom, ezeket már a 80-as évektől játszuk, de mi öregek, ezt simán csak mászkálósnak, vagy lövöldözősnek hívjuk.
A programozás általi alkotás öröme 15 évesen, 1985-ben, a HT1080Z gépen fertőzött meg. Azóta sok demót, felhasználói, illetve speciális cél programot írtam. Játékokat csak elvétve, azok is inkább logikai, vagy ügyességi játékok voltak. Jó pár éve, írtam egy egyszerű, kezdetleges mászkálós játékot, apa-fia projektként, mikor az álltalános suliban ismerkedtek a BASIC programozással. Ő inkább csak ötletelt, s megrajzolta a főhőst. A kódolást meg úgy ahogy, de elég jól megértette, bár még így is bonyolult volt számára. A játék online itt kipróbálható. PLAY
A pályázat beadási határideje végéig volt még három hét, hát elhatároztam, hogy végre, írok egy igazi, több pályás (képernyős) nagy mászkálósat.
Nulladik nap.
Miután elküldtem a TILI TOLI játékot, másnap, friss fejjel belegondoltam, hogy mire is vállalkozok. Te jó ég! Ezeket évekig, vagy legalábbis hónapokig fejlesztik.
Nézzük, hogy milyen feladatok várnak rám:
Kell készíteni egy csomó kisebb-nagyobb méretű grafikai elemet, ami a játék kinézetét adja.
Meg kell rajzolni minden olyan tárgyat, ami az inventory-ba kerül, vagy pusztán csak valamiért (pl. pontot ad) fel kell venni.
Meg kell rajzolni a játékos és az ellenfelek animált alakjait.
Meg kell tervezni és szerkeszteni a térképet.
Meg kell rajzolni a HUD-ot.
A fenti rajzokból és tervekből kell készíteni egy adatbázist.
Le kell programozni az adott térképrészletet legeneráló algoritmust.
Aztán, a kész térképrészletből a végleges képet lerenderelő algoritmust.
A HUD és a tartalmát megjelenítő részt megírni.
A játékos és az ellenség kirajzolását megírni.
Billentyű-figyelést, mozgási tartományt, és az interakciókat leprogramozni.
Ha kész a játék, még egy kezdőképet is kell szerkeszteni.
Végül összecsomagolni és WAV-osítani.
Ugye milyen egyszerű?
Na jó, tényleg belátom, hogy ez azért igen csak egy "Mission: Impossible".
De azért megcsinálom, maximum nem leszek kész vele időre.
Harmadik nap.
Mivel én nem vagyok jó rajzoló (műszaki rajzon kívül), ezért úgy döntöttem, hogy a számomra bonyolultabb dolgokat asset-ből oldom meg. Ezek például a fák, bokrok, virágok, sziklák. A házat egy alpesi ház mintája alapján rajzoltam meg. A nád, fű, patak, híd, útvesztő, és az összes tárgy is már mind az én munkám.
Elérkeztünk az első tényleges munkához. Az egyértelmű, hogy ekkora térképet Hi-Res felbontásban lehetetlen egy az egyben betuszkolni. Kell valamilyen tömörítés. A leg egyszerűbb az RLE, de 16 térképszelet így sem fér be. A megoldás nem más, mint a 80-as évek óta alkalmazott csempe rendszerű térképtárolás. Erre a célra, a C64-hez készült egy CharPad nevű fejlesztői program. Tudja az 1 bites monochrome képet is, hisz ez is van a C64-en. Bármekkora térképet, bármekkora csempét készíthetünk vele. A kész képeket karakterek formájában menti ki, viszont a Homelab-on nem lehet átkonfigurálni a karakter készletet. Erre kitaláltam egy megoldást, azt majd később részletezem.
A CharPad, és az eddig elkészült grafikai elemek.
Elsőként, ki lett találva a térkép mérete, ami 4X4 képernyő, a csempe mérete pedig 4X4 karakter. Ebből adódóan, egy kép 10X6 csempéből áll. A rajzok elkészítésénél arra kellett figyelni, hogy ne lépjem túl a 256 karaktert. A program tud képet importálni, így az asset-et csempeméretű képekből össze ollózott képből importáltam be, s kiegészítettem a saját rajzaimmal.
Elkészültek a grafikai elemek. Ismeretes lett a program kimenő adatai alapján, hogy mi mennyi helyet fog elfoglalni.
Matekozzunk:
Mivel az alap memória 16 kB (RAM) + 1 kB karakteres képernyő memória (V-RAM), így komolyabb grafikus alkalmazásnál nagyon optimalizálni kell, mert olyankor mi is marad a forrásnak, a pályatérképnek és a grafikai elemeknek? Összesen 8,75 - 9 kB.
256 karakter van, ez 2048 bájt.
36 darab 4X4 csempe van, az 576 bájt.
1 pálya 10X6 csempe +4 bájt infó, az 64 bájt. 16 pálya 16X64 bájt, azaz 1024 bájt.
1 játékos/ellenfél egy pozíciója (16X16 pixeles kép) 32 bájt. 1 játékos, 3 ellenfél 4 fázisú animációval összesen 512 bájt.
Tehát: charset 2048 + csempeadatok 576 + pályaadatok 1024 + szereplők 512 = 4160 bájt.
Végeredmény: 8960 (free) - 4160 (data) = 4800 bájt
Azaz, kb. 3776 (RAM) + 1024 (V-RAM) bájt marad a forráskódra és az összes változóra.
A lefordított, betölthető program maximum 8 kB-lehet.
No, ez már tényleg Mission: Impossible.
Negyedik nap.
A térkép több mint negyede nagyjából kész. Ez már bőven elég ahhoz, hogy az adatbázist felépítsem, s elkezdjem írni a programot.
A grafikai renderelő rutin már kész, hisz a TILI TOLI játéktáblája is már ezzel a programmal készült, így a karakter alapú rajzoló algoritmust használja. Ezt meg kell fejelni egy csempe alapú képösszeállító szubrutinnal, ami a karakteres videomemóriában összeállítja a pályarészletet, és már lehet is a 16 pályarész között válogatni.
Az adatbázis felépítése
A kiexportálást több lépcsőben készítettem el. Elsőként a karaktereket, aztán a csempéket, végül a térkép 16 részre osztott darabjai egyenként. Az assemblerbe az alábbi módon importálom be. Itt csak 4 térképrészlet importálása látható, természetesen, a többit is hasonlóan kell.
A térképrészlethez 4 kiegészítő információs adat is került, ami nem más, mint az, hogy melyik térképrészlet szomszédos vele az adott oldalon. Ha nincs szomszédja, akkor az érték 0, azaz nulla. A tervezetthez képest, bekerült még egy adat (binárisan látható), ami a pályafelépítő rutinnak jelzi, hogy nincs több adat. Mivel ez a 6. bit, így 64 csempe lekezelésére képes. A 7. bit más célra lefoglalva, róla később írok.
Tizenegyedik nap
Kicsit lassabban haladtam, mind szerettem volna, de az eredmény kielégítő. Végülis, a grafikai motor legnagyobb részét a pálya renderelő részt kellett megírni. Ígértem, hogy erről később írok, hát most itt az ideje.
A képi elemek túl nagyok lennének, ha mind bitmapként tárolnánk. Erre találták ki az átdefiniálható karaktereket, és azokból, mozaikkép szerűen kirakni a teljes képet. Mint említettem, a Homelab2 nem tud felhasználói karakterkészletet kezelni, tehát, ki kell találni valamit.
A megoldás: Szoftveresen létrehozni a pszeudo karakteres képet. Ez sem újdonság, a TVC is ezt használja. Nosza hajrá, írjuk meg! Jó-jó, de én ezt már megírtam a TILI TOLI-hoz.
Pszeudo karakteres képgenerálás
A mozaikkocka adott elemeinek megfelelő tényleges ASCII karakterek a meglévő karakteres videomemóriába kerülnek. Ezután, karakterről karakterre haladva, a karakterkészletből (Chars.bin) a grafikus képre másolódik az a nyolc bájt, ami az adott karakternek megfelel. Így végig haladva a 40X25-ös mezőn, elkészül (le-renderelődik) a teljes kép. A folyamat gyorsítása végett, a rajzolás idejére ki van kapcsolva a képernyő.
Most nézzük meg ezeket képekben, lépésről lépésre.
A renderelő program az új karakterkészlettel a memóriában. Indításra készen.
Átváltva grafikus módra, és a pszeudo karakterdefiníció szerint az új karakterkészlettel lerenderelve. Ugye milyen hasonló a C64-eshez?
Egy próba pálya karakteres módban. A csempeadatok szerinti pálya képét elnézve, láthatóak az azonos grafikai elemek elhelyezkedése.
Végül, grafikus módban a próba pálya. A karakterkészlet 2048 bájtján, és a csempék 576 bájtján kívül, mindössze 60 bájt kell egy ilyen kép eltárolásához. Ezután már csak 60 bájtra van szükség minden egyes új képhez. Sőt, még a felszedhető tárgyak és az út akadályok is ebben a 60 bájtban tárolódnak el, megfelelő bit kombinációval.
Amire szükségem volt, az egy olyan algoritmus, ami egy adott szám (1-16) alapján kiválasztja a hozzá tartozó térkép részlet (60 bájt), majd ezen adatok alapján, a csempe adatokból (576 bájt) felépíti a karakteres képernyőt.
Ezen a forráskód részleten látható, hogy az A regiszterbe töltöm az aktuális térképrészlet számát, amit a MapNumber változóban tárolok el. Azért tárolom el így, mert más algoritmusnak is szüksége lesz rá.
Ezután jön a karakteres pálya generáló, majd a grafikus kép renderelő algoritmus.
Tizenharmadik nap
A terv az volt, hogy: "1 játékos, 3 ellenfél 4 fázisú animációval"
A valóság: A játékos 4*8 fázisú animációt + 1 álló pozíciót kapott.
Szép az eredmény, még így nyersben is.
Ami ehhez elkészült:
Billentyű figyelés, irányítás.
Ütközés figyelés a tájjal, "rámászás" elkerülése érdekében.
4 irányú, bites scrollozás animációval.
1 álló fázis, ha nem mozog.
A kód még nincs is teljesen optimalizálva, de így is 5120 ciklus lassítást kellett betenni.
Full sebességen "Tép mint a gép..."
S akkor jöjjön a... "De hogyan?"
Gondolom, a billentyű figyelést, irányítást nem kell magyaráznom.
Az ütközés figyelést egyszerűen úgy oldottam meg, hogy nem a grafikus felületet nézem, hanem a karakteres, 40*24-es mátrixot. Ugyanis, Kildu ezen a mezőn mozog virtuálisan, a grafikus részen pedig csak a meganimált látványa van. Ha azok a cellák akár egyik cellája is foglalt, ahova menne, akkor ütközést észlel az erre írt algoritmus. Visszatérő eredményként a cellában talált kódot adja meg. Ez az információ a felszedhető dolgok miatt kell.
Az animáció, és az álló kép előállítása, ezek integrálása részben hasonló az eddig tárgyalt grafikai megoldáshoz.
Ismételten, a rajzolási késségem okán, assethez nyúltam. Sokat keresgéltem, mire találtam egy olyan karaktert, ami a grafikai paraméterei miatt alkalmas a játékomhoz. Volt négy irányú animált mozgása, ha nem is egy színű, de legalább nem truecolor, és méretben sem óriási.
Végre, rátaláltam erre.
Jöhetett a meló. Átrajzolni fekete fehérré, és az egyes fázisokat elhelyezni a szükséges pozíciókra.
A jóöreg paint pont megfelel erre.
Ezután az egyes fázisokat egyenként kimentettem, és 1 bites .wbmp formátumra konvertáltam. Ezek importálása szintén fájlként történt meg.
Tizenhatodik nap
A játékfigura megalkotása után, látva egyéniségét, cuki kis tipegését, a tárgyakhoz arányított méretét, eldöntöttem, hogy ő egy kis koboldlány lesz, s hozzá méltóan a Kildu nevet kapta.
A névadó bulit kipihenve, elkészült a teljes, 960 csempéből álló 16 képernyős térkép.
Mutatnám, de akkor könnyű lenne végig játszani.
Kildu már nemcsak egy képernyőn belül képes mászkálni, hanem, ha van szomszédos terület, akkor át tud menni oda is. Ekkor már eldöntöttem, hogy nem lesznek ellenfelek.
Ez a játék inkább a nyugis mászkálásról szól, mint sem futás az idővel. Lesz majd picit gyorsabb is, ha iszol elixirt, de az sem olyan rohanós. Inkább a jó út megtalálása, és az akadályok leküzdésének a módjára kell rájönni, amihez nem kell más, csak az, hogy nálad legyen a hozzá szükséges eszköz. Nincs lejáró idő, nincs elfogyó élet, nincs halál, csak a végtelennek tűnő mászkálás.
Már 7097 bájtos a nyers program. Még van hely, egyre biztosabb, hogy minden bele fog férni az előzetesen kalkuláltak szerint.
Tizennyolcadik nap
Elkészült a tárgyak gyűjtögetésének, és egyes tárgyak meglétének feltételéhez szabott interakciók leprogramozása. Ezekhez volt szükség az ütközésfigyelésnél visszanyerni az adott kódot.
Elkészült a HUD megrajzolása, kiexportálása, beillesztése (a szokásos módon), s a számlálók, kijelzők működésbe hozása.
Huszonegyedik nap
A beadás határideje előtti nap.
Elkészült a címkép. A lefordított assembly forrás bináris fájlja betöltve az emulátorba. BASIC indítósor hozzáírva. Kimentve HTP fájlként, melyből legeneráltam a WAV-ot.
Gábornak elküldtem, nagyon tetszett Neki, majd idővel jön a kérdés:
- Végig mentem, hogy tudom elölről kezdeni?
Hááát... Izééé... Újrakezdés újra-töltéssel.
Kb. 300-400 bájt kellene az összeszedett dolgok, és interakciók miatt a tárgyak visszarakásához a térképre. Ez a grafikai részletesség rovására menne. Még a karakteres képmemória is felvan használva. Kb. 30-40 szabad bájt van már csak.
Nem hagyott nyugodni a dolog, az agyam pörgött rajta. Végül, lett egy ötletem a megoldásra, éjjel kipróbáltam.
A megoldás pofon egyszerű volt. A térképadatok 60 bájtja 256 (0-255) különböző csempét tud lekezelni. A 255-öst az adatsor végének jelölésére használtam fel. Mivel csak kb. 40 csempém van, ezért, azok információi elférnek 6 biten. A maradék 2 bitet fel lehet használni további információk tárolására. Így lett a 6. bit az adatsor végét jelölő információ.
Majd az áttörő ötlet, hogy a 7. biten jelölöm, ha egy tárgy fel lett véve, vagy már ne látszódjon a térképen, hisz leküzdött akadály.
Ezáltal, nem törlöm az adatbázisból ezeket az elemeket, hanem csak a 7. bitet beállítom, s a pálya generáló következő arra sétálás esetén nem jeleníti meg újra a tárgyat.
Új játék indításakor, végig pásztázva az adatbázist, csak törölni kell a 7. bitet, s visszaállítva minden.
Az ötletem bevált. Grafika nem szenvedett kárt. Szabad memória terület 0 bájt lett.
A játékprogram elküldve!
Letöltés
Az alábbi helyről letölthető, és kipróbálható a program: KILDU
Gépigény: Aircomp-16K / Homelab 2 - 16 kB RAM-os verzió
Kiadási megjegyzés
Kiadó: ENTARY GAMES / NICKMANN Studio
Verzió: v1.0
Dátum: 2023. 10. 14.
Fejlesztő: Nickmann László
Támogatás
Köszönöm a figyelmet!
Ha tetszett, és meghívsz egy kávéra, bátorítasz, hogy írjak még hasonló érdekességeket a számodra.