Użyć Listy o nazwie „Ścieżka”, aby zapisać punkty, które opisują Twoją ścieżkę, oraz podwójnie połączonej listy o nazwie „Wąż”, aby zapisać poruszające się obiekty i Ścieżkę.
Obiekt wiodący określa nowe punkty orientacyjne podczas podróży. Następujące obiekty poruszają się wzdłuż ścieżki zdefiniowanej przez te punkty trasy.
Każdy obiekt ma strefę bezpieczeństwa określoną przez pewną odległość. Jeśli wiodący obiekt się zatrzyma, następujące obiekty będą się poruszać tylko do momentu dotknięcia strefy bezpieczeństwa swojego poprzednika.
Oto pseudo-kod dla tego, jak te rzeczy mogą być zaimplementowane. Pamiętaj, że może to nie być najbardziej eleganckie rozwiązanie pod względem podziału obowiązków i hermetyzacji.
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();
}
}
}
Ścieżka-> WayPoints staje się tym większa, im dłużej gra trwa. Jeśli twój Wąż istnieje od dłuższego czasu, musisz usunąć ostatni WayPoint, ilekroć ostatni element Węża przekroczy drugi przedostatni WayPoint. Pamiętaj również, aby odpowiednio zmniejszyć distanceFromEnd we wszystkich MovingObjects of Snake.
Zasadniczo będziesz potrzebować dwóch struktur danych (logicznych, natrętnych lub rzeczywistych, w zależności od reszty kodu). Pierwszy będzie śledził łańcuchy obiektów, a drugi ścieżkę.
Łańcuch Po prostu musisz wiedzieć, które obiekty podążają za innymi obiektami. W najprostszym przypadku będzie to po prostu A po B, ale może obejmować więcej obserwujących. Jest wyznaczony lider łańcuchu .
Ścieżka Dla każdego łańcucha potrzebujesz ścieżki. W zależności od tego, jak działa twoja gra, określisz, jak to będzie zorganizowane. W większości przypadków będzie to jakaś połączona lista. Spowoduje to śledzenie pozycji, które musi przestrzegać każdy w łańcuchu.
Teraz lider w łańcuchu będzie dodawał przedmioty do ścieżki . Za każdym razem, gdy się poruszy, doda coś do nagłówka listy. Każdy obiekt w łańcuchu pamięta, gdzie jest na liście. Jeśli chodzi o przenoszenie, po prostu przechodzi do następnego elementu na liście (odpowiednio interpolowanego, jeśli to konieczne). Gdy ostatni element w łańcuchu przesuwa się obok elementu na liście, element ten można upuścić (będzie na ogonie).
Metaforycznie przywódca pozostawia ślad swoim partnerom. Ostatni obserwujący na liście zużywa bułkę tartą.
To, czy twoja lista zawiera pojedyncze punkty, czy tylko wierzchołki ścieżki, czy coś innego, zależy całkowicie od twojego silnika gry. Ale w każdym razie nie widzę, że będziesz w stanie ominąć samą listę.
źródło
Wyszukaj ścieżkę *. Jest to ogólny i łatwy sposób, aby twoje podmioty / obiekty gry trafiły / podążały za pozycją.
źródło