Oppure

Loading
02/04/09 17:36
Anonymous
Salve gente... premettendo che col java sono alle prime armi... vorrei chiedervi in che modo si può togliere il fastidioso sfarfallio di un applet quando ad esempio si simula il movimento di qualche pallina.. ecco qua il codice dell'applet sfarfallante...
package appletpallina;
import java.awt.*;
import java.applet.Applet;

class Pallina {
    int x,y;
    int vx, vy;
    int diametro;
    Color colore;
    Pallina(int x, int y, int diametro, Color colore){
        this.x=x;
        this.y=y;
        vx=(int)(Math.random()*5+1);
        vy=(int)(Math.random()*5+1);
        this.colore=colore;
        this.diametro=diametro;
    }
}

class Movimento extends Thread{
    Pallina p;
    AppletPallina applet;
    boolean stopped=false;

    Movimento(AppletPallina applet,int x, int y, int diametro,Color colore){
        this.applet=applet;
        p=new Pallina(x,y,diametro,colore);
    }
    public void run(){
        int ampiezza=applet.getWidth();
        int altezza=applet.getHeight();
        for(;;){
            applet.repaint();
            try{
                Thread.sleep(10);
            }catch (InterruptedException e){
            }
            if(p.x+p.diametro>=ampiezza){
                p.vx=-p.vx;
                p.colore=(new Color((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255)));

            }
            if(p.y+p.diametro>=altezza){
                p.vy=-p.vy;
                p.colore=(new Color((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255)));
            }
            if(p.x<0 && p.vx<0){
                p.vx=-p.vx;
                p.colore=(new Color((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255)));
            }
            if(p.y<0 && p.vy<0){
                p.vy=-p.vy;
                p.colore=(new Color((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255)));
            }
            p.x=p.x+p.vx;
            p.y=p.y+p.vy;
            if (stopped)
                break;
        }
        System.out.println(getName()+" fermato");
    }
}


public class AppletPallina extends Applet {
    final int n=20;
    Movimento vettore[]=new Movimento[n];
 
    public void init() {

        
        for (int i=0;i<n;i++){
            vettore[i]=new Movimento (this, 10, 10, 50, Color.YELLOW);
            vettore[i].start();
        }
    }

    public void paint(Graphics g){
        g.clearRect(0,0,getWidth(),getHeight());

        
        for (int i=0;i<n;i++){
            g.setColor(vettore[i].p.colore);
            g.fillOval(vettore[i].p.x, vettore[i].p.y, (int)(vettore[i].p.diametro), (int)(vettore[i].p.diametro));
        }        
    }
    public void stop(){
        try{
            for (int i=0;i<n;i++){
                vettore[i].stopped=true;
                vettore[i].join();
                vettore[i]=null;
            }
        }
        catch (InterruptedException e){
        System.out.println("Si è verificato un errore");
        }
    }
    
}

aaa
03/04/09 7:31
netarrow
devi usare il doppio buffering.
cioè invece di scrivere direttamente nel Graphics dello schermo crei un'oggetto ImageBuffer, disegni sul suo Graphics e alla fine disegni l'ImageBuffer sullo schermo, così viene disegnato a schermo l'immagine già pronta a non c'è più sfarfallio.
aaa
03/04/09 17:48
Anonymous
ho provato a creare un nuovo oggetto di tipo ImageBuffer... ma netbeans me lo segnala errore..

aaa
03/04/09 18:49
netarrow
scusa ho controllato il nome corretto della classe è BufferedImage
aaa
03/04/09 19:09
Anonymous
ok.. quindi una volta che faccio

BufferedImage antiSfarfallio = new BufferedImage(...);

dentro che parametri gli servono??

e poi dopo per fargli disegnare dentro a quell'oggetto devo fare così?

for (int i=0;i<n;i++){
            aniSfarfallio.setColor(vettore[i].p.colore);
            aniSfarfallio.fillOval(vettore[i].p.x, vettore[i].p.y, (int)(vettore[i].p.diametro), (int)(vettore[i].p.diametro));
        }     


al posto di:

for (int i=0;i<n;i++){
            g.setColor(vettore[i].p.colore);
            g.fillOval(vettore[i].p.x, vettore[i].p.y, (int)(vettore[i].p.diametro), (int)(vettore[i].p.diametro));
        }     


???
aaa
04/04/09 10:54
netarrow
Inizializzi così:

        BufferedImage buffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Graphics gbuf = buffer.getGraphics();


dove w è la larghezza e h l'altezza dell'immagine di buffering (che sarà la dimensione del pannello su cui disegni) e il terzo è la modalità di rappresentazione dell'immagine mettendo RGB ha i solito colori rappresentati da rosso verde blue da 0 a 255.

A questo punti dentro al metodo paint invece di fare direttamente le operazioni su g le fai su gbuf, e alla fine fai

g.drawImage(buffer);
aaa
04/04/09 11:42
Anonymous
sul
g.drawImage(buffer); 


mi chiede altri parametri oltre alla variabile buffer...
e provando a mettere
g.drawImage(buffer, 0, 0, this);


lo sfarfallio mi fa peggio di prima perché mi si visualizzano strisce e basta, ogni tanto qui e ogni tanto li ma globalmente l'applet rimane bianco... XD
Ultima modifica effettuata da Anonymous 04/04/09 11:45
aaa
04/04/09 12:10
netarrow
le modifiche da fare sono queste:

...
	BufferedImage buffer;
	Graphics gbuf;
	
    public void init() { 
		buffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
		gbuf = buffer.getGraphics();
		
        for (int i=0;i<n;i++){ 
            vettore[i]=new Movimento (this, 10, 10, 50, Color.YELLOW); 
            vettore[i].start(); 
        } 
    } 
	
    public void paint(Graphics g){
        gbuf.clearRect(0,0,getWidth(),getHeight()); 
		
		
        for (int i=0;i<n;i++){ 
            gbuf.setColor(vettore[i].p.colore); 
            gbuf.fillOval(vettore[i].p.x, vettore[i].p.y, (int)(vettore[i].p.diametro), (int)(vettore[i].p.diametro)); 
        } 
        g.drawImage(buffer, 0, 0, this);
    } 
...


Per sicurezza ho pure provato il codice e funziona senza sfarfallii.
aaa