Loppuraportti


Sisällys


Kohdeohjelman kuvaus

Käyttöliittymä

Tekninen toteutus

Rakenne

Kokemuksia projektista

Yhteenveto

Ohjelmakoodi ja JavaDoc


Kohdeohjelman kuvaus

Escape the Olkkari on tyypillinen runsasta klikkailua vaativa peli, jonka tavoitteena on päästä ulos suljetusta huoneesta. Tavoitteeseensa pääsemiseksi pelaajan on kerättävä huoneesta oikeat esineet ja niitä yhdistelemällä löydettävä ratkaisu oven avaamiseksi. Ensimmäisellä pelikerralla peli on ratkaistavissa onnesta ja pelikokemuksesta riippuen 5-30 minuutissa, mutta jo toisella kerralla ”ratkaisemiseen” menee alle puoli minuuttia eikä pelillä ikävä kyllä ole enää oikeastaan mitään tarjottavaa pelaajalle.

Ajatus peliini syntyi kokeiltuani montaa erittäin hyvää ja huonoa peliä samaisesta kategoriasta. Halusin toteuttaa omanlaiseni version, joka ei olisi liian hankala logiikaltaan tai käytettävyydeltänsäkään. Tosin todettakoon, että peliä on moitittu liian vaikeaksi. Ympäristöksi päätin valita jonkin olemassa olevan tilan säästääkseni itseäni uuden maailman keksimiseltä. Valitsin Athenen (epävirallisen) kiltahuoneen – mahdollisimman tutun ympäristön kaikille Studio1-kurssin osallistujille.

Käyttöliittymä

Pelin käyttöliittymä koostuu pää-, sivu- ja alapaneelista. Pääpaneelissa näkyy huoneen tutkittavana oleva seinä tai sillä hetkellä tarkastelussa oleva esine. Kerätyt esineet säilötään sivupaneelin ruudukkoon, josta niitä voi valita lähempään tarkasteluun. Alapaneeli säilöö JLabel -olion, jonka avulla pelaaja saa (lähes poikkeuksetta hyödyttömiä) vihjeitä tavaroita tutkiessaan.


Text Box: Näkymä peli-ikkunasta. Alapaneelissa teksti "Et vaan osaa", Esinepaneelisa muutamia kerättyjä esineitä, pääpaneelissa näkymä huoneen seinästä. Pääpaneeliin, samoin kuin Esinepaneeliin on lisätty kuuntelija, joka kuuntelee käyttäjän hiirenklikkailuja ja reagoi niihin. Valikkoriviltä käyttäjä voi avata Peli-valikon, josta voi lopettaa pelin ja Apua-valikon, jonka takaa löytyvät lyhyet ohjeet pelaamista varten. Lisäsin valikoille myös pikanäppäimet joten pelin sulkeminen onnistuu helposti painamalla Alt:ia ja F4:sta ja ohjedialogi ponnahtaa esille F1:n painalluksesta.

Tekninen toteutus

Peli on toteutettu käyttäen vanhaa tuttavaani Eclipseä, Windows XP ja Windows Vista-ympäristöissä, JDK 1.6:lla. Uudeksi apuvälineeksi löysin projektinteon tiimellyksessä (kaverin vinkistä) Eclipsestä oman versionhallintasysteemin, joka osoittautui erittäin positiiviseksi kokemukseksi helppokäyttöisyytensä ja kätevyytensä vuoksi. Olisinkin ehkä jo aiemmin toivonut tähän työkaluun tutustumista, sillä kurssin aikana tehtävien vekslaaminen eri koneiden välillä oli erittäin rasittavaa.

Projektini rakentuu viidestätoista luokasta, joiden yhteispituudeksi tuli noin 1800 riviä JavaDoc-kommentoitua koodia. Rakenteellisesti ohjelma yrittää kovasti olla MVC-rakenteen mukainen, mutta käytännössä mikä tahansa luokka pääsee lähes mihin tahansa muun luokan metodeihin käsiksi. Pelin grafiikan ulkoistin suurimmaksi osaksi Hovin Jannelle ja saatuja kuvia väänsin itse oikeanlaiseen muotoon ja kokoon Adobe Photoshopin (CS 2) avulla.

Rakenne

Pelissäni on pääohjelmaluokka Nakyma, joka perii JFrame-luokan. Nakyma-luokka huolehtii, että peli-ikkunaan asetellaan komponentit oikealla tavalla ja peliä varten luodaan tarvittavat Huone-, Esinepaneeli- ja Esineruudukko-oliot. Luokan huomionarvoisin metodi public void muutaKuvaNakymaan(Kuva esine, Esinelokero lokero) huolehtii tarkasteltavan esineen asettamisesta pääpaneeliin. Metodissa luodaan esinettä varten kuuntelija, joka klikkauksen jälkeen kutsuu tarkasteltavan esineen paivita(Dimension dim) -metodia käyttäen parametrina klikkauksen perusteella luotua Dimension-oliota. Esineestä riippuen Nakyma-luokka saa metodilta uuden kuvan, jonka se asettaa pääpaneeliin tai nullin, jolloin esine palautuu esineen kuva katoaa ja huoneen näkymä tulee taas näkyviin.

Pääohjelmaluokan selkeyttämiseksi olen erottanut HuoneenKuuntelija-luokan, joka hyvinkin olisi voinut olla Nakyma:n sisäluokka, erilliseksi luokaksi. HuoneenKuuntelija huolehtii siitä, että huone kääntyy kun sen reunaan klikataan ja esineet luodaan ja ne voi kerätä kun klikkaus osuu oikealle alueelle. HuoneenKuuntelija ei ole pelkkä kuuntelijaluokka, vaan kuunneltuaan se myös toimii. Esineiden luonti ja paneeliin tallentaminen on täysin tämän luokan vastuulla, eikä pelilogiikkaa näiltä osin ole tallennettu erilliseen MVC-mallin mukaiseen luokkaan.

Jo aikaisemmin mainittu luokka Esinepaneeli on myöskin kuuntelijaluokka. Se toteuttaa MouseListener rajapinnan, mikä mahdollistaa esineen poistamisen lokerosta tutkittavaksi ja palauttamisen takaisin. Esinepaneeli on JPanelin aliluokka, joka säilöö JLabelin aliluokan, Esinelokero, instansseja. Esinepaneelin mallina toimii Esineruudukko luokka. Esinepaneeli tietää Nakyma-olion, jossa se näkyy mallinaan toimivan Esineruudukko-luokan instanssin ja sillä on myös omana attribuuttina Esinelokeroista koostuva kaksiulotteinen taulukko tavaroiden hallintaa varten.

Esinelokero on yksinkertainen JLabelin aliluokka, jonka olio tietää sijaintinsa paneelissa ja säilömänsä esineen. Luokalla on metodi public void nayta(), joka kutsuu lokeron säilömän esineen annaPikkukuva()-metodia ja asettaa saadun kuvan Lokeron näytettäväksi.

Esine on pelin esineiden abstrakti malliluokka. Esineellä on pieni kuva lokeroa varten ja iso kuva pääpaneelia varten, lisäksi se tietää sijaintinsa esinepaneelissa eli lokeron johon se on säilötty. Jo aiemmin mainittu paivita(Dimension dim) -metodi on esineen toiminnallisuuden ydin. Se reagoi esineestä ja klikkauksen koordinaateista riippuen muuttamalla esineen isoa kuvaa ja palauttamalla sen. Tämä mahdollistaa joidenkin esineiden osalta kääntelyn ja toisten osalta muodonmuutokset.

Huone-luokka toimii pelimaailman mallinnoksena. Huone rakentuu neljästä Seina-oliosta, jotka se säilöö ArrayListinä. Huone-luokan konstruktori huolehtii seinien luonnista ja seinien esittämistä varten tarvittavien kuvien tallentamista Seina-luokasta löytyvän public void lisaaKuvatiedosto(String tiedostonNimi)-metodin avulla. Huone pitää seinänsä järjestyksessä ja kääntyminen tuottaa aina loogisen tuloksen.

Kokemuksia projektista

Jos tekisin projektini alusta, pakottaisin itseni tarkempaan suunnitteluun. Aloittaessa selvää oli ainoastaan minkä tyyppisen ja näköisen pelin tulisin tekemään. Ajatukseni teknisen toteutuksen tai pelin juonen osalta olivat hyvin alkeellisella tasolla. Tiesin, että liikkumiseen tarvitsisin hiirenkuuntelijaa ja Esinepaneelin toteutus olisi hyvin samankaltainen kuin sokobanin Pelipaneelin. Esineet olin aikonut toteuttaa abstraktin luokan avulla, mutta projektia tehdessäni rakenne muuttuili tavallisen luokan ja rajapinnan yhdistelmästä pelkkään rajapintaan ja abstraktiin luokkaan takaisin. Lisäksi myöhemmin miettiessäni huoneen muunteluun ja kääntelyyn liittyvää hiirenkuuntelijaa, olen pohtinut myös toisenlaista ratkaisua. Olisin ehkä voinut säilöä klikkauksiin reagoivat alueet johonkin kokoelmaan ja sitoa ne vastaaviin tapahtumiin. Nykyinen rypäs if-else if-else -lauseita on toimiva, mutta melko hankalasti hallittava ja luettava.

Vaikka minulla ei ollutkaan tarkkaa suunnitelmaa missään vaiheessa projektiani, en onneksi viettänyt lähes yhtään aikaa virheiden korjailuun. Suurimmat ongelmat syntyivät kuvan päivittämisen kanssa, mutta hetken googleteltuani löysin muiden samankaltaisten ongelmien ratkenneen JLabel:in validate()- ja JPanel:in updateUI()-metodien avulla.

Työskentelyni oli melko tehokasta, kun siihen ryhdyin. En pakottanut itseäni koodaamaan kovinkaan paljon, jos se ei sujunut. Turha aikareikä oli työskentelyn ohella tapahtuva taustahäsellys. Opinkin, että on parempi tehdä yhtä asiaa kerrallaan, monen asian puolittaisen tekemisen sijaan. Täydellisellä keskittymisellä koodi eteni ongelmitta, eikä tarvinnut palata korjailemaan virheitä. Yllätyksenä itselleni en juurikaan viettänyt aikaa Apeja selaillen, vaikka uskoin aloittaessani että suurimman osan asioista joudun jostain etsimään.

Suunnitteluvaiheessa en ollut suunnitellut ajankäyttöäni juuri lainkaan. Olin ainoastaan varautunut, että tekisin niin paljon töitä kuin pelin valmistuminen vaatisi. Vasemmalla taulukossa hieman suuntaa antavaa kirjanpitoa aktiivisesta koodiajasta tunteina per päivä. Laskeskeltuani ei ohjeellinen 80 työtuntia täyttynyt, mutta koodaamisen ohella uhrattu aika mm raporttiin, ideointiin, stressaamiseen, pohdiskeluun ja bloggamiseen(http://escapetehjava.wordpress.com/ ) käytetty aika kyllä täyttää loput tunnit.

Yhteenveto

Kaiken kaikkiaan olen tyytyväinen tuotokseeni. Palatessani (koodi)loman jälkeen pelimaailmanani toimivalle olkkarille olin erittäin tyytyväinen kuinka onnistunut mallinnokseni (tosin grafiikkahan ei minun tekemääni ollut) todellisesta maailmasta oli. Grafiikan ulkoistaminen osaltaan opetti jonkin verran muiden ihmisten hoputtelua. Voinkin jälkipolville kertoa kuinka tärkeää hyvien kaverisuhteiden ylläpitäminen on.

Ohjelmakoodi ja JavaDoc

http://users.tkk.fi/~alipiain/docs/

 

Esine.java

Esinelokero.java

Esineruudukko.java

Esinepaneeli.java

Huone.java

Huoneenkuuntelija.java

Intro.java

Kuva.java

Nakyma.java

Nalle.java

Paperiarkki.java

Purkki.java

Seina.java

Tietokone.java

VihjeLappu.java