Il JDK mette a disposizione molti strumenti per trattare con efficacia grafica e animazioni, tanto da consentirci di avere nel nostro browser degli effetti simili a quelli dei famosi "DEMO" scritti in C o Assembler. In questo articolo verrà presentata un applet che simula la neve che cade e che interagisce con quello che trova sul suo percorso.

Le classi utilizzate

In questo articolo esamineremo brevenente le classi MemoryImageSource e PixelGrabber e il loro utilizzo per costruire la nostra l'applet natalizia.*

Queste due classi fanno parte del package java.awt.image.\* e consentono qualsiasi elaborazione di un immagine (limitatamente alle prestazioni ), riferendoci ad essa attraverso un vettore di interi.

  • Esaminiamo prima la MemoryImageSource che permette di creare un immagine a partire un vettore di interi opportunamente dimensionato, per esempio il seguente spezzone di codice alloca con questa tecnica un immagine 100x100:
...........

int[]

pixels;

pixels

= new int[100 * 100];

/*

il primo e il secondo parametro sono la larghezza e l'altezza,il terzo

è il vettore, il quarto l'offset e l'ultimo la larghezza dell'immagine

*/

MemoryImageSource

imgsrc = new MemoryImageSource(100, 100, pixels, 0, 100);

Image

memimg = createImage(imgsrc);

imgsrc.setAnimated(true);

...........

> Il metodo setAnimated (introdotto con il JDK 1.1) settato a true fa in modo che ogni volta che si richiama il metodo newPixels l'immagine a video venga aggiornata con le informazioni che si trovano nel vettore che contiene il colore di ogni pixel.

> Il codice che segue mostra come tracciare una linea obliqua dall'angolo superiore sinistro all'angolo inferiore destro di colore nero:

......

Color

nero = new Color(0,0,0);

for

(int x=0;x<100;i++)

pixels[x

* 100 + x] = nero.getRGB();

/*

newPixels( "area da aggiornare, in questo caso tutta l'immagine"); */

imgsrc.newPixels(0,0,100,100);

.........

> NOTA: per individuare i pixel nell'array ho usato questa conversione:

> > Il pixel con coordinate X,Y si trova alla posizione > > > y \* Larghezza + x del vettore dove la variabile larghezza è la larghezza dell'immagine.

  • Invece la PixelGrabber consente di copiare un oggetto Image in un buffer che per i nostri scopi può essere ancora una volta il solito array, per esempio:
Image

img = getImage(getDocumentBase(),nome_immagine);

pg

= new PixelGrabber(img, 0, 0, LARGHEZZA, ALTEZZA, pixels, 0, LARGHEZZA);

Il frammento di codice sopra riportato trasforma l'immagine in una sequenza

di interi che vengono copiati nell'array "pixels" consentendo di

elaborare facilmente l'immagine agendo sul vettore in questione.

...LA TEMPESTA DI NEVE

Presa un pò di confidenza con queste due classi che il JDK ci mette a disposizione, è facile ideare un algoritmo che simuli la neve che cade; quella che segue è l'analisi per punti dell'algoritmo, per i dettagli implementativi rimando al codice sorgente completo snow.java.

  • Prima di tutto le strutture dati fondamentali sono due array di interi:
x

= new int[MAX_FIOCCHI];

y

= new int[MAX_FIOCCHI];

che andranno a contenere le coordinate di ogni fiocco di neve;

Occorreranno anche altri due vettori che serviranno uno come maschera, e l'altro come buffer per la visualizzazione a video che dovranno essere opportunamente dimensionati per contenere l'immagine scelta.

pixels

= new int[ALTEZZA * LARGHEZZA];

maschera

= new int[ALTEZZA * LARGHEZZA];

Ora usando la classe MemoryImageSource come visto, creiamo una Image a partire dal vettore "pixels" e dopo aver caricato un immagine da usare come sfondo, utilizzando la classe PixelGrabber la riversiamo nel vettore "maschera" che ci servirà in seguito.

A questo punto inizializziamo le coordinate dei fiocchi di neve con dei valori random che per le x saranno compresi tra 1 e la larghezza dell'immagine utilizzata e per le y tra 1 e circa 1/5 dell'altezza.

Adesso ci servirà una funzione che ogni volta muova i fiocchi di neve ad ogni iterazione sapendo che se nel vettore "maschera" c'è il colore nero allora significa che non c'é nessun ostacolo e quindi il fiocco può proseguire per la sua strada, altrimnti se il colore è diverso dal nero vuol dire che c'è un ostacolo e quindi si dovrà deviare.

Schematicamente

per ogni fiocco di neve faccio i seguenti controlli:

Se

il pixel immediatamente sotto il fiocco è nero (

cioè "maschera[(y[i]+1) * LARGHEZZA + x[i]] == nero.getRGB()") allora

possiamo proseguire e incrementiamo la coordinata y del nostro fiocco di

neve;

Altrimenti

controllo con lo stesso metodo se i pixel immediatamente più in

basso a destra e a sinistra sono liberi e in caso affermativo rispettivamente

incremento o decremento la coordinata x di 1 e in etrambi i casi incremento

la y.

Se

neanche il punto (2) ha avuto successo allora il fiocco di neve è

arrivato in fondo e non si può muovere, quindi lo si memorizza

nella maschera (per tenerne conto alla prossima iterazione) e lo si rigenera

in modo casuale.

  • Fatto questo non ci resta che inserire la funzione di movimento in un thread che la richiami ciclicamente e aggiorni ogni volta il video.

...e siamo pronti per dare il buon natale ai visitatori del nostro sito con questo nuovo effetto.

CONCLUSIONI

Questa applet non vuole essere niente di più che l'ennesimo esempio di come con un pò di fantasia e poche righe di java si può abbellire una pagina web (magari nel periodo natalizio) mentre l'articolo introduce le due classi MemoryImageSource e PixelGrabber messe a disposizione dal JDK per l'elaborazione delle immagini.

Ora non mi resta che augurare a tutti buon natale e felice 1998!