25.12.2013

Oma koodailuprojekti, osa VII

Pitkän tauon jälkeen

Pygame-projektini on edennyt enemmän kuin mitä postaustahdista voisi olettaa. Pääasiassa olen räveltänyt taustapalikoiden kanssa, mitään kovin näkyvää tai käyttäjälle suoraan (ainakaan vielä) näkyvää en niinkään.
Toisaalta, jos edellispostausta aiheen tiimoilta katsoo, aikalaillahan tässä on muuttunut.

Viimeksi siis pelimaailma sektoreineen luotiin ja sen perusteella käyttäjälle (tässä vaiheessa ei ole mitään pelattavaa, joten en saata kutsua sitä "pelaajaksi") näytettiin kartta. Kartan sai avata/sulkea ja pelin pystyi pistämään tauolle. Perustoimintoja, muttei mitään kovin hienoa tai ihmeellistä.

Jatkoaskeleet

Ensimmäisen iteraation pelinäkymä oli kiinteä ja alus lensi siinä vapaasti. Ensimmäinen asia oli siis aluksen kiinnittäminen näytettävän alueen (viewport) keskelle ja sen vierittäminen eestaas ympäri pelialuetta (sektoria). Koska sektorin koko olisi aina näyttöaluetta laajempi, ei olisi myöskään mitään tolkkua piirrättää sellaisia objekteja, jotka eivät ole näyttöalueen sisällä. Sektorilla olisi siis oltava jonkunlainen tietorakenne peliobjektejaan varten, josta tuonkin tiedon saisi kaivettua esiin.

QuadTree

QuadTreen idea on, että jos sen yksittäisen solun kapasiteetti ylitetään, se jakautuu neljään alisoluun, johon kaikki sen sisältämät objektit jaetaan edelleen alisolujen sisään. Ja niin edelleen, kunnes puun maksimisyvyys on saavutettu. Mikään selitykseni ei voi olla parempi kuin jo olemassaolevat, joten vaikkapa wikipediasta voi lukea lisää.
Oleellista on se, että toteutin oman (tai tässä vaiheessa osan siitä) versioni tuosta. Alkuvaiheessa, kun sen pelkkä olemassaolo riittää hyvin, kaikki sektoriin kuuluva romu lisätään puuhun. Yllämainittu tarve näyttöalueella olevien peliobjektien hakemisesta taas oli ensimmäinen oikea käyttötapaus. Koska sektorit ovat neliöitä, kaikki peliobjektini toimivat ainakin tässä vaiheessa neliöinä ja nelipuun kaikki solut ovat luonnollisesti neliöitä, pygamen colliderect-metodit ratkaisevat kaiken.

def get_contained_objects(self, rectangle):
  contained_objects = []
  if self.gameobjects:
    for gameobject in self.gameobjects:
      if rectangle.colliderect(gameobject.get_rect()):
        contained_objects.append(gameobject)
      if self.top_left:
        contained_objects.extend(self.top_left.get_contained_objects(rectangle))
        contained_objects.extend(self.top_right.get_contained_objects(rectangle))
        contained_objects.extend(self.bottom_right.get_contained_objects(rectangle))
        contained_objects.extend(self.bottom_left.get_contained_objects(rectangle))
  return contained_objects

Oleellista ylläolevassa on välitetty rectangle, joka on siis pelinäkymä (viewport). Pelinäkymän pinta-ala taas kaivetaan pelaajan aluksen keskipisteen ympäriltä. Samalla vaivalla lasketaan aluksen keskipisteen ja kuvapinta-alan 0,0-pisteen välinen poikkeama, jota taas käytetään palautettujen peliobjektien renderöintiin. Kaikkien peliobjektien sijainti kartalla (sektorissa) on suhteessa sen vasempaan yläkulmaan ja siksi tuota poikkeamaa tarvitaan, jotta ko. peliobjekti voidaan piirtää oikeaan paikkaan suhteessa pelaajan alukseen.

Ehkä selitin tämänkin taas turhan oudosti, mutta minkäs teet. Koko ongelman selvittämiseen meni muutamakin istunto ja tuokio. Olin siis hyvin ylpeä, kun sain asiat vihdoin toimimaan oikein.



Peliobjektien paluu

Tietysti minulla piti olla jotain piirrettävää, jotta sain nelipuuni toiminnan testattua edes alkeellisesti. Alkuvaiheessa minulla oli nuo viimeksikin mainitut kolme aliavaruuspiraattien alusta heitettynä vakiopisteisiin sektorissa. Niiden lisäksi halusin tietysti palauttaa Asteroidit mukaan kuvaan, mutta tälläkin kerralla vähän paremmin. Samalla vaivalla puun insert- ja jakautumismetodeja voisi testata satunnaismäärällä sisältöä.

Asteroidikoodi siirtyi lähes sellaisenaan uuteen projektiin. Inittiin tuli lähinnä lisää satunnaisuutta. 2d6-heiton tuloksella 9-12 syntyy jääasteroidi, muuten kivinen murikka. Samoin 2d6-heitolla määritellään murkulan kokoluokka vanhoilla tutuilla pieni / keskikokoinen / iso / suunnaton -vaihtoehdoilla. Materiaali vaikuttaa sekä väriin, satunnaisarvottuun massaan että pyörimisnopeuteen. Kiviset ovat sekä raskaampia että hitaampia kuin jäiset asteroidit.



19.12.2013

Naamiokuvion uusintaa

Sudin eilisiltana tummemmalla harmaalla uudet kuviot Turkinan pintaan. Lopputulos on edelleen epäoptimaalinen, mutta se johtuu aikalailla siitä, että jouduin varomaan jo olemassaolevia koristeita. Täysin puhtaalta pöydältä aloittaessa tekele olisi ollut (toivottavasti) parempi.




Seuraavaksi taidan vetää pintaan ruskean litkun niin kuin edellisen OmniMech-nelikon kanssa. Jos maali ei lopu kesken. Mutta raportointi siitä tulee hoitumaan ensi vuoden puolella, minä kun lähden viettämään lomanpätkää ilman nappuloita, maaleja ja sen sellaista.

11.12.2013

Hyvin pieniä fiksejä edelleen

Joulukuu ja kaikki muu sekalainen touhuaminen eli muut projektit ovat syöneet 'Mechienfiksailulta resursseja. Samoin inspiraatio on ollut jostain syystä matala tämän touhun kanssa, joten nuo muut ovat myös päässeet rohmuamaan aikaani. Pääasiassa olen sivistänyt itseäni Alex Dentonin seikkailuilla tai pyöritellyt PyCharmia, mutta siitä lisää parin viikon päästä.

Esimarssija eli koekaniini

Jadehaukkojen oma rynnäkkömechi, Turkina, jonka saatan pistää ryppään komentajan ajopeliksi, kaipasi siis lievää uudelleenmaalausta. Ongelma tämän ja sen ohella samassa sarjassa maalattujen 'Mechien kanssa oli siis käytetty vihreä (mustan päälle vieläpä) oli ihan liian tumma. Päälle piti siis vetää jotain ja valkkasin maalivarastostani Sick Greenin (Game Color 72029) ja rupesin sutimaan.

Turkina aiemmin


Turkina nyt




En muistanutkaan, miten kauheaa jälkeä olin tuon kanssa aikanaan tehnyt. Maalasin lähestulkoon koko rottelon päälle välittämättä ihan päättömästä kaavion irvikuvasta. Seuraavaksi vedän uuden naamiokaavion tuohon päälle ja korjaan loput jadekorostukset. Miksi en peittänyt niitäkin samalla vaivalla? No kun minusta torson Galaksitunnukset olivat niin hyvin onnistuneet, että niiden tuhoaminen olisi ollut suuri sääli.

Tämän miniatyyrin kokemusten perusteella jyrään nuo loput varmaan aikalailla samalla periaatteella. Kunhan tämä yksi saadaan alta pois ensin.





2.12.2013

Pikafiksejä III/13

Vanhojen palojen läpikäynti

Kehuin aiemmin, että kävisin vuosia sitten maalaamani OmniMechit läpi ja maalaisin niidenkin ohjaamot uusiksi. Olen joskus sanani mittainen, joten tässäpä kevyt raportti aiheesta.

Viitostrinäärin alku

Lukumääräisesti vielä pienin ja siten siis nopein korjata oli hävittäjälaivueeni neljä Sakaraa. Kovin kauaa näihin ei aikaa kulunut, koska vekottimia oli kahdeksan ja kuomut olivat hyvin pienet. Jatkossa näitä on varmaan kyhättävä taas lisää, mutta koska minä siihen touhuun ehdin? Saa nähdä.



Kaksijalkaiset

Samalla vaivalla kun kävin kaikki ohjaamot läpi nappasin myös vioittuneet erilleen. Menin kerran erehdyksessä myös ostamaan Summoner D:nä kaupatun vanhan version Primestä, joka oli ihan jäätävä. En siis sörkkinyt sitä ensinkään vaan korvaan koko retaleen joskus ja käytän tuon vaikka palasiksidremelöitynä alustojen satunnaiskoristeena.


Tuosta sekamelskasta ei ota turhan hyvin selkoa, joten kerään alle muutamassa erässä nuo napit.
Ensin siis Nova prime, Cougar prime, Cougar C, Ice Ferret ja Cauldron-Born prime. C-mallin Cougar oli jossain välissä menettänyt oikean kätensä, joten se siirtyi kohti JSP:tä ja mekaanikkoarmeijaa.


Seuraavaksi raskaan sarjan vempaimia. Ensin sekä Mad Dog, Hellbringer ja Summoner prime-variantteina ja jonon jatkoksi yksi Summoner B-varianttina. Kaikki olivat ehjiä ja sinänsä moitteettomia, jollei vuosien takaisia ja sittemmin muuttuneita maalausperiaatteita lasketa moitittaviksi.




Rynnäkköpainoluokassa tarjolla oli Executioner, Gargoyle, Dire Wolf, Turkina ja Warhawk kaikki prime-variantteina ja yksi ehdottomista suosikeistani, Warhawkin täysin sairas C-malli (2x LPLas, 2x ERPPC, liekinheitin, TC). Hassusti neljä ensimmäistä sattuivat olemaan myös sitä sarjaa, jotka aion maalata osittain uudelleen: käytin niiden pintaan tummempaa vihreää kuin olin aikonutkaan, mutta en lähtenyt tuhertamaan niitä tässä välissä uudelleen.


Toinen ryppääni Timber Wolfeista (niitä on kaksi, koska pidän niistä muttei enempää, kun ne eivät ole olevinaan Jadehaukoille kovin ominaisia) on luonnollisesti silkka prime-variantti sekin:



Novat

Kaksi Novaani olin varustanut vähän muuta rypästä kevyempää kalustoa, idealla "nopeasti tilanteeseen ja Elementaalit kyydistä". Ehkä se sotii vähän Raatelukynsiryppään (Talon Cluster) kokoluokkakuvausta vastaan, joten olen valmistautunut myös järjestämään molemmille tarpeen vaatiessa raskas-/rynnäkköluokan 'Mechit käyttöön. Minusta ripeät koneet vain kuulostivat enemmän Novamaisilta.

Ensin siis kolme Stormcrowta, reunimmaiset prime-variantteina ja keskimmäinen jotain satunnaisviritelmänä.





Seuraavassa setissä oli kolme Kit Foxia ja kaksi Fire Mothia. Kaikki prime-variantteina, en oikeastaan muista, oliko näiden tilausvaiheessa olemassakaan mitään fiksua tapaa tällaisten kirppujen kustomointiin.
Aiemmin nähdystä kuvasta Nova ja Ice Ferret olivat siis merkittyjä Noviin näiden kahdeksen lisäksi.

Vaurio-osasto

Critical hittejä oli jaettu näemmä enemmänkin. Syy oli tietysti omissa rakennusmetodeissani, koska nämä hajonneet kustomoidut liitokset oli tehty mm. ennen dremel-aikakauttani ja muutenkin vähän miten sattuu.
Ensimmäisenä surullisena esimerkkinäni olkoon aikainen Hellbringer A:ni, jonka oikean käden AC on askarreltu korvansörkkimispumpulipuikon varresta. Tämä yksilö oli ottanut kriittiset osumat molempien käsiensä lower arm actuatoreihin. Pinnauksella nuo pysynevät paikoillaan vastaisuudessa.



Joukko-osaston toinen Timber Wolf on mallia A ja sen vasen käsi oli tipahtanut puoliksi irti. Hellbringerin tapaan tämäkin oli ottanut kriittisen osuman lower arm actuatoriinsa.


Onneksi vain kolme Sakaraa oli menettänyt käsiään. Niin ja se yksi vyötäröstään kahtia mennyt Summonerinromu, josta ei puhuta, koska se uusitaan muutenkin. Syy kaikkiin hajoamisiin on täysin omani ja siksi pyrin korjaamaan nämä parhaan taitoni mukaan. Tai no, tekisin niin vaikka syy olisi ollut jonkun muun.