Newsgroup: it.comp.java
Titolo: BufferedImage invisibili..

Salve,
sto sviluppando un gioco 2d e mi sono imbattuto in questo strano problema.
Ho realizzato una classe statica che gestisce le texture.
In pratica quando la istanzio non fa altro che andare a cercare in un 
file di configurazione i path delle texture disponibili. Poi per ognunga 
crea una BufferedImage apposita e la memorizza in una hashtable. Così ho 
pensato che in pratica mi tengo in memoria sempre l'immagine 
direttamente utilizzabile evitando quindi di ricaricarla da disco ogni 
volta che devo disegnarla...sbaglio?
Ora tutto sembra funzionare perchè al momento di usare una texture la 
richiedo alla hashtable con la chiave giusta e me la ritorna esattamente...
A questo punto la passo alla Graphics che si occupa di disegnarla con il 
metodo drawImage(), solo che 9 volte su 10 non la disegna!! E' come se 
perdesse l'immagine!!
Inoltre se prima di richiedere la texture alla hashtable faccio in modo 
che le texture siano ricaricate da disco, ritrasformate di nuovo in 
BufferedImage e reinserite nella hashtable... allora tutto magicamente 
funziona!!
Qualche idea?
Grazie a tutti,
Jack

 funziona!!
Questo mi fa venire un sospetto. Forse in questo caso, essendo il tempo 
di caricamento da disco molto maggiore, fai in tempo a vedere l'immagine
precedentemente caricata prima che venga sostituita dalla nuova. Però 
bisognerebbe vedere un po' di codice...
pole
-- 
ammentos - a lightweight persistence framework for JDK5
http://ammentos.biobytes.it
Flash tutorial: 
http://ammentos.biobytes.it/quickstart/quickstart.htm

pole wrote:
 > Ciao, sembrerebbe un problema di sincronizzazione. Bisognerebbe vedere
 > il codice perlomeno del loop principale di disegno. Non ho ben capito 
 > se stai utilizzando la tecnica del double buffering (in tal caso
 > bisognerebbe vedere come stai spostando a video il buffer).
Beh a dire la verità non credo che stiamo usando direttamente il double 
buffer, o per lo meno non o stiamo facendo volontariamente perchè non 
sappiamo come farlo esattamente in java.
 >> Inoltre se prima di richiedere la texture alla hashtable faccio in
 >> modo che le texture siano ricaricate da disco, ritrasformate di 
nuovo >> in BufferedImage e reinserite nella hashtable... allora tutto
 >> magicamente funziona!!
 > Questo mi fa venire un sospetto. Forse in questo caso, essendo il
 > tempo di caricamento da disco molto maggiore, fai in tempo a vedere
 > l'immagine
 > precedentemente caricata prima che venga sostituita dalla nuova. Però
 > bisognerebbe vedere un po' di codice...
Dunque. Il ciclo che disegna è semplicemente dentro il metodo 
paintComponent() ridefinito per il JPanel in cui voglio applicare queste 
texture. Quindi ogni volta che l'applicazione fa repaint() viene 
ridisegnato tutto con queste benedette texture fantasma!
Per questo ho pensato di usare una sorta di gestore delle texture che le 
carica in memoria sottoforma di immagini fin dall'avvio e poi i vari 
oggetti che necessitano di texture non fanno altro che accedere 
all'immagine voluta (contenuta in una hashtable) e disegnarla quanto e 
dove vuole.
Il problema appunto è che quasi mai vengono disegnate le texture ma al 
loro posto ci sono caselle nere...è questo che mi spiazza...in realtà 
quindi viene caricata l'immagine giusta ma quando la visualizza è nera.
Ho provato a fare due test:
1) nel punto in cui creo la BufferedImage dal file immagine su disco per 
trasferirla poi nella hashtable, ho sostituito tale creazione con dei 
semplici rettangoli blu (g.fillRect()). In pratica così nella hashtable 
ho solo degli stupidi rettangolini blu come texture, sempre sottoforma 
di BufferedImage. Tuttavia per non falsare nulla, carico comunque le 
vere texture da disco però poi non le trasformo in 
BufferedImage...insomma la complessità dell'operazione dovrebbe rimanere 
la stessa no? Bene il risultato è che le texture blu funzionano benissimo!
2) ho semplificato al massimo. Ho la mia classe statica per la gestione 
delle texture identica a prima, che quindi legge le texture da file su 
disco, le trasforma in BufferedImage e le memorizza in una hashtable. 
Però ora ho provato semplicemente a disegnare un rettangolo con una 
textura in un frame...insomma ho tolto tutta l'interfaccia grafica, ho 
solo ridefinito il metodo paintComponent() e dentro disegno un 
rettangolo con una texture...risultato: non funziona, di nuovo un 
rettangolo nero...eppure qui si tratta di caricare 1 immagine e 
disegnarla 1 volta e basta!
PS: ho evitato di postare il codice ora vista la lunghezza del post..
ma se serve lo posto :)
Jack

A causa di problemi sul news server questo post ieri non è arrivato. Eccolo:
Jack wrote:
 > Beh a dire la verità non credo che stiamo usando direttamente il 
double buffer, o per lo meno non o stiamo facendo volontariamente perchè 
non sappiamo come farlo esattamente in java.
Il concetto di base è banale: fai tutte le operazioni di disegno nel 
buffer invisibile, cosicché mentre l'immagine precedentemente 
visualizzata sta ancora impressionando la retina tu stai preparando la 
successiva. Una volta terminata la nuova immagine sul buffer la stampi a 
video e così via.
 > Dunque. Il ciclo che disegna è semplicemente dentro il metodo 
paintComponent() ridefinito per il JPanel in cui voglio applicare queste 
texture. Quindi ogni volta che l'applicazione fa repaint() viene 
ridisegnato tutto con queste benedette texture fantasma!
Temo che questo non sia il metodo più indicato per questo genere di 
cose. Per i giochi è decisamente più conveniente sfruttare altre strade 
rispetto a quelle utilizzate da swing.
Ecco un articolo con un bel po' di codice interessante:
http://www.gameprog.it/?resource=995


 perdesse l'immagine!!
Inserisci questo nel paint, supponendo che l'immagine si chiami... immagine:
      try
       {
        MediaTracker track=new MediaTracker(this);
        track.addImage(immagine,0);
        track.waitForID(0);//aspetta a disegnare che l'immagine sia 
completamente caricata
       }
      catch(InterruptedException e) {System.out.println("Errore");};