Reibungslose Bewegung in einem Spiel auf Kachelbasis

8

Wie können wir unseren Charakter dazu bringen, sich reibungslos über Kacheln zu bewegen? Er bewegt sich Kachel für Kachel, aber das sieht unprofessionell aus. Wenn Sie die Pfeiltasten gedrückt halten, bewegt er sich außerdem über den Bildschirm. Wie können wir das verhindern?

leo882
quelle
Sie verwenden Ganzzahlen für die Spielerbewegung. Versuchen Sie stattdessen, Floats zu verwenden.
Mokosha
1
Es ist am besten, wenn Sie Ihren Code auf das Minimum reduzieren, das erforderlich ist, um Ihr Problem / Ihre Frage zu demonstrieren / zu kommunizieren. Diese Frage könnte Sie auch interessieren .
Kevintodisco
1
Ich habe die unnötigen Teile Ihrer Frage entfernt. Es ist am besten, auf den Punkt zu kommen und keinen zusätzlichen Code oder andere Flusen hinzuzufügen.
MichaelHouse

Antworten:

6

Eine reibungslose Bewegung kann auf verschiedene Arten erreicht werden. Und es hängt wirklich davon ab, welche Art von Bewegung Sie zulassen möchten.

  • Die Bewegung ist immer noch auf Fliesen beschränkt. Dieser Typ ist am einfachsten für Dinge wie Kollisionserkennung und andere Bewegungsprüfungen. Bei dieser Art von Bewegung interpolieren Sie einfach die Position im Laufe der Zeit, wenn Sie zwischen Kacheln wechseln. Es kann so einfach sein, der Update-Schleife Folgendes hinzuzufügen.

Pseudocode:

 if(GetDistance(position, targetposition) > minDistance) {
     position = MoveTowards(position, targetposition, deltatime);
 }

Wobei MoveTowardsnur die aktuelle Position einnimmt und einen Teil des Abstands zwischen ihr und der Zielposition hinzufügt.

  • Die Bewegung ist nicht auf Kacheln beschränkt. Die Implementierung wird viel schwieriger. Im Wesentlichen speichern Sie bei dieser Methode nur die Position und aktualisieren sie über die Geschwindigkeit. Das heißt, die Position ändert sich im Laufe der Zeit.

Das Halten der Pfeiltasten zum Verschieben von Zeichen kann auch auf verschiedene Arten implementiert werden. Wahrscheinlich ist das, was Sie tun, so etwas wie:

if(keydown(left))
   tilePosition.X--;

Dies würde in der Tat dazu führen, dass der Charakter über den Bildschirm läuft. Da würden Sie die Position viele Male pro Sekunde aktualisieren. Ein etwas besserer Weg, dies zu implementieren, wäre das Hinzufügen einer Verzögerung. Etwas wie

if(keydown(left)) {
    if(leftKeyHeldTimer > movementDelay) {
        tilePosition.X--;
        leftKeyHeldTimer = 0;
    } else {
        leftKeyHeldTimer+= deltaTime;
    }
}

Dies fügt einen Verzögerungszeitgeber hinzu und aktualisiert die Kachelposition erst, wenn der movementDelayWert erreicht wurde.

MichaelHouse
quelle
0

Ich kann zwei Probleme identifizieren. Der erste bezieht sich auf sanfte Bewegungen und der zweite auf das Zippen des Charakters vom Bildschirm.

Um eine gleichmäßige Bewegung zu erstellen, können Sie eine Technik namens Lineare Interpolation oder (LERP) verwenden, um die Bewegung zu glätten. Grundsätzlich funktioniert es zwischen Ihrem Start- und Endpunkt. Sie berechnen eine Reihe von immer kleiner werdenden Abständen, um eine reibungslose Bewegung und Verlangsamung zu emulieren, wenn der Endpunkt fast erreicht ist.

Das einfachste Beispiel für diese Funktion wäre:

//point1 is the current position, will be starting position on first call
//point2 is the target position
//epsilon is the % of the distance between current and target you want
//to cover per game physics loop (a fixed realworld time based loop).
//The smaller the % the "smoother" the motion.

float lerp(float point1, float point2, float epsilon)
{
    return point1 + epsilon * (point2 - point1);
}

Wenn sich der Charakter Punkt 2 nähert, wird er allmählich langsamer. Beachten Sie jedoch, dass sie Punkt 2 niemals berühren, sondern sich unendlich nähern. Sie müssten dies korrigieren, und wenn der Spieler weniger als eine unendlich kleine Entfernung von Punkt 2 hat, können wir davon ausgehen, dass sich der Spieler auf Punkt 2 befindet.

Das zweite Problem, das Sie erwähnt haben, bezieht sich auf Ihren Charakter, der außerhalb des Bildschirms fliegt. Dies ist ein Ergebnis der Eingabe, die bei jeder Aktualisierung der Spielschleife gelesen wird, kombiniert mit der sofortigen Bewegung zwischen den Kacheln.

Um dies zu lösen, müssen Sie sich in Ihrem Code entscheiden

  1. Wie viel Zeit in der realen Welt würde es dauern, bis sich der Charakter von Punkt 1 zu Punkt 2 bewegt.
  2. Stellen Sie Ihren Lerp so ein, dass er während dieser Dauer zwischen Punkt 1 und 2 läuft
  3. Lesen Sie die Eingabe erneut, sobald Punkt 2 erreicht ist, um zu entscheiden, wohin Sie gehen möchten
Ang Li
quelle