Tecnica per oggetti che si susseguono in completo movimento?


14

Mi chiedo come gli oggetti si susseguono quando si spostano sulla posizione precedente dell'oggetto di fronte a loro. Quando l'oggetto principale si ferma, tutto ciò che segue dovrebbe fermarsi nella loro posizione. Come si ottiene questo risultato?

Così:

inserisci qui la descrizione dell'immagine

Modifica:
Quello che voglio ottenere è che tutti i seguenti oggetti "percorrono" il percorso che sta prendendo l'oggetto principale di fronte. Tutti gli altri oggetti si muovono semplicemente alla velocità dell'oggetto principale (questo sarebbe passare il vettore di velocità a tutti i seguenti oggetti). Ma come faccio a far muovere / mettere in pausa tutti gli oggetti lungo il percorso mantenendo la loro distanza.

Risposte:


11

Utilizzare un Elenco chiamato "Percorso" per memorizzare i punti di passaggio che descrivono il percorso e un elenco doppiamente collegato chiamato "Serpente" per memorizzare gli oggetti in movimento e il Percorso.

L'oggetto principale definisce nuovi waypoint mentre viaggia. I seguenti oggetti si spostano lungo il percorso come definito da questi punti di passaggio.

Ogni oggetto ha una zona di sicurezza definita da una certa distanza. Se l'oggetto principale si arresta, i seguenti oggetti si spostano solo fino a quando non toccano la zona di sicurezza del loro predecessore.

Ecco alcuni pseudo-codici per come queste cose potrebbero essere implementate. Essere consapevoli del fatto che questa potrebbe non essere la soluzione più elegante in termini di distribuzione delle responsabilità e incapsulamento.

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();
        }
    }
}

Percorso-> WayPoints diventa sempre più grande quanto più il gioco procede. Se il tuo Serpente esiste da un po 'di tempo, devi eliminare l'ultimo WayPoint ogni volta che l'ultimo elemento del Serpente ha superato il penultimo WayPoint di Path. Ricorda di ridurre di conseguenza anche distanceFromEnd in tutti gli MovingObjects di Snake.


Diciamo che vorrei trascinare il mio oggetto principale con il mouse (non quello che voglio, ma diciamo che lo faccio). Come funzionerebbe con il tuo esempio?
Sidar,

L'elenco di oggetti potrebbe spostarsi lasciando prima che il primo elemento si spostasse dalla sua posizione corrente in una data direzione (con una data velocità), e quindi lasciando che tutti gli altri elementi si spostassero dalle loro posizioni correnti in una direzione specificata dalla loro posizione corrente e $ this-> previousElement-> getPosition (). Se trascini il tuo primo elemento da qualche parte, devi solo chiamare il suo metodo setPosition (). Quando viene visualizzato l'elenco, gli altri oggetti cambieranno il loro percorso per seguire i loro predecessori.
BerndBrot,

Correggimi se sbaglio, ma ciò non provocherebbe anche che gli oggetti che seguono prendono scorciatoie mentre cambiano direzione? (come nella parte inferiore dell'immagine che ho dato). Sembra che non seguirebbero il percorso dell'oggetto davanti. Invece andrebbero nella direzione dell'oggetto principale davanti a loro il più possibile. Causare gli oggetti che vanno fuori strada e prendere scorciatoie?
Sidar,

Sì, sarebbe davvero accaduto con questa particolare implementazione. Ho pubblicato la risposta prima di aggiungere le tue foto, quindi
riproviamo

Tutto a posto. Che dire di questo?
BerndBrot,

6

Fondamentalmente avrai bisogno di due strutture di dati (logica, intrusiva o reale, a seconda del resto del codice). Il primo seguirà le catene di oggetti e l'altro il percorso.

Catena Semplicemente devi sapere quali oggetti seguono altri oggetti. Nel caso più semplice questo sarà semplicemente A segue B, ma potrebbe includere più follower. C'è un leader designato nella catena.

Percorso Per ogni catena è necessario un percorso. A seconda di come funziona il tuo gioco determinerà come è strutturato. Nella maggior parte dei casi sarà una specie di elenco collegato. Questo seguirà le posizioni che tutti nella catena devono seguire.

Ora, il leader della catena aggiungerà elementi al percorso . Ogni volta che si sposta aggiungerà qualcosa in testa alla lista. Ogni oggetto nella catena ricorda dove si trova nell'elenco. Quando si tratta di spostarsi, si sposta semplicemente sull'elemento successivo nell'elenco (interpolato opportunamente se necessario). Mentre l'ultimo elemento nella catena si sposta oltre un elemento nell'elenco, quell'elemento può essere eliminato (sarà alla coda).

Metaforicamente il leader lascia una scia di pangrattato per i suoi seguaci. L'ultimo follower nell'elenco consuma il pangrattato.

Se la tua lista contiene punti individuali, o solo i vertici di un percorso, o qualcos'altro, è determinato interamente dal tuo motore di gioco. Ma in ogni caso non vedo che sarai in grado di evitare l'elenco stesso.


Sì, ho pensato a una cosa del genere. È l'implementazione che di solito implora la mia mente. Grazie per la risposta però. Risposta di berndBrots approvata ma votata come tua.
Sidar,

-3

Ricerca A * pathfinding. Questo è un modo semplice e generale per far sì che le entità / oggetti di gioco vadano / seguano una posizione.


So cos'è A *, non quello che sto cercando e decisamente troppo pesante per qualcosa che sembra piuttosto molto più semplice.
Sidar,

la tua risposta non è nemmeno vicina a quale sia la risposta corretta. A * è un algoritmo per trovare un percorso. Anche se non vuole trovare nulla, vuole solo che l'oggetto si segua esattamente in ogni posizione dell'ultimo oggetto.
Ali1S232,

Quando originariamente ho risposto alla domanda, non è stato risolto chiarire di più / non c'era un'immagine che mostrasse cosa intendesse dire. Ho appena letto le prime 2 frasi e ho pensato che avesse più entità che cercavano di rintracciare qualcosa, non seguire un percorso. Ci scusiamo per la risposta cattiva immagino
thedeadlybutter

Ho detto di seguirsi = P non passare a un punto.
Sidar,

Lo so, le mie scuse.
thedeadlybutter,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.