![]() |
Multimediaa Javalla |
Seuraavaksi tutustumme siihen, miten Javalla tehtyyn käyttöliittymään voidaan lisätä multimediaelementtejä mukaan.
Kuvien näyttäminen
Java-kieli tukee HTML-kielen tavoin GIF- ja JPEG-kuvaformaatteja.
Kuvien lataaminen tapahtuu applet-luokan getImage-metodilla.
Ensimmäisenä parametrina funktiolle annetaan URL-osoite, josta kuva löytyy ja toisena parametrinä annetaan kuvatiedoston nimi. Mikäli kuva sijaitsee dokumentin kanssa samassa hakemistossa, voidaan URL-osoite muodostaa getCodeBase-funktion avulla.
Kuva ladataan Image-olion ilmentymään. Image-olio tarjoaa erilaisia metodeja kuvien käsittelemiseksi. (esim. getWidth- ja getHeight-metodit, jotka palauttavat kuvan mitat).
Kuvan piirto tapahtuu Graphics-olion metodilla drawImage(kuva,x,y,this);
Mikäli kuva halutaan venyttää määrätylle alueelle, käytetään drawImage-metodista muotoa drawImage(kuva,x,y,leveys,korkeus,this);
Seuraava esimerkki havainnollistaa kuvien tulostusta Java-kielen avulla:



Animaation toteuttaminen
Animaation voi toteuttaa periaattessa kahdella tavalla:
| Kuvia siirtämällä |
| Latomalla kuvia päällekäin |
Tietenkin näiden yhdistelmällä saa varsin näyttävää animaatiota.
Animaatio toteutetaan vaiheittain seuraavasti:
| Pyyhitään edellinen kuva |
| Päivitetään koordinaatit uusiin arvoihinsa (x- ja y-muuttujat) |
| Piirretään seuraava kuva |
| Pidetään pieni viive (40 - 100 ms) |
Seuraava esimerkki havainnollistaa animaatiota, jossa kuvaa liikutetaan näytöllä:




Säikeet:
Säikeillä tarkoitetaan ohjelman suorituksen jakamista useaan samanaikaisesti suoritettavaan toimintoon.
Säikeet luodaan olioluokan Thread avulla määrittelemällä itse appletti toteuttamaan "rajapinta" Runnable.
Seuraavassa on kuvattu säikeitä sisältävän Java-ohjelman toimintaperiaate:
| Ylikirjoitetaan metodi nimeltä run().
Tähän metodiin kirjoitetaan säikeen varsinainen
toiminnallinen koodi. Jotta säie voisi toimia, se täytyy ensin luoda ja käynnistää. Nämä operaatiot tehdään ylikirjoittamalla Start()-metodi. Start()-metodissa luodaan tyyppiä Thread oleva olio, joka käynnistetään olion omalla start()-metodilla. Eli heti käynnistämisen jälkeen säie etsii metodin run() ja ryhtyy suorittamaan sitä. Tässä metodi run() toteutetaan silmukkana, jonka sisälle säikeen koodi kirjoitetaan, eli säie pyörii "tausta-ajona" silmukassa ja suorittaa koodia. Säikeen suorittaman kierroksen kesto määritellään silmukkaan sijoitettavalla sleep()-metodilla, joka aiheuttaa halutun mittaisen viiveen. Silmukkaan on syytä sijoittaa myöskin Java-kielen poikkeuskäsittelijä: try() {...} ... catch() {...} mahdollisten ongelmatilanteiden varalle. Kun Appletti käynnistetään, suoritetaan ensin mahdollinen Init()-metodi ja heti sen jälkeen metodi start(). Kun säie käynnistetään, siirrytään metodiin run(). |
Voisiko ne värinät saada animaatiosta pois?
Edellisen esimerkin animaatiossa oli melko paljon "lepatusta" mukana. Värinä johtuu siitä, että käytämme metodia Paint piirtopinnan uudelleen piirtämiseksi, jolloin jokaisella päivityskerralla piirretään koko piirtopinta uusiksi.
Paint-metodi toimii siten, että se tyhjentää aluksi koko piirtopinnan update-metodinsa avulla ja piirtää sen sitten uudestaan. Juuri tämän takia animaatio värisee.
Voimmekin toteuttaa värinättömän animaation korvaamalla update-metodi omalla samannimisellä metodilla (ylikirjoittamalla) ja kirjoittamalla se sellaiseksi, ettei se puhdista automaattisesti koko piirtopintaa. Eli tyhjennetään kulloinkin vain tarvittavat osat piirtopinnalta.
Tämäkään ei vielä riitä poistamaan kaikkia värinöitä, koska syntyy tilanteita, joissa piirtopinnalle piirretään samanaikaisesti kun sitä yritetään näyttää. Tämä toiminto pitäisi saada jotenkin synkronoitua.
Seuraavassa muutamme edellisen esimerkin animaation välkkymättömäksi:




Hieman lisää kaksoispuskuroinnista (kaksoisbufferoinnista):
Kaksoisbufferointi tarkoittaa, että ylläpidetään kahta erillistä piirtopintaa, joihin piirretään vuorotellen. Eli toista näytetään ja toiselle piirretään ja seuraavalla kierroksella piirtopinnat vaihtavat osia. Tällöin ei voi syntyä tilannetta, että jotain piirtopintaa näytettäisiin ja sille piirrettäisiin samanaikaisesti.
Javassa ei valitettavasti voi käyttää kaksoisbufferointia aidosti, koska Java ei sisällä esimerkiksi ominaisuuksia piirtopinnan vaihtamiseen.
Kaksoisbufferoinnin voi kuitenkin toteuttaa myös Javassa valitsemalla toiseksi piirtopinnaksi Image-tyypin olio (kuva), koska Image-olio sisältää oman piirtopinnan ja getGraphics-metodin piirtopinnan kopioimiseksi.
Miksi Appletit käynnistyvät "epätasaisesti"?:
Olet varmaan huomannut, että joissain tilanteissa Appletti käynnistyy varsinkin animaation osalta vähän ennen aikojaan ja tökkien.
Tämä voidaan estää korvaamalla ImageUpdate-metodi omalla vastaavalla. Tällöin emme anna appletille lupaa käynnistyä ennen aikojaan.
Näin edellisen esimerkin animaation on saatu käynnistymään tasaisesti.
Äänet:
Java 1.1 tukee ainoastaan .au -muotoisten äänitiedostojen esittämistä. .au -tiedostomuoto on kehitetty UNIX-ympäristöjä varten ja se on laadultaan melko huono mm. kehittymättömän pakkustekniikan ansiosta.
.au -tiedostoja voidaan tehdä ja muokata useilla äänenäsittelyohjelmilla, joista yksi on GoldWave.
Java-kielellä voidaan esittää .au - tiedostoja kahdella eri tavalla. Yksinkertaisimmillaan voidaan käyttää Applet-luokan valmista play-metodia, jolloin valittu äänitiedosto soitetaan kertaalleen läpi seuraavan esimerkin mukaisesti:



Toinen tapa on käyttää valmista AudioClip-oliota, jolloin saadaan hieman kehittyneemmät ominaisuudet äänitiedoston soittoon (soitto,toisto ja lopetus).
Seuraava esimerkki havainnollistaa AudioClip-olion käyttöä:



Ja sitten kaikki yhteen
Tehdäänpä seuraavaksi oikeaa multimediaa eli laitetaan säikeiden avulla animaatio ja ääni toimimaan yhdessä:




Jos äänen tulee liittyä johonkin nimenomaiseen tapahtumaan, sen täytyy olla lyhyt ja tulee liittää johonkin sellaiseen käsittelijään, jota suoritetaan jatkuvasti (esim. Paint).
Edellisessä esimerkissä käytimme koodina välkkyvää animaatiota, koska näin saimme koodista hieman lyhyemmän, mutta samalla tavoin ääntä voidaan käyttää kaksoisbufferoidunkin animaation kanssa(huom. se ei välky!).
Jos halutaan toteuttaa esimerkiksi kävelevä ihminen, täytyy ihmisen kävelystä tehdä eri vaiheet (esimerkiksi 10 kuvaa), ladata ne esimerkiksi taulukkoon, jonka alkiot ovat Image-tyyppiä. Paikallaan kävelevä ihminen saataisiin näyttämällä näitä kuvia vuorotellen ja eteenpäin kävelevä ihminen saataisiin siirtämällä lisäksi kuvan piirtokohtaa hieman eteenpäin jokaisen kuvan kohdalla.
Harjoituksia:
| 1. | Muuta animaatioesimerkkejä vaihtamalla animoitavia kuvia. Kokeile myös yhdistää paikallaan olevat ja liikkuvat kuvat. |
| 2. | Kokeile toteuttaa animaationa kävelevä ihminen (tikku-ukko). |
| 3. | Yhdistä multimedia ja tapahtumaohjaus siten, että toteutat jonkin yksinkertaisen pelin. Mieti itse aihe. |
| 4. | Tee appletti, jossa jokin ääni, esimerkiksi oma puheesi, on liitetty erilaisiin käyttäjän tapahtumiin, esimerkiksi painonapin painamiseen. |