LE CAPACITA' MULTIMEDIALI DEL JAVA

Negli articoli precedenti abbiamo esplorato le capacità di interattività del Java costruendo delle interfacce, che possono risultare molto utili. Una pagina web, comunque, oltre ad essere utile deve essere attraente e gradevole: questo risultato si ottiene molto più agevolmente se ci sono animazioni e suono, e il Java anche in questo campo può rendersi molto utile.
Normalmente le icone animate vengono ottenute tramite il GIF89, ossia una estensione del comune formato GIF che contiene più di una immagine, in grado di visualizzarle in sequenza.
Questo sistema è perfetto per alcune cose, ma molto limitato. Si pensi soltanto al fatto che non si possono associare effetti sonori sincronizzati nei punti giusti della piccola animazione, e soprattutto che non è possibile alcun cambiamento a seguito di interazione con l'utente.
Supponiamo ad esempio di voler visualizzare una simpatica animazione che rappresenti un operaio che piccona, a simboleggiare i lavori in corso sulla nostra pagina, dove si senta anche il colpo della picconata nel momento giusto.
L'unica soluzione multipiattaforma per questo problema è il Java, specialmente se si volesse aggiungere qualche tocco di interattività, ad esempio l'operaio che si gira verso l'osservatore quando è clickato col mouse.
Lasciando al lettore il compito di aggiungere interattività o altri upgrade, voglio proporre la prima applet, che programmai nel Dicembre 1995, al tempo in cui il Java era sempre alla Alpha version. Si tratta, infatti, di una semplicissima applet che carica una serie di immagini .gif e un campione audio, e visualizza il tutto secondo le nostre preferenze.


Il multithreading.

Il Java supporta il multithreading, ossia la capacità di eseguire contemporaneamente più "flussi di esecuzione". Per esempio possiamo far "partire" un thread che disegna dei quadrati e subito dopo un'altro che disegna dei cerchi, e vedremmo disegnare contemporaneamente cerchi e quadrati. Se cambiamo la priorità tra i thread, potremo veder disegnare più "spesso" una figura rispetto ad un'altra.
Questa caratteristica è molto potente, se ben usata, ma porta anche a molti problemi e difficoltà, legati ai metodi synchronized e ai casi di deadlock (blocco morto).
Per la nostra semplice animazione basterà un singolo thread (monothreading), e in particolare il metodo sleep() che ci permetterà di sospendere e riprendere l'esecuzione del thread, secondo le nostre esigenze di sincronizzazione e velocità di replay.
Per dotare la nostra applet di un thread dobbiamo aggiungere "implements runnable" alla sua definizione, in modo che l'interfaccia runnable venga implementata, col relativo metodo run(). Abbiamo visto che appena l'applet è caricata, viene eseguito il metodo init().
A questo punto il controllo passa al metodo start(), eseguito all'avvio e ad ogni eventuale riavvio, se si torna alla pagina contenente l'applet. Infatti, cambiando pagina l'applet diviene invisibile, ma rimane in funzione, rallentando silenziosamente le operazioni: è per questo che è eseguito il suo metodo stop(), nel quale si fermano le eventuali azioni continue.
Se si torna alla pagina dell'applet col pulsante "back" del browser o da un link, il metodo start() sarà rieseguito, in modo che sia possibile riattivare ciò che si era disattivato con stop().
Sulla rete a volte si trovano applet di animazione programmate in modo approssivativo, non avendo un appropriato start() e stop() per bloccare e riavviare le onerose operazioni di ridisegno continuo: dopo averle caricate, l'unico modo per liberarsi dal rallentamento generale nella navigazione è chiudere e ricaricare il browser. ricapitolando:

public void init() { ... } // operazioni da eseguire
// subito dopo il caricamento.

public void start() { ... } // Avvio (o riavvio) dell'applet

public void stop() { ... } // Arresto dell'applet

E' a questo punto che fa la sua comparsa il thread: nel metodo start() lo istanzieremo e lo faremo partire, mentre nel metodo stop() lo bloccheremo. Il codice del thread si deve trovare nel metodo run(), che viene eseguito una sola volta, quindi metteremo un while() sempre vero in modo da creare un ciclo infinito all'interno del quale inserire il codice per cambire fotogramma adeguatamente. L'unico modo per interrompere l'animazione sara' quello di cambiare pagina.
Per evitare che i fotogrammi siano scambiati troppo velocemente, è indispensabile far "addormentare" il thread col metodo sleep(numero microsecondi da attendere), che è posto strategicamente tra uno scambio e l'altro.


Il caricamento delle immagini.

Caricare grafica dalla rete è molto semplice, basta usare il metodo getImage(), e controllare lo stato del caricamento con il mediatracker. In pratica, basta dichiarare un array di immagini grande abbastanza da contenere tutti i fotogrammi, che nel nostro caso sono .gif, ma potrebbero anche essere .jpg.
A questo punto con getImage(URL immagine da caricare) si fa iniziare il caricamento. Attenzione al fatto che il programma continua l'esecuzione dopo il getImage() anche se il caricamento non è terminato, e ci si può trovare a visualizzare l'animazione con i fotogrammi caricati solo in parte. Per attendere il termine del caricamento è sufficiente "puntare" un mediatracker sull'immagine in caricamento e attendere il completamento tramite il metodo waitForID(numero ID selezionato precedentemente con addImage):

mTracker.addImage(imgs[i], i);
try {
mTracker.waitForID(i);
}
catch(Exception e) {}

In questo modo continuiamo l'esecuzione solo ad immagini completamente caricate.


Il caricamento dei suoni.

La gestione dell'audio in Java non è molto elaborata, almeno nella versione attuale, dato che sono supportate riproduzioni soltanto di suoni mono a 8000 Hz in formato .AU, un formato proprietario della Sun. E' possibile suonare più campioni contemporaneamente, ma la sincronizzazione non è eccelsa.
Comunque, anche se per una gestione audio di qualità MIDI probabilmente dovremo aspettare Java 2.0, per suonare un colpo di piccone al momento giusto è più che sufficiente.
Ecco come si dichiara, carica e suona un campione audio (detto AudioClip):
AudioClip suono = null;
suono = getAudioClip(base, "audio/piccon.au");
suono.play();

Probabilmente è più complesso ottenere l'AudioClip in formato .AU: avrete sicuramente presenti i più comuni formati .waw, .voc e .iff usati per i campioni audio, ma i programmi di campionamento quasi mai salvano direttamente in .au.
Nessun problema, basta munirsi di un programma in grado di convertire i .waw in .au, ad esempio il GoldWave:

Goldwave page

Ricordatevi di scalare il campione a 8000 Hz mono prima di salvare.


Istruzioni d'uso dell'applet.

Alcuni parametri sono modificabili da HTML (listato 2), mentre altri, come il colore di sfondo, solo da sorgente .java (listato 1).
Ricordatevi che i tag WIDTH e HEIGHT dell'applet devono indicare la grandezza esatta dei fotogrammi.
Col paramentro "img" si indica il nome dell'animazione, e l'eventuale subdirectory dove si trova. Nel nostro esempio i fotogrammi si trovano nella subdirectory /anim e i fotogrammi si chiamano ani0.gif, ani1.gif eccetera, quindi il parametro da inserire è "anim/ani". Da notare che si usa / e non \, secondo lo standard unix. I parametro "quantifr" indica il numero di fotogrammi, il parametro "veloc" indica i millisecondi da attendere tra un fotogramma e l'altro, mentre il parametro "pausa" indica la pausa in millisecondi che si deve attendere alla fine dell'animazione prima di ricominciare.
Il movimento di un operaio che piccona è del tipo detto "ping-pong", quindi è implementato questo tipo di animazione.
Le animazioni possono essere cicliche (ossia si parte dal primo fotogramma e si visualizzano in sequenza tutti gli altri, fino all'ultimo, dopo il quale si riparte dal primo e così via), o ping-pong, cioè si parte dal primo fotogramma e si visualizzano in sequenza tutti gli altri, ma quando si arriva all'ultimo si rivisualizzano tutti tornando indietro fino al primo, per poi ripartire tornando "avanti", proprio come la pallina in una partita di ping-pong.
In questo modo basta fare i fotogrammi del piccone che va verso il basso, poi per farlo "risalire" basterà far rivedere i fotogrammi all'indietro, dimezzando il numero di immagini gif richieste.
Partendo da questa semplice applet si possono creare molte animazioni con sonoro, interattive o meno, per abbellire e rendere più singolare un sito web.
Facendo un ulteriore passo in avanti, è possibile anche eseguire delle operazioni di distorsione, ondeggiamento ecc. sulle immagini visualizzate, come potete vedere, ad esempio, nella mia home page.

Fabio Ciucci
fabioc@anfiteatro.it


Scarica il listato 1: ANanim2b.java

Scarica il listato 2: ananim2b.html


Torna all' indice degli articoli