Timer nur 64 mal pro Sekunde?

Status
Nicht offen für weitere Antworten.
G

Guest

Gast
Hallo,

Ich wusste nicht wie ich es nennen sollte...

Ich schreibe zur Übung ein Spiel (2 Flugzeuge die sich gegenseitig bekämpfen).
Ich nutze einen Timer damit ich die Geschwindigkeit regeln kann, d.h. z.B. alle 20ms werden die Flugzeuge etc. bewegt.
Folgendes Problem:
Auf meinem Athlon 750MHz mit Suse Linux 9.0 und Java 1.5 bekomme ich bei delay=0 ca.250 Bilder pro Sekunde.
Auf meinem AthlonXP 2500+ mit WindowsXP und Java 1.5 bekomme ich bei delay=0 genau 64 Bilder pro Sekunde und ich habe eine CPU-Auslastung von <2%.
Wenn ich die Rechenlast erhöhe geht auf dem Athlon 750 die Anzahl der Bilder zurück, beim AthlonXP 2500+ kann ich die Rechenleistung vervielfachen ohne das die Anzahl der Bilder fällt.

Irgendwie sind die Anzahl der Bilder also auf 64 pro Sekunde begrenzt.


Irgendeine Idee was das sein könnte?


mfg
Christian
 
G

Guest

Gast
Sorry, musste kurz weg.
Hier noch eine Ergänzung:
Zur Bestimmung der Anzahl Bilder pro Sekunde verwende ich einen 2.Timer mit 1 Sekunde Delay.
Jedes mal wenn Timer1 ausgeführt wird zähle ich eine Variable hoch, wenn Timer 2 ausgeführt wird gebe ich den Wert aus.
Das Programm läuft auch tatsächlich langsamer, die Anzeige stimmt also!


Das ganze spielt sich in einem JFrame ab, frühere Versionen liefen als Applet, da hatte ich die Probleme nicht.
Irgendwann gingen dann plötzlich (Abends PC heruntergefahren, morgens ging es nicht mehr) z.B.alle JOptionPanes nicht mehr (in allen Java-Programmen) und ich habe nach mehreren vergeblichen Versuchen Java für 1 Monat beiseite gelegt.
Jetzt laufen alle Programme wieder, außer das Applet (ich vermute fehlende Zugriffsrechte bzw. Sicherheistregelungen die das lesen der Dateien verhindert), also bin ich auf JFrame umgesteigen.
Der Programmverlauf des Applets und des JFrames ist praktisch identisch, ich habe schon sofort nach der "Konvertierung" auf JFrame (es mussten nur wenige Zeilen geändert werden) diese Begrenzung auf 64 Bilder pro Sekunde bemerkt...
Ich verwende nicht die paintComponent Methode, sondern "male" alles manuell, z.B. wenn etwas gelöscht werden soll wird es weiß übermalt.


mfg
Christian
 

Nova

Bekanntes Mitglied
Hallo,

Hat denn niemand eine Ahnung woran das liegen könnte?
(Ist mein Beitrag, war noch nicht registriert).


mfg
Christian
 

Wildcard

Top Contributor
Also zum Einen halte ich es für unrealistisch ein Spiel in Java mit 250fps zeichnen zu können und hege deshalb
starke Zweifel an der Richtigkeit deiner Messung, zum Anderen sind 64fps(falls das korrekt ist) doch mehr als genug, also versteh ich das Problem nicht...
 

Nova

Bekanntes Mitglied
Hallo,

Das Spiel ist ja noch bei weitem nicht fertig und ich habe mir alle Mühe gegeben bisher so wenig Rechnezti wie möglich zu verbauchen um später mehr für KI etc. übrigzuhaben.
Die 250fps stimmen!
Ich hab ja geschrieben wie ich es mache (mit 2 Timern) und das es am 750MHz Athlon vieeeel schneller läuft als auf meinem AthlonXP 2500+.


Bisher habe ich die fps-Anzeige immer benutzt um zu erkennen wieviel CPU-Last ich verursache. Gerade wenn man was neues einbaut ist es doch gut zu wissen wieviel CPU-Last es braucht und somit den Code vielleicht sofort umändert, im nachhinein wäre es viel schwieriger den Code zu ändern bzw. überhaupt zu finden warum es so langsam ist...
Später will ich eventuell nur z.B. alle 5 Bilder zeichnen und die gesparte Rechenzeit für bessere KI etc. nutzen, dann reichen 64 "actionEvents" des Timers nicht mehr.


mfg
Christian
 

Wildcard

Top Contributor
Mit Timern und Zählvariablen die tatsächlichen frames zu ermitteln ist nicht einfach (falls das überhaupt geht),
also stell doch mal bitte den Code hier rein...
 

Nova

Bekanntes Mitglied
Hallo,

Hier mal der Code aus der Klasse in der die beiden Timer sind, den ganzen Code zu posten würde zuweit führen (>1000 Zeilen)

Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.Timer;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.LinkedList;
import javax.swing.JOptionPane;

public class PaintPanel extends JPanel implements KeyListener{

    public static int[][] matrix;
    public final static int MAX_WIDTH = 1000, MAX_HEIGHT = 600;
    private final int DELAY = 0;
    private Flugzeug flugzeug1, flugzeug2;
    private Timer timer1, timer2;
    private int fps, fps_alt;
    
    public PaintPanel(){
        matrix = new int[MAX_WIDTH][MAX_HEIGHT];
        timer1 = new Timer(DELAY, new TimerListener1());
        timer2 = new Timer(1000, new TimerListener2());

	    Point p1 = new Point(80,MAX_HEIGHT/2);
     	Point p2 = new Point(MAX_WIDTH-80,MAX_HEIGHT/2);
	    flugzeug1 = new Flugzeug(p1,10000,0,1, matrix);
	    flugzeug2 = new Flugzeug(p2,20000,180,1, matrix);
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        flugzeug1.setGraphics(getGraphics()); // Graphik neu übergeben, erst hier möglich!
        flugzeug2.setGraphics(getGraphics()); // Graphik neu übergeben, erst hier möglich!
	    timer1.start(); // Timer starten (vorher nicht möglich da erst die Graphik übergeben werden muss)
	    timer2.start(); // Timer starten (vorher nicht möglich da erst die Graphik übergeben werden muss)
	    
	    setBackground(Color.white);
    	// Begrenzung
        for (int x = 0; x <= (MAX_WIDTH)-1; x++){
	        matrix[x][0] = 1;
	        matrix[x][1] = 1;
	        matrix[x][2] = 1;
	        matrix[x][3] = 1;
	        matrix[x][MAX_HEIGHT-1] = 1;
	        matrix[x][MAX_HEIGHT-2] = 1;
	        matrix[x][MAX_HEIGHT-3] = 1;
	        matrix[x][MAX_HEIGHT-4] = 1;
        }
	    for (int y = 0; y <= (MAX_HEIGHT)-1; y++){
	        matrix[0][y] = 1;
	        matrix[1][y] = 1;
	        matrix[2][y] = 1;
	        matrix[3][y] = 1;
	        matrix[MAX_WIDTH-1][y] = 1;
	        matrix[MAX_WIDTH-2][y] = 1;
	        matrix[MAX_WIDTH-3][y] = 1;
	        matrix[MAX_WIDTH-4][y] = 1;
	    }
        for (int x = 0; x <= MAX_WIDTH-1; x++){
	        for (int y = 0; y <= MAX_HEIGHT-1; y++){
	            int wert = matrix[x][y];
		        if (wert == 1){
		            g.setColor(Color.black);
		            g.drawRect(x,y,0,0);
		        }
	        }
	    }
    }

    public void keyPressed(KeyEvent event){
	if (event.getKeyCode() == KeyEvent.VK_P){
	    if (timer1.isRunning()){
	        timer1.stop();
    		timer2.stop();
    	} else {
	        timer1.start();
            timer2.start();
    	}
    }

    	// Flugzeug 1:
    	if (event.getKeyCode() == KeyEvent.VK_UP){
    	    flugzeug1.setSpeed_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_DOWN){
    	    flugzeug1.setBreak_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_LEFT){
    	    flugzeug1.setLeft_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_RIGHT){
    	    flugzeug1.setRight_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_SPACE){
    	    flugzeug1.setFire1_key_pressed(true);
    	}

    	// Flugzeug 2:
    	if (event.getKeyCode() == KeyEvent.VK_W){
    	    flugzeug2.setSpeed_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_S){
    	    flugzeug2.setBreak_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_A){
    	    flugzeug2.setLeft_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_D){
    	    flugzeug2.setRight_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_CONTROL){
    	    flugzeug2.setFire1_key_pressed(true);
	    }
    }

    public void keyReleased(KeyEvent event){
        // Flugzeug 1:
    	if (event.getKeyCode() == KeyEvent.VK_UP){
    	    flugzeug1.setSpeed_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_DOWN){
    	    flugzeug1.setBreak_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_LEFT){
    	    flugzeug1.setLeft_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_RIGHT){
    	    flugzeug1.setRight_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_SPACE){
    	    flugzeug1.setFire1_key_pressed(false);
    	}
        // Flugzeug 2:
    	if (event.getKeyCode() == KeyEvent.VK_W){
    	    flugzeug2.setSpeed_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_S){
    	    flugzeug2.setBreak_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_A){
    	    flugzeug2.setLeft_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_D){
	        flugzeug2.setRight_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_CONTROL){
    	    flugzeug2.setFire1_key_pressed(false);
    	}
    }

    public void keyTyped(KeyEvent event){}

    private class TimerListener1 implements ActionListener{
        public void actionPerformed(ActionEvent event){
	        fps++;
	        flugzeug1.moveFlugzeug(); // Flugzeug 1 bewegen
	        flugzeug2.moveFlugzeug(); // Flugzeug 2 bewegen
	        double schaden1 = flugzeug1.moveWeapon1(); // Geschosse von Flugzeug1 bewegen und angerichteten Schaden speichern
	        if (schaden1 != 0){
	        	flugzeug2.damaged(schaden1);
	        }
	        double schaden2 = flugzeug2.moveWeapon1(); // Geschosse von Flugzeug2 bewegen und angerichteten Schaden speichern
	        if (schaden2 != 0){
	        	flugzeug1.damaged(schaden2);
	        }
	        flugzeug1.paintStatus(new Point(20,20)); // Status Flugzeug 1 zeichnen
	        flugzeug2.paintStatus(new Point(MAX_WIDTH-100,20)); // Status Flugzeug2 zeichnen
	    }
    }

    private class TimerListener2 implements ActionListener{
        public void actionPerformed(ActionEvent event){
	    // fps:
	        Graphics g = getGraphics();
	        if (fps != fps_alt){
                g.setColor(Color.white);
 	            g.drawString("fps: " + fps_alt,20,MAX_HEIGHT-20);
	            fps_alt = fps;
	        }
            g.setColor(Color.black);
 	        g.drawString("fps: " + fps,20,MAX_HEIGHT-20);
	        fps = 0;
    	}
    }
}


Das Programm läuft auf dem Athlon 750MHz auch um ein vielfaches schneller als auf dem 2500+, d.h. an einem "Messfehler" kann es nicht liegen.


mfg
Christian
 

Wildcard

Top Contributor
Was du da misst hat nicht das geringste mit den fps zu tun :lol:
Du rechnest dir aus wie oft ein Timer der OHNE delay gestartet wird in einer sekunde aufgerufen wird.
Das hat überhauptkeinen Bezug zum zeichnen des Bildes.
 

Nova

Bekanntes Mitglied
Hallo,

"Malen" tun die Methoden selbst, z.B. flugzeug1.moveFlugzeug(), flugzeug1.moveWeapon() oder flugzeug1.paintStatus(). (paintComponent wird momentan nur einmal beim start des Programms aufgerufen)
Diese Methoden werden im TimerListener1 aufgerufen, wenn diese abgearbeitet wurden wird der TimerListener1 sofort wieder aufgerufen (wegen DELAY = 0).
Der TimerListener2 wird jede Sekunde aufgerufen, und zählt wie oft TimerListener1 in dieser Sekunde aufgerufen wurde (also wieviele Bilder gezeichnet wurden, oder sehe ich da was falsch?).
Die CPU-Auslastung ist ja auch <2%, da das Programm aber ohne Verzögerung arbeitet müsste die Auslastung doch bei 100% liegen?!? (Wenn ich die Rechenlast erhöhe ist dies auch derfall)



mfg
Christian
 

Wildcard

Top Contributor
Zum einen hast du nicht die Kontrolle darüber wie oft die paintComponent aufgerufen wird, zum anderen
läuft zeichnen asynchron ab und du kannst auf diese art nicht feststellen wie oft nun wirklich gezeichnet wurde.
Auch die Methode die du benutzt ist verkehrt. Man speichert ein Graphics objekt nicht.
Verwende die paintComponent methode (von dieser methode kannst du die Graphics bspw. an die
Flugzeuge weiterreichen). Dann brauchst du einen Thread der Das DatenModel verändert, repaint() (nicht die paintComponent oder die draw-Methode der Flugzeuge!) aufruft und anschließend schläft.
 

Nova

Bekanntes Mitglied
Hallo,

Ob die Bilder wirklich alle gezeichnet wurden weiß ich nicht, ich wusste nicht dass das verzögert läuft?!?, die Berechnungen wurden aber alle durchgeführt was sicher >95% der Rechnzeit ausmacht.
Es kommt mir auch eigentlich nicht darauf an wieviele Bilder gezeichnet werden (solange es flüssig läuft, zumal der Bildschirm ja sowieso nur 60-100 Bilder pro Sekunde darstellt), es ging mir eher um die Anzahl der Berechnungen bzw. die benötigtige Rechenzeit.
Wenn mit dem Athlon 750MHz jetzt 250fps erreicht werden weiß ich das ich noch massig Reserven habe. Ich habe z.B. kürzlich das Waffenfeuer eingebaut, auf dem 2500+ konnte ich keinen Unterschied bemerken (64fps), als ich das Programm dann aber auf dem Athlon 750MHz laufen ließ stellte ich fest das die Anzahl der bilder von ca.230 auf teilweise unter 100 fielen wenn die Flugzeuge feuerten. Ich hab dann einen Fehler im Code gefunden der extrem viele unnötige Berechnungen verursacht, später nach vielen weiteren Änderungen hätte ich den Fehler nur schwer finden können, und wenn wäre es schwierig gewesen den auszubügeln wenn schon andere Methoden auf diesen Code aufbauen...

In früheren Versionen habe ich mit dem Timer die paintComponent() aufgerufen (bzw. paint() als es noch ein Applet war), dabei wird aber z.B. die "Begrenzung" jedes mal neu gemalt was Rechenzeit kostet und zu flimmern führt.
Es macht doch auch keinen großen Unterschied ob ich die Methoden direkt im TimerListener aufrufe oder mit dem TimerListener die paintComponent()-Methode und dann dort die Methoden aufrufe, oder?!?
Ganz am Anfang haben die Methoden auch nur die Matrix verändet, gemalt wurde dann in paint(). Das war aber vieeeel zu rechenintensiv, denn es mussten ja alle 600.000 Pixel gemalt werden. Jetzt malen sich die Objekte selbst, und da diese die alte und neue Position kennen, müssen nur sehr wenige Pixel gemalt werden!
Das Graphics-Objekt (bzw. ein "Pointer" darauf) wird den Flugzeugen übergeben damit diese direkten Zugriff haben.
Es ist ja nicht immer sicher das die Flugzeuge gemalt werden, wenn sie eine ungültige Position erreicht haben oder zerstört wurden dürfen sie nicht gemalt werden. Um das zu verhindern müsste ich z.B. die Methode flugzeug1.testePosition() aufrufen, deren Rückgabewert in paintComponent auswerten etc.
Die Werte in der Matrix braucht z.B. die testePosition()-Methode der Flugzeuge um festzustellen ob ein Flugzeug mit etwas kollidiert ist, oder damit ein Geschoss "weiß" das es ein Flugzeug getroffen hat.


Ich habe gelesen das die paintComponent-Methode teilweise automatisch vom Programm aufgerufen wird. Das passiert bei mir aber höchstens 1 mal in der Minute, das sehe ich daran das "angefressene" Ränder (kleines Problem beim malen des Flugzeuges bei einem Crash) nicht oder erst nach einiger Zeit wieder "normal" aussehen.


Was meinst du mit "Thread der Das DatenModel verändert"?


Ich programmiere erst sei gut einem halben Jahr Java, an der Uni hatten wir praktisch gar nichts mit Graphik und schon gar keine so komplexen Programme gemacht... (auch nix mit Threads, Streams etc.)
Da es keine weiterführende Veranstaltung gibt will ich mir nun selbst Java beibringen.
Daher bin ich für jeden Tipp dankbar, ich will mich ja schließlich was lernen :toll:
Ich habe hier zwar das Buch "Java-How to Programm" mit über 1500 Seiten was auch sehr informativ ist, solche Probleme werden dort aber nicht behandelt...



mfg
Christian
 

Nova

Bekanntes Mitglied
Hallo,

Ich hab mal das Programm jetzt mal hochgeladen:
http://people.freenet.de/ChristianPetry/Dogfight.zip

Da sind alle Klassen und der Quellcode drin.
Einfach downloaden, entpacken und Dogfight.class ausführen.
Flugzeug1 steuert man mit den Pfeiltasten und Leertaste, Flugzeug2 mit A,S,W,D und Strg

Mich würde interessieren was ihr für fps-Zahlen bekommt.
(das Problem das die fps-Zahlen in den Keller gehen beim feuern habe ich noch nicht behoben)


mfg
Christian
 

Wildcard

Top Contributor
Da du auf dem neuen Rechner immer 64 erreichst, und auf dem alten mehr vermute ich das da unterschiedliche
Betriebssysteme laufen? Der Swing Timer ist für Frame-Steuerung übrigens völlig ungeeignet!
Du solltest dir das hier mal ansehen:
http://www.javalinkbase.de/detail.php?show=1&key=Tutorial&key2=Game
Es gibt 2 unterschiedliche ansätze:
der einfache Weg ist der den ich dir eben beschrieben habe: nur mit repaint() arbeiten und niemals paintComponent()
direkt aufrufen!
der kompliziertere weg geht über sog. active rendering.
Dabei verzichtest du auf die paintComponent, zeichnest dir selbst ein Offscreen-Image und musst bei jedem render-durchlauf die sleep-Time neu errechnen.
Das im einzelnen zu erklären ist hier zu aufwendig, also schau dir einfach mal die Tutorials an.
 

Nova

Bekanntes Mitglied
Hallo,

Danke für die Tipps!

Hatte die letzten Tage viel zu tun und bin erst jetzt dazu gekommen weiter zu programmieren...
Gestern hatte ich plötzlich 250fps auf dem AthlonXP 2500+, heute sind es wieder 64.
Sehr seltsam...


Wie auch immer, ich habe die Timer jetzt rausgeworfen und es mit einem Thread versucht.
Wenn ich das richtig verstehe soll ich "Runnable" implementieren, einen Thread erzeugen, die "run()"-Methode zum berechnen der Flugzeugbewegungen etc. verwenden und in "repaint()" die "draw-Funktionen" der Flugzeuge aufrufen?
Ich habe das mal so versucht, dabei gibts aber 2 Porbleme mit repaint():
1. Ich komme nicht an das Graphics-Objekt, kann also nicht malen (getGraphics() liefert Nullpointer)
2. die Instanzvariablen sind alles Nullpointer (d.h. es gibt z.B. das Objekt "flugzeug1" nicht), obwohl diese im Konstruktor ersellt wurden


Hier mal der Code: (die Methoden sind momentan noch alle in der run()-Methode weil wie oben beschrieben ich in der repaint()-Methode nichts machen kann)

Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;
import java.util.LinkedList;
import javax.swing.JOptionPane;

public class PaintPanel extends JPanel implements KeyListener,Runnable{

    public static int[][] matrix;
    public final static int MAX_WIDTH = 1000, MAX_HEIGHT = 600;
    private final int DELAY = 0;
    private Flugzeug flugzeug1, flugzeug2;
    
    public PaintPanel(){
        matrix = new int[MAX_WIDTH][MAX_HEIGHT];

	    Point p1 = new Point(80,MAX_HEIGHT/2);
     	Point p2 = new Point(MAX_WIDTH-80,MAX_HEIGHT/2);
     	
     	Flugobjekt.setMatrix(matrix); // Matrix an Flugobjekt übergeben, somit "kennen" alle Flugobjekte die Matrix
     	
	    flugzeug1 = new Flugzeug(p1,10000,0,1); // Flugzeug 1 erstellen
	    flugzeug2 = new Flugzeug(p2,20000,180,1); // Flugzeug 2 erstellen
	    
	    Thread th = new Thread(this);
	    th.start();
    }
    
    public void run(){
		// Erniedrigen der ThreadPriority um zeichnen zu erleichtern
	    Thread.currentThread().setPriority(Thread.MIN_PRIORITY);

		// Solange true ist läuft der Thread weiter
		while (true)
		{
	        flugzeug1.moveFlugzeug(); // Flugzeug 1 bewegen
	        flugzeug2.moveFlugzeug(); // Flugzeug 2 bewegen
	        double schaden1 = flugzeug1.moveWeapon1(); // Geschosse von Flugzeug1 bewegen und angerichteten Schaden speichern
	        if (schaden1 != 0){
	        	flugzeug2.damaged(schaden1);
	        }
	        double schaden2 = flugzeug2.moveWeapon1(); // Geschosse von Flugzeug2 bewegen und angerichteten Schaden speichern
	        if (schaden2 != 0){
	        	flugzeug1.damaged(schaden2);
	        }
	        flugzeug1.paintStatus(new Point(20,20)); // Status Flugzeug 1 zeichnen
	        flugzeug2.paintStatus(new Point(MAX_WIDTH-100,20)); // Status Flugzeug2 zeichnen		

			repaint();

			try
			{
				// Stoppen des Threads für in Klammern angegebene Millisekunden
				Thread.sleep(20);
			}
			catch (InterruptedException ex)
			{
				// do nothing
			}

			// Zurücksetzen der ThreadPriority auf Maximalwert
			Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
		}    	
    }
    
    public void repaint(){
    	setBackground(Color.white);	    	
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Flugobjekt.setGraphics(getGraphics()); // Graphik übergeben, erst hier möglich!
	    
	    setBackground(Color.white);
    	// Begrenzung
        for (int x = 0; x <= (MAX_WIDTH)-1; x++){
	        matrix[x][0] = 1;
	        matrix[x][1] = 1;
	        matrix[x][2] = 1;
	        matrix[x][3] = 1;
	        matrix[x][MAX_HEIGHT-1] = 1;
	        matrix[x][MAX_HEIGHT-2] = 1;
	        matrix[x][MAX_HEIGHT-3] = 1;
	        matrix[x][MAX_HEIGHT-4] = 1;
        }
	    for (int y = 0; y <= (MAX_HEIGHT)-1; y++){
	        matrix[0][y] = 1;
	        matrix[1][y] = 1;
	        matrix[2][y] = 1;
	        matrix[3][y] = 1;
	        matrix[MAX_WIDTH-1][y] = 1;
	        matrix[MAX_WIDTH-2][y] = 1;
	        matrix[MAX_WIDTH-3][y] = 1;
	        matrix[MAX_WIDTH-4][y] = 1;
	    }
        for (int x = 0; x <= MAX_WIDTH-1; x++){
	        for (int y = 0; y <= MAX_HEIGHT-1; y++){
	            int wert = matrix[x][y];
		        if (wert == 1){
		            g.setColor(Color.black);
		            g.drawRect(x,y,0,0);
		        }
	        }
	    }
    }

    public void keyPressed(KeyEvent event){
    	// Flugzeug 1:
    	if (event.getKeyCode() == KeyEvent.VK_UP){
    	    flugzeug1.setSpeed_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_DOWN){
    	    flugzeug1.setBreak_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_LEFT){
    	    flugzeug1.setLeft_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_RIGHT){
    	    flugzeug1.setRight_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_SPACE){
    	    flugzeug1.setFire1_key_pressed(true);
    	}

    	// Flugzeug 2:
    	if (event.getKeyCode() == KeyEvent.VK_W){
    	    flugzeug2.setSpeed_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_S){
    	    flugzeug2.setBreak_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_A){
    	    flugzeug2.setLeft_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_D){
    	    flugzeug2.setRight_key_pressed(true);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_CONTROL){
    	    flugzeug2.setFire1_key_pressed(true);
	    }
    }

    public void keyReleased(KeyEvent event){
        // Flugzeug 1:
    	if (event.getKeyCode() == KeyEvent.VK_UP){
    	    flugzeug1.setSpeed_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_DOWN){
    	    flugzeug1.setBreak_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_LEFT){
    	    flugzeug1.setLeft_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_RIGHT){
    	    flugzeug1.setRight_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_SPACE){
    	    flugzeug1.setFire1_key_pressed(false);
    	}
        // Flugzeug 2:
    	if (event.getKeyCode() == KeyEvent.VK_W){
    	    flugzeug2.setSpeed_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_S){
    	    flugzeug2.setBreak_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_A){
    	    flugzeug2.setLeft_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_D){
	        flugzeug2.setRight_key_pressed(false);
    	}
    	if (event.getKeyCode() == KeyEvent.VK_CONTROL){
    	    flugzeug2.setFire1_key_pressed(false);
    	}
    }

    public void keyTyped(KeyEvent event){}
}


So läuft das Programm, wenn ich einen niedrigeren Wert bei Thread.sleep() eingebe läuft das Programm auch schneller (keine "Begrenzung" mehr auf 64fps).


mfg
Christian
 

Bleiglanz

Gesperrter Benutzer
schon mal was von switch gehört??

für ken KeyEvent VK_CONROL machst du vorher 9 sinnlose Bedingungsabfragen, schaut mir nicht nach super-performance programmierung aus...
 

Nova

Bekanntes Mitglied
Hallo,

O.K. habs auf switch umgestellt.

Aber wie siehts mit dem Problem in der repaint()-Methode aus?
Wie kann es sein das diese Methoden die Instanzvariablen nicht kennt? Die Methode kann doch erst dann aufgerufen werden wenn das Objekt erstellt wurde, aber dann sind die Instanzvariablen doch ebenfalls erstellt???
In den anderen Methoden kann ich auf die Instanzvariablen zugreifen!


mfg
Christian
 

Wildcard

Top Contributor
Nova hat gesagt.:
Aber wie siehts mit dem Problem in der repaint()-Methode aus?
Wie kann es sein das diese Methoden die Instanzvariablen nicht kennt?
In den anderen Methoden kann ich auf die Instanzvariablen zugreifen!
Was soll denn das heißen? Du rufst repaint() doch nur auf, was hat das mit deinen Variablen zu tun?
 

Nova

Bekanntes Mitglied
Hallo,

Ich will in repaint() die "Draw-Methoden" der Flugzeuge aufrufen. (momentan noch alles in "moveFlugzeug()" integriert)
Oder darf ich repaint() gar nicht überschreiben? Wo soll ich dann die "Draw-Methoden" der Flugzeuge aufrufen?


mfg
Christian
 

Wildcard

Top Contributor
Überschreib repaint nicht! Überschreib painComponent und zeichne darin. Wenn du neuzeichnen willst repaint aufrufen.
Hatten wir das nicht alles schonmal?
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
P Swing Eine Sekunde warten (Timer) Allgemeine Java-Themen 7
W Timer terminiert nicht Allgemeine Java-Themen 5
W Timer Konzept-Frage Allgemeine Java-Themen 16
Z Timer Allgemeine Java-Themen 5
H Timer funktioniert nicht? Allgemeine Java-Themen 3
Tacofan Kurzer Timer Allgemeine Java-Themen 22
B Threads Timer wird immer schneller Allgemeine Java-Themen 6
H Consumer (Java8 Lambda) an Timer übergeben Allgemeine Java-Themen 2
wolfgang63 Best Practice Taktgeber oder Timer mit variablem Intervall Allgemeine Java-Themen 1
I Timer Allgemeine Java-Themen 1
X Timer Allgemeine Java-Themen 3
C Timer? Allgemeine Java-Themen 8
U Timer - Timertask endet nicht Allgemeine Java-Themen 4
X timer.schedule - Allgemeine Java-Themen 7
D Simpler Timer zum warten Allgemeine Java-Themen 19
H java.util.Timer und Funktion mit SQL Exception Allgemeine Java-Themen 5
G Threads Timer wird unterbrochen Allgemeine Java-Themen 20
P Java Timer Allgemeine Java-Themen 3
K Timer Thread Allgemeine Java-Themen 8
E Wie Timer anbringen mit Designer in Netbeans Allgemeine Java-Themen 5
M Ampelsteuerung über Timer in Java realisieren Allgemeine Java-Themen 3
O Timer pausieren Allgemeine Java-Themen 5
M Timer von nicht existiertem Objekt stopen Allgemeine Java-Themen 5
B util.Timer zu langsam? Allgemeine Java-Themen 3
P Java Timer Allgemeine Java-Themen 2
S Timer in Applet? Allgemeine Java-Themen 11
G Swing Timer führt Methode nicht aus Allgemeine Java-Themen 2
V Frage zu util.Timer (-> TimerTask) Allgemeine Java-Themen 2
E Timer class macht einfach garnichts :/ Allgemeine Java-Themen 6
T Timer oder Alternative? Allgemeine Java-Themen 3
Z Timer -> Thread jeden Tag ausführen Allgemeine Java-Themen 5
D Probleme mit einem Timer Allgemeine Java-Themen 6
E Timer - gleichen Task mehrfach planen Allgemeine Java-Themen 2
D Timer oder Thread, das ist hier die Frage Allgemeine Java-Themen 3
A TimerTask - Task stoppen - timer.cancel() funktioniert nicht Allgemeine Java-Themen 8
S Problem mit einem Timer (Aktualisierung etc.) Allgemeine Java-Themen 2
B Timer übergabe Allgemeine Java-Themen 3
G Timer abbrechen und neu starten Allgemeine Java-Themen 3
G timer mit buttondruck abbrechen Allgemeine Java-Themen 7
T Timer oder ähnliches? Allgemeine Java-Themen 3
O Timer und TimerTask: Programm terminiert nicht! Allgemeine Java-Themen 3
O Thread als Timer Interrupt Allgemeine Java-Themen 2
C Timer.scheduleAtFixedRate(). Allgemeine Java-Themen 5
H gibts in Java sowas wie in Visual Basic den Timer? Allgemeine Java-Themen 5
B 24 Uhr Timer Task Allgemeine Java-Themen 5
S Frage zu jTDS, JAVA allgemein und Timer Allgemeine Java-Themen 6
L Problem mit Timer Allgemeine Java-Themen 7
J Timer-Objekt / Task-Zustand ermitteln Allgemeine Java-Themen 5
berserkerdq2 run-methode eines Threads so programmieren, dass 30x die Sekunde etwas ausgeführt wird. Allgemeine Java-Themen 44
N 1000 MQTT Messages die Sekunde - 1000 Threads erstellen ? Allgemeine Java-Themen 10
T Array - Wert am nächsten zur vollen Sekunde Allgemeine Java-Themen 20
K Methode wiederholt nach einer Sekunde aufrufen Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben