# Gameloop funktioniert nicht!



## Damtonix (16. Jul 2018)

Ich bekomme keine flüssige Game-Loop hin. Bei mir leggt es immer ein wenig. Weiß jemand woran das liegt?



```
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GameloopTest {
 
 
 static Img[] img = new Img[20];
 static JFrame frame = new JFrame("GameloopTest");
 static JPanel contentPane = new JPanel() {
  public void paint(Graphics g) {
   super.paint(g);
   g.setColor(Color.BLACK);
   for(int i = 0; i < img.length; i++) {
    img[i].draw(g);
   }
  }
 };
 
 public static void main(String[] args) throws InterruptedException {
  init();
  long lastTime = System.currentTimeMillis();
  while(true) {
   update();
   draw();
   long thisTime = System.currentTimeMillis();
   Thread.sleep(1000/60 - (thisTime - lastTime));
   lastTime = System.currentTimeMillis();
  }
 }
 
 private static void init() {
  for(int i = 0; i < img.length; i++) {
   img[i] = new Img();
  }
  frame.setSize(800, 600);
  frame.setLocationRelativeTo(null);
  frame.setDefaultCloseOperation(3);
  frame.setContentPane(contentPane);
  frame.setVisible(true);
 }
 
 private static void update() {
  for(int i = 0; i < img.length; i++) {
   img[i].update();
  }
 }
 
 private static void draw() {
  contentPane.repaint();
 }
 
 private static class Img {
  
  private double x = 0, y = (int)(Math.random() * 400);
  private double speed = Math.random() * 5 + 1;
  private Image img;
  
  public Img() {
   try {
    img = ImageIO.read(new File("./res/img.png"));
    img = img.getScaledInstance(100, 100, 100);
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
  
  public void draw(Graphics g) {
   g.drawImage(img, (int)x, (int)y, null);
  }
  
  public void update() {
   x += speed;
   if(x > 800) {
    x = -100;
   }
  }
 }
}
[code]
```


----------



## Robat (16. Jul 2018)

Wenn du mit "laggen" ein flackern meinst dann solltest du dir mal DoubleBuffering anschauen.


----------



## Damtonix (18. Jul 2018)

Ich meine mit "laggen" wirklich ein Hängen des Bildes. (DoubleBuffering kenne ich) Trotzdem danke für deine Hilfe.


----------



## Xyz1 (18. Jul 2018)

Damtonix hat gesagt.:


> Thread.sleep(1000/60 - (thisTime - lastTime));


16ms ist etwas kurz. Das packt Java nicht. Schon deswegen weil da Bilder gezeichnet werden müssen.


----------



## Damtonix (22. Jul 2018)

Danke für die Hilfe. Ich habe bereits eine Lösung für das Problem gefunden. Gibt es eine Möglichkeit dieses Thema zu löschen oder so?


----------



## mrBrown (22. Jul 2018)

Verrätst du uns deine Lösung denn auch? 

Themen explizit schließen muss man hier nicht.


----------



## JuKu (6. Aug 2018)

DerWissende hat gesagt.:


> 16ms ist etwas kurz. Das packt Java nicht. Schon deswegen weil da Bilder gezeichnet werden müssen.



Das liegt nicht an Java, sondern an Swing!
Mit OpenGL (LWJGL / libGDX) bekommt man das auch locker mit Java hin, Java hat hier also keinerlei Schuld!
Und die Grafikkarte kann viele Bilder in 16ms zeichnen.
Das Problem ist nur Swing, da 1. der repaint() Call logischerweise nicht sofort das Bild neu zeichnet (sondern erst beim nächsten Durchlauf, wenn der OpenGL Thread soweit ist) und 2. keine Vertices in der Grafikkarte anlegt, sondern das ganze bei jedem Cycle neu auf die Grafikkarte hochlädt --> mega ineffizient.
Für Spiele mit Gameloops ist Swing einfach nicht gedacht, das ist eine GUI Library! Für Spiele gibt es LWJGL oder einfacher libGDX!



mrBrown hat gesagt.:


> Verrätst du uns deine Lösung denn auch?



Würde mich auch einmal interessieren, wie du es ohne Double Buffering gelöst hast!


----------

