# Performance



## JaVa (8. Aug 2004)

Hi!

Mein Pong Spiel wäre jetzt fertig, doch jetzt bin ich auf eines des Lästigsten Probleme gestossen: Die Performance!!!
Im Applet Viewer läuft es ganz gut, obwohl man ein leichtes Ruckeln des Balles sehen kann. Dock kaum verschiebe ich das Fenster (Appletviewer) dann fängt der Ball an mal langsamer mal schneller über den Bildschirm zu fliegen! Das ist total nervig und macht das Spiel unspielbar! Beim Browser, noch schlimmer: da muss man gar nichts machen und der Ball spinnt wie oben beschrieben, nur noch eine Spur radikaler! Ich glaube nicht dass es etwas mit meiner Ball Klasse zu tun hat, wo ich eine Methode schrieb die den Ball bewegt. Ich glaube es liegt in der Hauptklasse! Hier der Code. Ich vermute stark es liegt am Thread!


```
/**
 * @(#)SampleThread.java
 *
 * Sample Applet application
 *
 * @author 
 * @version 1.00 04/08/05
 */
import java.awt.*;
import java.util.*;
import java.applet.*;
import java.net.*;


public class SampleThread extends Applet implements Runnable 
{
	Thread t;
    //int i;
    //DOUBLE-BUFFER
    Image dbImage;
    Graphics dbg;
    
    //SPIELELEMENTE
    ball PongBall;
    player MyPlayer;
    enemy YourEnemy;
    
    //SOUND
    sound Game_sound;
    
    //Zeichensatz
    //noch keiner
	
	public void init()
	{
		PongBall = new ball (200,200);
		MyPlayer = new player (100, PongBall);
		YourEnemy = new enemy();
		Game_sound = new sound ();
		
	    Game_sound.bounce_wall = getAudioClip(getCodeBase(), "wall_bounce2.au");
	    Game_sound.bounce_player_paddle = getAudioClip(getCodeBase(), "player_bounce.au");
		//i = 0;
	}
	
	public void start()
	{
		t = new Thread(this);
		t.start();
	}
	
	public void stop()
	{
		t.stop();
	}
	
	
	
	public void run()
	{
		Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
		while(true)
		{
			//i++;
	
			repaint();
			PongBall.isBallOut(Game_sound, YourEnemy);
			
			PongBall.checkCollision(MyPlayer, Game_sound);
			PongBall.move();
			YourEnemy.move(Game_sound, PongBall);
			
			try
			{
				Thread.sleep(10);
			}	
			catch (InterruptedException e)
			{
				break;
			}
			Thread.currentThread().setPriority(Thread.MAX_PRIORITY);	
		}
	}
	
	public void destroy()
	{
		
	}
	
	public void update (Graphics g)
    {
	  // init of Double Buffer
	  if (dbImage == null)
	  {
        dbImage = createImage (this.getSize().width, this.getSize().height);
		dbg = dbImage.getGraphics ();
	  }

	  // delete image in the background
	  dbg.setColor (getBackground ());
	  dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);

	  // draw foreground on deleted background
	  dbg.setColor (getForeground());
	  paint (dbg);
	
	  // displays complete image on screen
	  g.drawImage (dbImage, 0, 0, this);
    }
	
	
	public void paint(Graphics g)
    {
      g.drawString("SCORE = " + PongBall.player_points, 10, 415);
      g.drawString("COMPUTER SCORE = " + YourEnemy.enemy_score, 350, 415);
      
      //g.drawImage(PCpaddle, x, y, this);
      //g.drawImage(ball, ball_x, ball_y, this);
      PongBall.paint(g);
      MyPlayer.paint(g);
      YourEnemy.paint(g);
      g.setColor(Color.black);
      g.drawRect(10, 10, 475, 385); //draws the game-area tollerating the width/height of the ball!
      
    }
    
    
    public boolean keyDown(Event e, int key)
    {
      if(key == 1005)
      {
      	MyPlayer.moveDOWN();
      }
      if(key == 1004)
      {
      	MyPlayer.moveUP();
      }
	  
      return true;
    }

}
```

Bitte helft mir!
ThX JaVa


----------



## Beni (8. Aug 2004)

Ich kann mir gut vorstellen, dass der Thread mal ab und zu paussiert wird, da der Prozessor auch mal anderes berechnen soll.



			
				JaVa hat gesagt.:
			
		

> Ich glaube nicht dass es etwas mit meiner Ball Klasse zu tun hat, wo ich eine Methode schrieb die den Ball bewegt.



Wie hast du die denn implementiert? Ich hoffe doch stark, dass hier die vergangene Zeit seit dem letzten Aufruf abgefragt wird, und entsprechend diesem Wert die neue Position errechnet wird?


----------



## JaVa (8. Aug 2004)

Hi!

Ich weiss nicht genau, was du meinst, deshalb gebe ich dir den source der Ball-klasse mal hier mit ;-)


```
import java.awt.*;
import java.applet.*;
import java.util.*;
import java.net.*;
//Die Ball-Klasse
public class ball
{
	 
	int ball_x; 				//Startposition x
    int ball_y; 				//       -"-    y
	int ball_width = 5; 		//breite
	int ball_height = 5; 		//höhe
	int ball_speed_x = 3;  		//Geschwindigkeit X
	int ball_speed_y = 3; 		//Geschwindigkeit Y
	int wall_up = 10;			//Die untere Wand
	int wall_bottom = 390; 		//Die obere Wand
	int wall_right = 480;  		//Rechte Wand
	int wall_left = 10;			//Linke Wand
	int ball_top;				//Oberseite des Balles
	int ball_bottom;			//Unterseite des Balles
	int ball_right;				//Rechte Seite des Balles
	int ball_left;				//Linke Seite des Balles
	int player_points = 0;		//shows player score

	public ball(int ball_x, int ball_y)
	{
		this.ball_x = ball_x;
		this.ball_y = ball_y;
	}
	
	public void move()
	{
	    ball_x = ball_x + ball_speed_x;
	    ball_y = ball_y + ball_speed_y;
	    //isBallOut();
	}
	
	public void isBallOut(sound Game_sound, enemy YourEnemy)
	{
		// Ball bewegt sich nach links
		if (ball_speed_x < 0)
		{
			if (ball_x < wall_left)
			{

				// Geschwindigkeit umdrehen
				ball_speed_x = - ball_speed_x;
				Game_sound.bounce_wall.play();
				player_points = player_points - 5;
			}
		}
		// Ball bewegt sich nach rechts
		else if (ball_speed_x > 0)
		{
			if (ball_x > wall_right)
			{
				// Geschwindigkeit umdrehen
				ball_speed_x = - ball_speed_x;
				Game_sound.bounce_wall.play();
				YourEnemy.enemy_score = YourEnemy.enemy_score - 5;
			}
		}

		// Ball bewegt sich nach oben
		if (ball_speed_y < 0)
		{
			if (ball_y < wall_up)
			{
				ball_speed_y = - ball_speed_y;
				Game_sound.bounce_wall.play();
			}
		}
		// Ball bewegt sich nach unten
		else if (ball_speed_y > 0)
		{
			if (ball_y > wall_bottom)
			{
				ball_speed_y = - ball_speed_y;
				Game_sound.bounce_wall.play();
			}
		}
	}
	
	//KOLLISIONSABFRAGE
	public void checkCollision(player MyPlayer, sound Game_sound)
	{
		// Initialisierung der Ballpositionen
		ball_top = ball_y;
		ball_bottom = ball_y + ball_height;
		ball_left = ball_x;
		ball_right = ball_x + ball_width;

		// Initialisierung der momentanen Positionen des Paddels
		MyPlayer.player_paddle_top = MyPlayer.get_player_paddle_y();
		MyPlayer.player_paddle_bottom = MyPlayer.get_player_paddle_y() + MyPlayer.get_player_paddle_height();
		MyPlayer.player_paddle_right = MyPlayer.get_player_paddle_x() + MyPlayer.get_player_paddle_width();

		//Zuerst muss geprüft werde ob die Y-Position des Balles übehaupt zwischen dem Paddle liegt!
		if ((ball_top >= MyPlayer.player_paddle_top - ball_width) && (ball_bottom <= MyPlayer.player_paddle_bottom))
		{
			//Dann kann man abfragen, ob die Y-Position des Balles kleiner (gleich) die des Paddles ist!
			if (ball_left <= MyPlayer.player_paddle_right)
			{
				//In diesem Falle wird der Ball vom Paddle abgelenkt
				ball_speed_x = - ball_speed_x;
				Game_sound.bounce_player_paddle.play();
				player_points = player_points + 10;
			}
		}
	
	}


	
	public void paint (Graphics g)
	{
		g.setColor (Color.red);
		g.fillRect (ball_x, ball_y, ball_width, ball_height);
	}
	
	
	
}
```


Kannst dir ja mal anschaun! Wenn du was erkennst dann bitte melden! Vielen Dank
JaVa


----------



## Beni (8. Aug 2004)

Bei dieser Methode gehst du davon aus, dass das Progi 10 Milisekunden (oder sonst eine konstante Zeit) geschlafen hat.

```
public void move()
   {
       ball_x = ball_x + ball_speed_x;
       ball_y = ball_y + ball_speed_y;
       //isBallOut();
   }
```


Aber das muss nicht unbedingt der Fall sein, externe Ereignisse (z.B. das verschieben eines Fensters) können diese Zeit beeinflussen.

Deshalb schlag ich dir mal vor, sowas auszuprobieren:


```
private long time = -1;

   public void move()
   {
       if( time == -1 )
         time = System.currentTimeMillis();
       else{
         long current = System.currentTimeMillis();

         long delta = (current - time) / 10;  // weil 10 Millisekunden Pause normal sind

         ball_x = ball_x + ball_speed_x * delta;
         ball_y = ball_y + ball_speed_y * delta;

         time = current;
       }
       //isBallOut();
   }
```


----------



## JaVa (8. Aug 2004)

Hi!

Danke, aber das funktioniert auch nicht! Komisch!
wenn jemandem noch was einfällt, dann BITTE posten!

Vielen, vielen Dank!
JaVa


----------



## JaVa (11. Aug 2004)

Hallo,

ich habe den Thread nicht einfrieren lassen, dann funktioniert es tadellos!
das heisst t.sleep(0);

oder gar nicht erst aufrufen ;-)

Gruß JaVa


----------



## Angel (19. Aug 2004)

hmm, ich würde aber mind. 

t.sleep(1);

aufrufen, da sonst die CPU ständig mit 100% ausgelastet ist und es passieren kann, das andere Programme nicht mehr richtig reagieren. So wars bei mir zumindest....


----------

