torstai 30. kesäkuuta 2016

Peliohjelmointikurssilla opittua

Kahdeksannen luokan peliohjelmointikurssi jatkui keväällä. Ensimmäisellä kokoontumiskerralla tiimit viimeistelivät suunnitelmansa OneDrive:ssa oleviin dokumentteihin. Me opettajat toimimme katselmoijina ja kyselimme epäselviä asioita sekä tarkennuksia ja lopulta suunnitelmat olivat jotakuinkin yksiselitteisiä niin, että graafikot ja koodarit saattoivat aloittaa omat hommansa.

Koodarit aloittivat tutustumalla opettajan Racket:illä koodaamaan pelipohjaan, jossa oli valmiina hahmojen piirtäminen ruudulle, tietorakenteet "peli" sekä "hahmo", hahmojen liikkumiseen sekä pelaajan ja toisen pelihahmon törmäyksen havaitsemiseen liittyvät funktiot sekä pelimoottori big-bang. Tietorakenteen kentille oli myös valmiiksi koodaattu set- ja get-funktiot.

Peli-tietorakenteessa oli seuraavat kentät:
  • tilanne : Symboli (esim. 'alku 'käynnissä 'pause 'loppu)
  • taso : Luku
  • pisteet : Luku
  • aika : Luku
  • pelaajat : Lista<hahmo>
  • dynaamiset : Lista<hahmo>
  • staattiset : Lista<hahmo>
 Hahmo-tietorakenteessa oli seuraavat kentät:
  • tyyppi : Symboli (esim. 'pejaaja 'kerättävä 'vaara)
  • id : Luku
  • tila : Symboli (esim. 'elossa 'kuollut)
  • varusteet : Lista<symboli> (esim. 'lippis 'pipo)
  • sijainti : Posn (x- ja y-koordinaatti)
  • suunta : Posn (vektori jossa x:n ja y:n suuntainen siirtymä)
  • laskuri : Luku (jos 0 niin ei liiku)
  • asento : Symboli (esim. 'vasen 'oikea)
Vaikka pelipohjassa oli paljon koodia, se ei vielä toteuttanut yhdenkään pelin logiikkaa joten ensimmäinen vaihe oli suunnitella miten kunkin ryhmän peli käyttäisi tietorakenteita hyväkseen, millaisia tiloja pelillä ja hahmolla piti olla jne. Tämä tehtiin isolle paperiarkille.

T'ässä pelissä sipsipussin piti kerätä hyppimällä juomia ja vältellä sivulta tulevia Shrekkejä (toinen "vuoristo"-taso jäi toteuttamatta)
Kun suunnitelma oli valmis, lähdimme tekemään pelejä yhdessä. Vaikka pelit olivatkin hyvin erilaisia, yllättävän monessa pelissä oli samoja piirteitä, jotka saatoimme koodata yhdessä opettajan johdolla kuitenkin niin, että kukin koodaripari sovelsi vaiheen omaan peliinsä sopivaksi. Lähdimme ensin luomaan kuhunkin peliin liittyviä hahmoja ja laitoimme ne liikkumaan oikeaan suuntaan (säätämällä suuntavektoria). Koska meillä ei ollut grafiikoita, ryhmät käyttivät erivärisiä ympyröitä, kolmioita ja nelikulmioita hahmojen kuvina. Ensimmäisinä koodasimme siis funktiot: tee-hahmo ja piirrä-hahmo. Kutsuimme tee-hahmo-funktiota riittävän monta kertaa, että saimme big-bangin käynnistyttyä muutamia hahmoja liikkumaan. Seuraava vaihe oli lisätä funktio, joka toteuttaa pelaajan liikkumisen käyttämällä nuolinäppäimiä. Koodasimme siis funktion: hoida-näppäimet. Kun pelaaja liikkui saatoimme lisätä törmäyksen havaitsemisen sekä pisteiden lisäämisen tai vähentämisen riippuen törmäyksen kohteesta. Nämä toteutettiin funktioiden: päivitä-peli ja törmäsikö? avulla. Lopuksi lisäsimme funktion, joka automaattisesti arpoi peliin lisää hahmoja. Tämä toteutettiin funktion lisää-hahmoja ja arvo-hahmot avulla.

Zombipelissä piti ampua sivuilta tulevia zombeja (huomaa läpinäkyvä ase ja matalalla liitävät ammukset)
Näiden perustoimintojen lisäksi, yhdessä pelissä hahmolle (sipsipussi) piti lisätä painovoima, eli se piti saada hyppäämään ja sen jälkeen putoamaan takaisin. Toisessa pelissä pisteiden laskenta toimi niin, että kolmen "vihanneksen" jälkeen pisteet nollautuivat kokonaan, eli peli loppui ja alkoi taas uudelleen. Kolmannessa pelissä hahmojen lisäksi taustakuva liikkui ajan suhteen, näin saatiin aikaan hahmon putoamisilluusio. Neljännessä pelissä hahmo ampui luoteja hiiren avulla, joten siihen piti lisätä myös hoida-hiiri-funktio. Viides peli jäi alkutekijoihinsä, koska koodareilta loppui mielenkiinto koodaamiseen melko nopeasti. Tämän ryhmän kanssa teimme niin, että graafikot siirtyivät kuvien valmistuttua koodaamaan ja ne ottivat käyttöön Scratch-työkalun, että saisivat jotain valmiiksi siinä  lyhyessä ajassa mitä oli enää jäljellä.

Tässä pelissä sankari hyppää katolta ja kerää matkallaan ES:iä ja nugetteja ja samalla väistelee lintuja (pallot kuvaavat ruokia, jotka jäivät graafikoilta toteuttamatta)
Pelejä koodattiin 7 kaksoistuntia ja samaan aikaan graafikot tekivät peligrafiikoita kuvataiteen opettajan ohjauksessa. Ensimmäisen kerran yritimme liittää kuvia ja koodia yhteen toukokuun alussa. Siinä vaiheessa tuli ilmi montakin ongelmaa, hahmojen kuvissa oli turhia valkoisia taustoja ja kuvia ei oltu rajattu mahdollisimman pieniksi, jotta törmäysehdot toimisivat moitteetta. Myöskään putoamisilluusion luomiseen tarkoitetut talon palaset eivät olleet sellaiset kuin piti (palat olivat eri kokoisia). Graafikot saivat tärkeää palautetta ja he palasivat korjaamaan kuvia, ja koodarit koodasivat pelejä hieman lisää. Kurssin loppu tuli kuitenkin vastaan aivan liian nopeasti, ja lopulta sovimme niin että opettaja koodaa jokaista peliä eteenpäin max 1h per peli. Lopulta neljän pelin loppuun koodamiseen meni 2h15min. Hankalin peli oli zombiepeli, koska siinä sekä zombit että ammukset liikkuivat ja ammuksen ja zombin törmäys piti havaita, kuten myös zombin ja pelaajan törmäys.

Tässä pelissä tehtävänä oli syödä taivaalta putoavia ruokia ja vältellä vihanneksi, tosin vihannekset jäivät graafikoilta piirtämättä ja tilalle tuli läjä sitä itseään.
Pelin lisäksi ryhmän piti tehdä pelille mainossivu, ja tämä toteutettiin blogikirjoituksen muodossa. Ryhmän graafikko ja tarinavastaava tekivät tämän kurssin lopussa. Vielä viimeiselläkin kerralla työstimme vielä pelejä, koska grafiikoissa oli edelleen puutteita: kerrostalon seinässä oli reikiä joista paistoi taivas, pitsapalassa oli turhaa näkymätöntä reunaa ja zombit ja zombien ampuja oli vielä piirtopöydällä. Lopulta kaikki viisi peliä olivat jotakuinkin pelattavassa kunnossa, hyvin riisuttuina versioina tosin mutta kuitenkin. Muutama graafinen elementti jäi puuttumaan, ilmeisesti pienten kommunikaatio-ongelmien takia ja zombien ampujan asekin jäi läpinäkyväksi ja ammusten lähtötaso säätämättä mutta näin voi käydä kun aika vain loppuu kesken.

Tässä pelissä piti hyppiä tasoilta toiselle ja kerätä rahoja, tasoja piti olla eri värisiä ja niiden piti kadota ja tulla taas esiin mutta tämä peli ei toteutunut aivan suunnitellulla tavalla
Kaiken kaikkiaan tämä oli hyvin mielenkiintoinen projekti. Tässä kurssissa tarkoitus ei ollut varsinaisesti oppia ohjelmointia vaan pääpaino oli uuden pelin ideoinnissa sekä projektityöskentelyn opettelussa. Ainakin ryhmille tuli selväksi, että jokaisen työpanosta tarvitaan, eikä peli tule valmiiksi jos jokin osa-alue jää tekemättä. Pelin suunnittelu oli aluksi vaikeaa, mutta lopulta suunnitelluista peleistä tuli jopa hieman turhan monimutkaisia toteutettavaksi näin lyhyen kurssin aikana. Pelipohja toimi siinä mielessä, että sen avulla pystyttiin tekemään nämä pelit, mutta kovin helppokäyttöinen se ei vieläkään ole. Lausekielen (tällä kurssilla Racket) käyttäminen näin suppealla kurssilla ei ehkä vastaa tarkoitustaan varsinkin kuin osalla koodareista ei ollut aikaisempaa kokemusta ohjelmoinnista. Asian (ohjelmointi) syväoppiminen ja pelin valmiiksi saaminen eivät ehkä toteudu saman kurssin puitteissa... Ensi lukuvuonna 8. luokan kurssin nimi onkin pelkkä "ohjelmointi". Katsotaan saako "ohjelmointi" enemmän tilaa, kun "peli"-aspekti jää pois.

Tässä pelien esittelyt löytyvät kurssin blogissa.

Ei kommentteja:

Lähetä kommentti