Buffering

Status
Nicht offen für weitere Antworten.
J

JNille

Gast
also, mein Snooker-Applet is jetzt ein bißl weiter, ich hab mal 10 Kugeln erstellt (mithilfe hunderter for-schleifen, was ziemlich nervt, aber gut).
Und jetzt

- flimmern 1. natürlich die Kugeln, weil sie kurz nach erstellen bereits wieder gelöscht werden, und

- werden sie nicht langsamer, was ich mir nicht erklären kann, in der version mit einer Kugel ging es ja noch... ???:L

also der code, vllt kann ja jemand helfen, wie ich diese probleme löse....

Code:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;


public class Snooker extends Applet
{
 Graphics g;
 Color hellgrün, grün, schwarz, rot, hellrot, weiß;
 Kugel[] k = new Kugel[10];

 public void init()
 {
  for(int i=0; i<k.length-1; i++)
  {
   k[i] = new Kugel();
  }
  for(int i=0; i<k.length-1; i++){
   k[i].x = (int)(Math.random()*(460 - 15)+20);
   k[i].xplus = 1;
   k[i].yplus = 1;
   k[i].y = (int)(Math.random()*(260 - 15)+20);
   k[i].wartezeit = 2;

  }

  g = getGraphics();

  hellgrün = new Color(0,200,0);
  schwarz = new Color(30,30,30);
  rot = new Color(170,0,0);
  hellrot = new Color(255,0,0);
  weiß = new Color(250,250,255);
  grün = new Color(0,120,0);
  /*super.addMouseMotionListener(new MouseMotionListener(){
    public void mouseMoved(MouseEvent evt)
    {
     try{Thread.sleep(100);}
      catch(InterruptedException e){}

     zeichneKugel(evt);
    };
    public void mouseDragged(MouseEvent evt){}
   });
  */

  super.addMouseListener(new MouseListener(){
    public void mousePressed(MouseEvent evt){}
    public void mouseReleased(MouseEvent evt){}
    public void mouseClicked(MouseEvent evt)
    {
    zeichneKugel(evt);
    }
    public void mouseEntered(MouseEvent evt){}
    public void mouseExited(MouseEvent evt){}
   });
 }

 public void zeichneKugel(MouseEvent evt)
 {
  g.setColor(schwarz);
  g.fillRect(10,10,480,280);

  g.setColor(grün);
  g.fillRect(20,20,460,260);

  //g.setColor(hellgrün);
  //g.fillRect(25,30,455,250);      //licht-effekt -naja
  
  

  while(!Thread.interrupted())
  {
   for (int i=0; i<k.length-1; i++){
   k[i].weiter();
   g.setColor(rot);
   g.fillOval(k[i].x,k[i].y,15,15);
   g.setColor(hellrot);
   g.fillOval(k[i].x+2,k[i].y+2,9,9);
   g.setColor(weiß);
   g.fillOval(k[i].x+8,k[i].y+8,4,4);
   
   k[i].warte();
   }
   for (int i=0; i<k.length-1; i++){
   g.setColor(grün);
   g.fillOval(k[i].x,k[i].y,15,15);
   }
  }
 }
 
}

class Kugel
{
 Kugel()
 {
 
 }
 //double nummer;
 Color farbe;
 int x, y, xplus, yplus, wartezeit;

 void warte()
 {
  Thread t = new Thread();
  try{t.sleep(wartezeit);}
  catch(InterruptedException e){
  System.out.println("E!! ");
  };
 }
 void weiter()
 {
  x+=xplus; y+=yplus;
  wartezeit = (int)(wartezeit + Math.pow(wartezeit, 1.7)*.001);
  if(x>=465 || x<=20) xplus = -xplus;
  if(y>=265 || y<=20) yplus = -yplus;
 }
 
}

übrigens: einige zeilen stammen eventuell noch aus vorigen versionen, also stört euch nicht an dem explizit definierten Konstruktor etc....
 
J

JNille

Gast
was is denn? weiß keiner, was ich meine, oder hat keiner lust, sich durch den Code durchzuarbeiten?
-> einfach compilieren und schaun, denk ich, ne.
 

Illuvatar

Top Contributor
So, compiliert, und gewünscht, du hättest dich an die Coding Conventions gehalten :)

Das hier ist jetzt rausgekommen, du kannst sicher noch bissle rumoptimieren :wink: :
Code:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;


public class Snooker extends Applet
{
Graphics g;
static Color hellgrün, grün, schwarz, rot, hellrot, weiß;
Kugel[] k = new Kugel[10];

public void init()
{
  for(int i=0; i<k.length-1; i++)
  {
   k[i] = new Kugel();
  }
  for(int i=0; i<k.length-1; i++){
   k[i].x = (int)(Math.random()*(460 - 15)+20);
   k[i].xplus = 1;
   k[i].yplus = 1;
   k[i].y = (int)(Math.random()*(260 - 15)+20);
   k[i].wartezeit = 2;

  }

  g = getGraphics();

  hellgrün = new Color(0,200,0);
  schwarz = new Color(30,30,30);
  rot = new Color(170,0,0);
  hellrot = new Color(255,0,0);
  weiß = new Color(250,250,255);
  grün = new Color(0,120,0);
  /*super.addMouseMotionListener(new MouseMotionListener(){
    public void mouseMoved(MouseEvent evt)
    {
     try{Thread.sleep(100);}
      catch(InterruptedException e){}

     zeichneKugel(evt);
    };
    public void mouseDragged(MouseEvent evt){}
   });
  */

  super.addMouseListener(new MouseListener(){
    public void mousePressed(MouseEvent evt){}
    public void mouseReleased(MouseEvent evt){}
    public void mouseClicked(MouseEvent evt)
    {
    zeichneKugel(evt);
    }
    public void mouseEntered(MouseEvent evt){}
    public void mouseExited(MouseEvent evt){}
   });
}
private Image dbImage;
private Graphics dbGraphics;

public void zeichneKugel(MouseEvent evt)
{
  //Double-Buffer initialisieren
  if (dbImage == null) {
    dbImage = createImage(
     this.getSize().width,
     this.getSize().height
    );
    dbGraphics = dbImage.getGraphics();
  }
  //Hintergrund löschen
  dbGraphics.setColor(schwarz);
  dbGraphics.fillRect(10,10,480,280);

  dbGraphics.setColor(grün);
  dbGraphics.fillRect(20,20,460,260);

  //g.setColor(hellgrün);
  //g.fillRect(25,30,455,250);      //licht-effekt -naja


  while(!Thread.interrupted())
  {
   for (int i=0; i<k.length-1; i++){
   k[i].weiter();

   k[i].paint (dbGraphics);
   k[i].warte();
   }
   g.drawImage(dbImage,0,0,this);
   for (int i=0; i<k.length-1; i++){
   dbGraphics.setColor(grün);
   dbGraphics.fillOval(k[i].x,k[i].y,15,15);
   }
  }
}

}

class Kugel
{
Kugel()
{

}
//double nummer;
Color farbe;
int x, y, xplus, yplus;
double wartezeit;

void warte()
{
  Thread t = new Thread();
  try{t.sleep((int)wartezeit);}
  catch(InterruptedException e){
  System.out.println("E!! ");
  };
}
void weiter()
{
  x+=xplus; y+=yplus;
  wartezeit = (wartezeit + Math.pow(wartezeit, 1.7)*.005);
  if(x>=465 || x<=20) xplus = -xplus;
  if(y>=265 || y<=20) yplus = -yplus;
}
void paint (Graphics g)
{
  g.setColor(Snooker.rot);
  g.fillOval(x,y,15,15);
  g.setColor(Snooker.hellrot);
  g.fillOval(x+2,y+2,9,9);
  g.setColor(Snooker.weiß);
  g.fillOval(x+8,y+8,4,4);
}
}

Veränderungen:
1. Die Kugeln werden in der Kugel-Klasse gezeichnet.
2. Wartezeit ist ein double und wird jetzt mit .005 und nicht .01 multipilziert.
3. Die Grafikausgabe ist doublegebuffered.

Edit:
Verbesserungsvorschläge:
Die Veränderungen der Kugeln in Threads und
Das Zeichnen der Kugeln in der paint-Methode --> Performance, CPU-Auslastung geht von 100% runter :wink:
 
J

JNille

Gast
ja, sowas hab ich gebraucht...
ok, dann doublebuffere ich demnächst alles so, danke nochmal!

wo hab ich mich denn nicht an irgendwelche vorschriften gehalten? außerdem, der code funktioniert doch, oder :)
ja, und warum hast du die kugeln SO langsam gemacht? was hast du für ein system? :shock: auf meinem Athlon XP 2000+ und mit 256 RAM laufen die kugeln jetzt exxtreem langsam... (außerdem is die angabe doch in ms, also müsste das ding überall prozessorunabhängig gleich schnell laufen, oder -?)
und noch eine letzte sache: is es nicht besser, nicht bei jedem Kugel-objekt ein neues Thread-Objekt zu erstellen, sondern nur eine warte-Methode in der haupt-(Snooker)-klasse?

so in etwa?:
Code:
public class Snooker2 extends Applet{
public void init(){...}
public void warten(int wartezeit)
{
  try{Thread.currentThread.sleep(wartezeit);}
  catch(InterruptedException e){}
}
}
...


sonst erstellt der doch bei jedem aufruf der methode einen thread, oder? naja, also danke jedenfalls, ich mach ma jetz weiter mit kugel-kollisionen, elastischem stoß etc... :) :roll:
 

Illuvatar

Top Contributor
Ich meinte die SUN Coding Conventions, die machen den Code besser lesbar.

Ich hab Athlon2500+ mit 512MB RAM. Ich finds nicht extrem langsam, aber mit .01 hats zu lange gedauert bis es langsamer wurde, war zum Testen schlecht.

Eine Warten-Methode ist natürlich auch gut. Ich meinte, für jede Kugel einen Thread, der dann wartet und wieder das gleiche macht.
 
J

JNille

Gast
Ja, und dann werden die auch nicht mehr alle gleichzeitig bewegt.... (sieht sicher besser aus)
warum is denn die paint()-methode immer so wichtig? warum kann man nich ne eigene methode schreiben, die das Graphics-objekt zutextet? und das bild neu macht?
außerdem is es ja auch so, dass paint immer weiter läuft, auch wenn man das fenster minimiert oder schließen will und dann nachher die kugeln über den weißen screen laufen sieht, die grüne spuren hinter sich herziehen...
also, diese ominöse Convention werd ich mir mal zu gemüte führen.. ;)
[schild=12 fontcolor=0000A0 shadowcolor=B0B0B5 shieldshadow=1]lesbar?[/schild]
 

L-ectron-X

Gesperrter Benutzer
JNille hat gesagt.:
...
warum is denn die paint()-methode immer so wichtig? warum kann man nich ne eigene methode schreiben, die das Graphics-objekt zutextet? und das bild neu macht?
Die paint()-Methode wird vom Browser aufgerufen bzw. wenn man das im Programmcode mit repaint() anfordert, ist ein Teil von java.awt.Component und ihren Child-Klassen und bringt daher entsprechende Funktionaltät mit. Um schnelles Zeichnen zu gewährleisten, sollte sie sich möglichst nur auf das Zeichnen beschränken. Berechnungen und der gleichen sollten, so weit dies möglich ist, in andere Methoden ausgelagert werden.

JNille hat gesagt.:
außerdem is es ja auch so, dass paint immer weiter läuft, auch wenn man das fenster minimiert oder schließen will und dann nachher die kugeln über den weißen screen laufen sieht, die grüne spuren hinter sich herziehen...
In diesem Fall kannst Du die stop()-Methode in Deinem Applet überschreiben und das Applet darin anhalten.
stop() wird vom Browser aufgerufen, wenn Du z.B. die Seite minimierst, das Applet aus dem Anzeigebereich scrollst, oder eine andere Webseite aufrufst. Kommst Du zur Webseite zurück, maximierst Du das Fenster wieder, oder scrollst es wieder in den Anzeigebereich, ruft der Browser die start()-Methode auf. In ihr kann dann das Applet wieder gestartet werden.
Beim Schließen des Browsers wird nach dem Aufruf von stop() auch noch die destroy()-methode aufgerufen, die das Applet anweist, belegten Speicher freizugeben.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben