2016-12-13 5 views
0

Ich bin auf ein Problem gestoßen, das ich selbst nicht beheben kann.Libgdx interpoliertes gerendertes Sprite, das ohne Grund rüttelt

ich diesen festen Zeitschritt umgesetzt haben, in meinem render() Methode wie folgt aus:

double time = TimeUtils.millis(); 

    loops = 0; 
    while (time > nextGameTick && loops< MAX_FRAMESKIP) { 
     gameLogic(1f/gameSpeed); 
     nextGameTick += SKIP_TICKS; 
     loops++; 
    } 

    if(!rendererDisposed) { 
     interpolation = (time + SKIP_TICKS - nextGameTick)/(SKIP_TICKS); 
     camera.update(); 
     renderer.render(interpolation); 
     hud.draw(dt); 
    } 

Der obige Code die letzte Implementierung von diesem Link lautet: http://www.koonsolo.com/news/dewitters-gameloop/

Und meine Renderer Klasse wie eine Charge zieht dies:

batch.draw(assets.getAnimation(), 
       player.getInterPos(interpolation).x, 
       player.getInterPos(interpolation).y, 
       player.getWidth()/2, 
       player.getHeight()/2, 
       player.getWidth(), 
       player.getHeight(), 1, 1, 
       player.getPolygon().getRotation()); 

Und getInterPos()

public Vector2 getInterPos(float delta){ 
    interPosition.x = position.x *delta + previousPosition.x*(1-delta); 
    interPosition.y = position.y*delta + previousPosition.y*(1-delta); 
    return interPosition; 
} 

Was zu erwarten ist: Interpolation gibt einen Gleitkommawert von 0 bis 1 zurück, der für die Interpolation zwischen der vorherigen und der aktuellen Position verwendet wird.

Gerade jetzt habe ich TICKS_PER_SEC = 25. Mit einem FPS: 25 bedeutet, dass Renderer und Gamelogic jedes Mal 1 Mal aufgerufen wird. Das funktioniert.

Problem beginnt, wenn fps! = TICKS_PER_SEC. Bei 50 fps würden wir annehmen, dass gamelogic einmal aufgerufen wird und der Renderer zweimal aufgerufen wird. Interpolation ist jetzt 0,5 und 1 beim 1. und 2. Renderer Call. Dies funktioniert auch. Allerdings verhält sich das gezeichnete Sprite merkwürdig und springt auf und ab. Hier

ist ein Video, das das Sprites Verhalten zeigt: https://www.youtube.com/watch?v=CE6cQr9o0kA

nun das größte Geheimnis ist, dass wenn wir diese Zeilen in der Renderer-Klasse hinzufügen

Gdx.app.log("player has y:"+player.getY()," and previous y:"+player.getPreviousPosition().y); 
Gdx.app.log("interpolation: "+interpolation," position: +player.getInterPos(interpolation)); 
     batch.draw(assets.getAnimation(), ... same as earlier 

Spieler haben y: 23,62517: und vorherigen y: 23.09717 interpolation: 1.0: position: (4.5,23.62517) Spieler hat y: 24.145168: und vorherige y: 23.62517 interpolation: 0.5: position: (4.5,23.88517) Spieler hat y: 24.145168: und vorherige y: 23,62517 Interpolation: 1,0: Position: (4.5,24.145168) Spieler hat y: 24,657167: und vorherigen y: 24,145168 Interpolation: 0,5: Position: (4.5,24.401169)

current und previousPosition korrekt aktualisiert werden und so auch die interpolierte Position. Wie Sie sehen können, ist die Position immer aufsteigend und fast linear. Also die Frage ist, warum auf der Erde macht die Charge das Sprite in 2 verschiedenen Positionen und wechselt zwischen ihnen?

Meine Schwerkraft-Funktion:

//dt is gameSpeed not the deltaTime 
velocity.add(acceleration.x*dt,acceleration.y*dt); 
position.add(velocity.x*dt,velocity.y*dt); 
    if (velocity.y<=-10) 
     velocity.y=-10; 

Wenn ich den Bildschirm drücken dies geschieht:

velocity.set(0,20); 

Extra Info:

  • Da das Objekt nach unten die Probleme verlangsamt weggeht
  • Das Gleiche passiert, wenn die Objekte frei fallen, geht le ft und rechts
  • Je höher die FPS, desto mehr Höhen und Tiefen es
  • ersetzt getInterPos mit getPosition beheben das Problem tun, aber dann die fps = TICKS_PER_SEC

Ich hoffe, dass ich wirklich so gründlich wie möglich war. Diese Dinge haben mich in den letzten 2 Wochen verrückt gemacht, und ich kann es einfach nicht schaffen, es zu reparieren.

Jede Hilfe wird sehr geschätzt!

EDIT:

Ich habe es geschafft, das Problem zu beheben. Es war aufgrund der Tatsache, dass ich die Kamera aktualisiert habe und es meinen Spielern aktuelle Logikposition statt der interpolierten Position gab und es innerhalb der Spiellogikfunktion aktualisierte.

Also änderte ich meine Kamera Positionierung von

camera.position.y = player.getPosition().y; 

Um

camera.position.y = player.getInterPos(interpolate).y; 

und nicht mehr Artefakte! Lassen Sie es hier für den Fall, dass jemand auf ein ähnliches Problem stößt.

Antwort

0

Nicht positiv, das ist Ihr einziges Problem.

Seit millis() kehrt ein langer, sollte time lang sein, kein Doppel:

long time = TimeUtils.millis(); // you declared time to be a double 

SKIP_TICKS und nextGameTick auch Long-Positionen sein. Und dann müssen Sie den Zähler und den Nenner vor dem Teilen schweben lassen, damit Ihre Interpolation nicht immer eine ganze Zahl (0 oder 1) erhält.

interpolation = (float)(time + SKIP_TICKS - nextGameTick)/(float)SKIP_TICKS; 
+0

Interpolation wird ausgelöst, um weiter unten im Code zu schweben. Schätze, es ist nicht der richtige Weg, das zu tun? Unabhängig davon werde ich Ihre Vorschläge versuchen und melden, wenn ich kann! Danke für deinen Beitrag. –

+0

Wenn Sie ein langes durch ein langes teilen, erhalten Sie ein langes, abgerundetes in Richtung 0. Zum Beispiel ist "59L/60L" gleich "0L". Ihr Interpolationswert ist also immer 0 oder 1, niemals dazwischen. Sie müssen Interpolation auch als Float deklarieren. – Tenfour04