Guten Morgen,
im Rahmen meiner Ausbildung programmiere ich momentan ein kleines Netzwerk Spiel. In dem Spiel steuert man einen kleinen Panzer mit der Tastatur. Und genau hier ist auch das Problem: Die Bewegung des Panzers ruckelt trotz 50 Berechnungen pro Sekunde.
Es gibt 2 Threads die für die Bewegung zuständig sind. "MovementTask" berechnet die Bewegung 50 mal pro Sekunde, während "Paint" alle vorhandenen Objekte 50 mal pro Sekunde mittels repaint() anzeigt. Stelle ich es so ein, dass es 200-250 mal pro Sekunde berechnet wird, wird es einwandfrei angezeigt. Alles darunter empfinde ich als starkes ruckeln, obwohl der Bildschirm nur 60 Bilder pro Sekunde anzeigen kann.
Da ich die dauer des Thread.sleep() selbst berechne um möglichst genau auf 50 Berechnungen pro Sekunde zu kommen ist ein performance leak ausgeschlossen. Wenn man sich die vergangene Zeit ausgeben lässt, kommt konstant 19.9 - 20 ms raus, was ja 50 fps entspricht.
Ich hoffe ihr könnt mir bei dem Problem helfen bzw. mir sagen wieso das ruckeln auftritt. Im Folgenden noch ein paar Code Ausschnitte und eine Ausführbare .jar Datei.
Paint Methode:
drawSprite()
getRotatedAffineTransform():
repaint Task:
eigener Sleep:
Danke schon mal für die Hilfe. Falls weitere Code Ausschnitte benötigt werden sagt bitte bescheid.
MFG Steffencz
im Rahmen meiner Ausbildung programmiere ich momentan ein kleines Netzwerk Spiel. In dem Spiel steuert man einen kleinen Panzer mit der Tastatur. Und genau hier ist auch das Problem: Die Bewegung des Panzers ruckelt trotz 50 Berechnungen pro Sekunde.
Es gibt 2 Threads die für die Bewegung zuständig sind. "MovementTask" berechnet die Bewegung 50 mal pro Sekunde, während "Paint" alle vorhandenen Objekte 50 mal pro Sekunde mittels repaint() anzeigt. Stelle ich es so ein, dass es 200-250 mal pro Sekunde berechnet wird, wird es einwandfrei angezeigt. Alles darunter empfinde ich als starkes ruckeln, obwohl der Bildschirm nur 60 Bilder pro Sekunde anzeigen kann.
Da ich die dauer des Thread.sleep() selbst berechne um möglichst genau auf 50 Berechnungen pro Sekunde zu kommen ist ein performance leak ausgeschlossen. Wenn man sich die vergangene Zeit ausgeben lässt, kommt konstant 19.9 - 20 ms raus, was ja 50 fps entspricht.
Ich hoffe ihr könnt mir bei dem Problem helfen bzw. mir sagen wieso das ruckeln auftritt. Im Folgenden noch ein paar Code Ausschnitte und eine Ausführbare .jar Datei.
Paint Methode:
Java:
@Override
public void paintComponent(Graphics g)
{
super.paintComponents(g);
drawSprite(player, g);
}
drawSprite()
Java:
public void drawSprite(Sprite sprite, Graphics g)
{
Graphics2D g21 = getNewGraphics2D(g);
g21.setPaint(new TexturePaint(Images.getInstance().get(sprite.getImageID()), new Rectangle2D.Double(sprite
.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight())));
AffineTransform transform = Calculate.getRotatedAffineTransform(sprite.getR(), sprite.getCenterX(),
sprite.getCenterY());
g21.transform(transform);
g21.fillRect((int) sprite.getX(), (int) sprite.getY(), (int) sprite.getWidth(), (int) sprite.getHeight());
g21.dispose();
}
getRotatedAffineTransform():
Java:
public static AffineTransform getRotatedAffineTransform(double theta, double anchorx, double anchory)
{
AffineTransform transform = new AffineTransform();
transform.rotate(theta, (int) anchorx, (int) anchory);
return transform;
}
repaint Task:
Java:
@Override
public void run()
{
long last = System.nanoTime();
while (true)
{
last = System.nanoTime();
repaint();
Calculate.sleep(50, last);
}
}
eigener Sleep:
Java:
public static void sleep(int tps, long last)
{
double fullDelay = (double)1e9/tps;
long nanoDelta = System.nanoTime() - last;
double targetNanoDelay = fullDelay - nanoDelta;
if (targetNanoDelay > 0)
{
long delayMillis = (long) (targetNanoDelay/1e6);
int delayNano = (int) (targetNanoDelay-delayMillis*1e6);
try
{
Thread.sleep(delayMillis, delayNano);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
Danke schon mal für die Hilfe. Falls weitere Code Ausschnitte benötigt werden sagt bitte bescheid.
MFG Steffencz