Technik für aufeinanderfolgende Objekte in vollständiger Bewegung?


14

Ich frage mich, wie Objekte aufeinander folgen, wenn sie sich über die vorherige Position des Objekts vor ihnen bewegen. Wenn das führende Objekt anhält, sollten alle folgenden Objekte an ihrer Position anhalten. Wie wird das erreicht?

Wie so:

Bildbeschreibung hier eingeben

Bearbeiten:
Was ich erreichen möchte, ist, dass alle folgenden Objekte den Weg "gehen", den das führende Objekt vor sich nimmt. Alle anderen Objekte bewegen sich nur mit der Geschwindigkeit des führenden Objekts (dies würde durch Übergabe des Geschwindigkeitsvektors an alle folgenden Objekte geschehen). Aber wie lasse ich alle Objekte über den Pfad wandern / pausieren, ohne dabei den Abstand zu verlieren?

Antworten:


11

Verwenden Sie eine Liste mit dem Namen "Pfad", um die Wegpunkte zu speichern, die Ihren Pfad beschreiben, und eine doppelt verknüpfte Liste mit dem Namen "Schlange", um die sich bewegenden Objekte und den Pfad zu speichern.

Das Leitobjekt definiert auf seiner Reise neue Wegpunkte. Die folgenden Objekte bewegen sich entlang des Pfades, wie durch diese Wegpunkte definiert.

Jedes Objekt hat eine Sicherheitszone, die durch einen gewissen Abstand definiert ist. Wenn das führende Objekt angehalten wird, werden die folgenden Objekte nur so lange weiterbewegt, bis sie die Sicherheitszone ihres Vorgängers berühren.

Hier ist ein Pseudocode, wie diese Dinge implementiert werden könnten. Beachten Sie, dass dies möglicherweise nicht die eleganteste Lösung in Bezug auf die Verteilung von Verantwortlichkeiten und die Kapselung ist.

class Position {
    property x;
    property y;
}
class WayPoint extends ListNode {
    property position;
}
class Path extends List { 
    property WayPoints = array();

    // Find out the x, y coordinates given the distance traveled on the path
    function getPositionFromDistanceFromEnd(distance) {
        currentWayPoint = this->first();
        while(distance > 0) {
            distanceBetweenWayPoints = this->getDistance(currentWayPoint, currentWayPoint->next());
            if(distanceBetweenWayPoints > distance) {
                position = ... // travel remaining distance between currentWayPoint and currentWayPoint->next();
                return position;
            } else {
                distance -= distanceBetweenWayPoints;
                currentWayPoint = currentWayPoint->next();
            }
        }
    }
    function addWayPoint(position) {
        // Vector describing the current and new direction of movement
        currentDirection = this->first() - this->second();
        newDirection = position - this->first();
        // If the direction has not changed, there is no need to add a new WayPoint
        if( this->sameDirection(currentDirection, newDirection) {
            this->first->setPosition(position);
        } else {
            this->add(position);
        }
    }
}
class Snake extends DoublyLinkedList {
    property Path;
    property MovingObjects = array();
}
abstract class MovingObject extends DoublyLinkedListNode {
    property Snake; // shared among all moving objects of the same snake
    property position;
    const securityDistance = 10;
    abstract function move() { }
}
class MovingObjectLeader extends MovingObject {
    property direction;
    function move() {
        this->position += this->direction * this->Snake->speed;
        this->Snake->Path->addWayPoint(this->position);
        if(this->hasFollower()) {
            this->follower->move();
        }
    }
}
class MovingObjectFollower extends MovingObject {
    property distanceFromEnd;
    function move() {
        this->distanceFromEnd += this->Snake->speed;

        // If too close to leader: stop in order to respect security distance
        if(this->distanceFromEnd > this->leader()->distanceFromEnd - this->securityDistance) {
            this->distanceFromEnd = this->leader()->distanceFromEnd - this->securityDistance;
        }

        this->position = this->Snake->getPositionFromDistanceFromEnd(this->distanceFromEnd);

        if(this->hasFollower()) {
            this->follower->move();
        }
    }
}

Pfad-> Wegpunkte werden immer größer, je länger das Spiel dauert. Wenn Ihre Schlange schon länger existiert, müssen Sie den letzten Wegpunkt löschen, wenn das letzte Element der Schlange den vorletzten Wegpunkt des Pfads passiert hat. Denken Sie daran, auch distanceFromEnd in allen MovingObjects of Snake entsprechend zu reduzieren.


Angenommen, ich möchte mein führendes Objekt mit der Maus ziehen (nicht, dass ich möchte, aber sagen wir, dass ich das tue). Wie würde das mit deinem Beispiel funktionieren?
Sidar

Die Liste der Objekte kann verschoben werden, indem zuerst das erste Element von seiner aktuellen Position in eine bestimmte Richtung (mit einer bestimmten Geschwindigkeit) verschoben wird und dann alle anderen Elemente von ihrer aktuellen Position in eine durch ihre aktuelle Position und $ angegebene Richtung verschoben werden this-> previousElement-> getPosition (). Wenn Sie Ihr erstes Element an eine beliebige Stelle ziehen, müssen Sie nur die Methode setPosition () aufrufen. Wenn die Liste gerendert wird, ändern die anderen Objekte ihren Pfad, um ihren Vorgängern zu folgen.
BerndBrot

Korrigieren Sie mich, wenn ich falsch liege, aber würde das nicht auch dazu führen, dass die folgenden Objekte Verknüpfungen verwenden, wenn sie die Richtung ändern? (wie im unteren Teil des Bildes, das ich gegeben habe). Es hört sich so an, als würden sie dem Pfad des Objekts nicht folgen. Stattdessen würden sie so weit wie möglich in die Richtung des führenden Objekts vor ihnen gehen. Die Objekte vom Weg abbringen und Verknüpfungen herstellen?
Sidar

Ja, das würde in der Tat bei dieser speziellen Implementierung passieren. Ich habe die Antwort gepostet, bevor Sie Ihre Bilder hinzugefügt haben, also versuchen wir es noch einmal ...
BerndBrot

In Ordung. Was ist damit?
BerndBrot

6

Im Wesentlichen benötigen Sie zwei Datenstrukturen (logisch, aufdringlich oder real, abhängig vom Rest Ihres Codes). Die erste verfolgt die Objektketten und die andere den Pfad.

Kette Sie müssen lediglich wissen, welche Objekte anderen Objekten folgen. Im einfachsten Fall ist dies einfach A folgt B, könnte aber mehr Anhänger enthalten. Es gibt einen bestimmten Anführer in der Kette.

Pfad Für jede Kette benötigen Sie einen Pfad. Abhängig davon, wie Ihr Spiel funktioniert, wird bestimmt, wie dies strukturiert ist. In den meisten Fällen handelt es sich um eine Art verknüpfte Liste. Dies wird die Positionen verfolgen, denen jeder in der Kette folgen muss.

Jetzt fügt der Anführer der Kette dem Pfad Elemente hinzu . Jedes Mal, wenn es sich bewegt, wird etwas zum Kopf der Liste hinzugefügt. Jedes Objekt in der Kette merkt sich, wo es sich auf der Liste befindet. Beim Verschieben wird einfach zum nächsten Element in der Liste gewechselt (bei Bedarf entsprechend interpoliert). Wenn der letzte Gegenstand in der Kette an einem Gegenstand in der Liste vorbeigeht, kann dieser Gegenstand fallengelassen werden (er befindet sich am Ende).

Metaphorisch hinterlässt der Anführer seinen Anhängern eine Paniermehlspur. Der letzte Follower in der Liste verbraucht den Breadcrumb.

Ob Ihre Liste einzelne Punkte oder nur die Eckpunkte eines Pfades oder etwas anderes enthält, hängt ausschließlich von Ihrer Spiel-Engine ab. Aber ich sehe auf keinen Fall, dass Sie die Liste selbst umgehen können.


Ja, ich habe mir so etwas gedacht. Es ist die Implementierung, die normalerweise meinen Verstand implodiert. Vielen Dank für die Antwort. Anerkannte berndBrots antworten, haben aber deine hochgestuft.
Sidar

-3

A * -Pfadfindung nachschlagen. Dies ist ein allgemeiner und einfacher Weg, um Ihre Spielobjekte zu einer Position zu bewegen.


Ich weiß, was A * ist, nicht wonach ich suche und viel zu schwer für etwas, das mir viel einfacher vorkommt.
Sidar

Ihre Antwort ist nicht annähernd richtig. Ein * ist ein Algorithmus zum Finden eines Pfades. Während er nichts finden will, möchte er nur, dass das Objekt genau an jeder Position aufeinander folgt, an der sich das letzte Objekt befand.
Ali1S232

Als ich die Frage ursprünglich beantwortete, war es nicht fixiert, um mehr zu klären / es gab kein Bild, das zeigte, was er meinte. Ich las gerade die ersten beiden Sätze und stellte fest, dass er mehrere Entitäten hatte, die versuchten, etwas zu verfolgen, anstatt einem Pfad zu folgen. Tut mir leid für die schlechte Antwort, schätze ich
Deadlybutter

Ich habe gesagt, folgt einander = P bewegt sich nicht zu einem Punkt.
Sidar,

Ich weiß, ich entschuldige mich.
Totenbutter
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.