Sisällys
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.
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.

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.
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.
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.
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.
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.
http://users.tkk.fi/~alipiain/docs/