Ich habe die Grundlagen des Spieldesigns gelernt und habe diese Spielschleife mit Hilfe vieler Tutorials in Java erstellt. Alles, was es jetzt tut, ist auf ein JFrame ein Grasfliese zu machen: es bei einem konstanten 60 FPS, das einzige Problem ist, es frisst läuft, kannSehr hohe CPU-Auslastung mit einfachem Java Game Loop
public class Game extends JPanel implements Runnable {
String title;
int height;
int width;
boolean ps;
private int ticks;
private JPanel p;
private BufferStrategy bs;
private Graphics g;
private boolean running = false;
private Thread thread;
private Frame frame;
private KeyHandler keyHandler;
public Game(String title, int width, int height){
this.width = width;
this.height = height;
this.title = title;
keyHandler = new KeyHandler();
}
private void init() {
TileHandler.init();
frame = new Frame(title, height, width);
frame.getFrame().addKeyListener(keyHandler);
}
private void tick() {
// KeyHandler.tick();
// updates game logic
}
private void render() {
render(g);
}
private void render (Graphics g) {
bs = frame.getCanvas().getBufferStrategy();
if(bs == null){
frame.getCanvas().createBufferStrategy(3);
return;
}
g = bs.getDrawGraphics();
g.clearRect(0, 0, width, height);
g.drawImage(TileHandler.grass, keyHandler.getPlayerX(),
keyHandler.getPlayerY(), null);
bs.show();
g.dispose();
}
@Override
public void run() {
int x = 4;
init();
int fps = 60; // target
double tickTime = 1000000000/fps; // time per 1 frame
double delta = 0;
long timer = 0;
long startTime = System.nanoTime();
long endTime;
while (x == 4) {
endTime = System.nanoTime();
delta += (endTime - startTime)/tickTime;
timer += endTime - startTime;
startTime = endTime;
if (delta >= 1) {
ticks++;
render();
delta--;
}
if(timer >= 1000000000){
ticks = 0;
timer = 0;
}
}
}
public int getTicks() {
return ticks;
}
public synchronized void startThread() {
// Start the thread
if (!running) { // if not already
running, you can begin
running = true;
thread = new Thread(this); //Run THIS class on a
new thread
thread.start();
}
else { // safety measure
return;
}
}
public void stopThread() {
if (!running) {
return;
}
running = false;
try {
thread.join(); //Method stops the thread
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Es funktioniert gut genug und ich so viel CPU. Im Durchschnitt verbraucht es ungefähr 50% CPU und verlangsamt den Rest meines Computers - Minecraft verwendet ungefähr dasselbe auf meinem Laptop! Ich weiß genau, dass das Problem in der Spielschleife im obigen Code liegt.
Also versuche ich nur zu verstehen, was das verursacht. Ich habe versucht, einen Profiler zu verwenden, aber ich konnte immer noch nicht herausfinden, was das Problem verursacht hat.
Die Schleife wird ständig ausgeführt, um zu sehen, ob sie render() aufrufen muss. Dies wird als Polling bezeichnet und ist normalerweise eine schlechte Idee. Versuchen Sie einen Timer zu verwenden, um stattdessen render() aufzurufen. – James
Auch würde ich Ihnen raten, in JavaFX zu schauen, da es Hardware-Beschleunigung verwendet, ist es viel mehr für die Entwicklung von Spielen geeignet. Es kommt auch mit Klassen wie [AnimationTimer] (https://docs.oracle.com/javase/8/javafx/api/javafx/animation/AnimationTimer.html) und [Zeitleiste] (https://docs.oracle.com /javase/8/javafx/api/javafx/animation/Timeline.html), die Gameloop-Management recht einfach machen. – Jhonny007