Flüssige Bewegung

  • Antworten:9
Maximilian O
  • Forum-Beiträge: 990

20.09.2011, 20:45:11 via Website

Hey Leute,
in meinem neuen Game habe ich einen Countdowntimer, welcher alle 100ms das Spielfeld überprüft und ale "Figuren" ein Feld weiterbewegt. Das klappt auch wunderbar. Nur sind 10fps nicht gerade flüssig. Wenn ich nun alles auf 50ms stelle und nur den halben Speed, ruckelt es. Habt ihr eine Idee, wie ich die Animationen gestalten kann?
MfG Maximilian

Vergiss nie wieder Geburtstage, oder viel schlimmer, deinen Hochzeitstag - Birthdays Download

Antworten
L3322
  • Forum-Beiträge: 467

20.09.2011, 20:58:20 via Website

A bissl mehr Information wäre super!
Und ein bisschen Code wäre auch super :)

mfg L3322

"Hard work beats talent, when talent fails to work hard"

Antworten
Maximilian O
  • Forum-Beiträge: 990

20.09.2011, 21:04:47 via App

Naja, was wäre denn noch wichtig? also das Spielfeld ist in 100*100 Teile aufgeteilt, welche in jeder schleife durch gegangen werden. so zusagen schiebe ich zB eine Figur ein Feld nach rechts. alles kein Problem. nur ist ein Bereich (960/100) auf meinem Sensation fast 10px groß. somit springt die Figur 10px alle 100ms, was 10fps entspricht. meine Frage ist jetzt, wie kann ich diese 10px Verschiebung "smooth" abwickeln?
mfg Maximilian

Vergiss nie wieder Geburtstage, oder viel schlimmer, deinen Hochzeitstag - Birthdays Download

Antworten
Tobias Eckert
  • Forum-Beiträge: 155

20.09.2011, 21:26:39 via Website

Maximilian O
meine Frage ist jetzt, wie kann ich diese 10px Verschiebung "smooth" abwickeln?

Die kurze Antwort ist: gar nicht. Wenn Du eine flüssige Animation machen willst musst Du das anders herum angehen. Anstatt die Pixel festzulegen und dann zu schauen wie groß der Zeitabschnitt sein muss in dem Du die Grafik aktualisierst, musst Du feststellen wie groß Dein Zeitabschnitt zwischen zwei Zeichenoperationen ist, und basierend darauf festlegen um wieviele Pixel du die Figur weiter bewegst.

Konkret: Baue eine Schleife die Deine Zeichenoperation ausführt. Prüfe wie viele Millisekunden zwischen den Zeichenoperationen vergehen. Bewege Deine Figur genau soviele Pixel weiter wie sie sich in der verstrichenen Zeit weiter bewegt haben sollte.

Zum Beispiel: Deine Figure soll in einer Sekunde 100 Pixel weit wandern. Zwischen Deinen Zeichenoperationen vergehen 50 Millisekunden. Dann bewegst Du Deine Figur zwischen zwei Zeichenoperationen (50 Millisekunden /1000 Millisekunden) * 100 Pixel = 5 Pixel weiter.

Wenn Du das Ganze jetzt noch ruckelfrei gestalten möchtest musst Du noch darauf achten dass Du die Garbage Collection in den Griff bekommst.

Ansgar M

Antworten
Maximilian O
  • Forum-Beiträge: 990

21.09.2011, 16:21:09 via Website

Danke euch allen!
Super Tipps.

@Tobias:
Danke für deinen ausführlichen Text :) Das klingt ja sehr gut. Nur eine Frage noch, wie sollte ich mein Spielfeld aufbauen? Derzeit besteht es aus 100x 100 Teilen. Wenn ich jetzt jedoch die Figuren verschiebe, um nur wenige Px, bleiben sie immer auf dem selben Spielfeld. Hast du dazu eine Idee?
MfG Maximilian

Vergiss nie wieder Geburtstage, oder viel schlimmer, deinen Hochzeitstag - Birthdays Download

Antworten
Tobias Eckert
  • Forum-Beiträge: 155

21.09.2011, 21:49:42 via Website

Maximilian O
Wenn ich jetzt jedoch die Figuren verschiebe, um nur wenige Px, bleiben sie immer auf dem selben Spielfeld. Hast du dazu eine Idee?

Da schlägt wahrscheinlich die Integer Rundung zu. Wenn Du nach der Logik oben die Elemente pro Update z.B. immer nur um 0,4 Pixel weiter schiebst wird das jedesmal zu 0 abgerundet und die Grafik bewegt sich dann effektiv gar nicht mehr. In diesem Fall musst Du die Position der Elemente nochmal separat als Float Wert speichern.

Also für Dein Grafik-Object einen Float Wert X und einen Y definieren. Die erhöhst Du in dem Beispiel dann in jedem Durchgang um 0,4 Pixel, und setzt dann Deine Grafik an die Stelle Round(X), Round(Y).

Antworten
Maximilian O
  • Forum-Beiträge: 990

22.09.2011, 16:26:28 via Website

Danke Tobias, das klappt. Aber ich verstehe einfach nicht, warum meine Schleife eine Differenz zw. den Durchläufen von 1500ms hat (!). Hast du ne Ahnung was da schief läuft?
Ausschnitt aus meinem Thread:
1@Override
2 public void run() {
3 long tickCount = 0L;
4 Log.d(TAG, "Starting game loop");
5 while (running) {
6 tickCount++;
7 long now = System.nanoTime();
8 long differenceSinceLastTick = now-lastTick;
9 lastTick = now;
10
11 playingField.handleTimerAction(differenceSinceLastTick/1000000);
12 // update game state
13 // render state to the screen
14 }
15 Log.d(TAG, "Game loop executed " + tickCount + " times");
16 }

MfG Maximilian

Vergiss nie wieder Geburtstage, oder viel schlimmer, deinen Hochzeitstag - Birthdays Download

Antworten
Maximilian O
  • Forum-Beiträge: 990

22.09.2011, 17:52:11 via Website

Ok, jetzt klappt alles :)
Läuft schon prima, nur ruckelt wie gesagt noch etwas. Da sagst du ja muss ich noch die Garbage Collection in den Griff bekommen. Hast du noch ein paar Tipss dafür parat? :)
MfG

Vergiss nie wieder Geburtstage, oder viel schlimmer, deinen Hochzeitstag - Birthdays Download

Antworten