Teknik untuk objek saling mengikuti dalam gerakan lengkap?

14

Saya bertanya-tanya bagaimana benda mengikuti satu sama lain di mana mereka bergerak di atas posisi sebelumnya dari objek di depan mereka. Ketika objek utama berhenti, semua yang mengikuti harus berhenti di posisi mereka. Jadi bagaimana ini dicapai?

Seperti itu:

masukkan deskripsi gambar di sini

Sunting:
Yang ingin saya capai adalah bahwa semua objek berikut "berjalan" di jalur yang diambil oleh objek utama di depan. Semua objek lain hanya bergerak dengan kecepatan objek yang mengarah (ini akan dengan melewatkan vektor kecepatan ke semua objek berikut). Tetapi bagaimana saya membiarkan semua benda bergerak / berhenti di atas jalan sambil menjaga jarak satu sama lain juga.

Sidar
sumber

Jawaban:

11

Gunakan Daftar yang disebut "Jalur" untuk menyimpan titik-jalan yang menggambarkan jalur Anda, dan daftar yang terhubung ganda yang disebut "Ular" untuk menyimpan objek dan Jalur yang bergerak.

Objek terdepan menentukan titik jalan baru saat bergerak. Objek berikut bergerak di sepanjang jalan sebagaimana ditentukan oleh titik-cara ini.

Setiap objek memiliki zona keamanan yang ditentukan oleh jarak tertentu. Jika objek utama berhenti, objek berikut hanya bergerak sampai mereka menyentuh zona keamanan pendahulunya.

Berikut adalah beberapa pseudo-code untuk bagaimana hal-hal ini dapat diimplementasikan. Sadarilah bahwa ini mungkin bukan solusi yang paling elegan dalam hal distribusi tanggung jawab dan enkapsulasi.

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

Path-> WayPoints menjadi lebih besar dan lebih besar semakin lama permainan berlangsung. Jika Snake Anda ada selama beberapa waktu, Anda perlu menghapus WayPoint terakhir setiap kali elemen terakhir dari Snake telah melewati WayPoint of Path kedua ke terakhir. Ingatlah untuk juga mengurangi distanceFromEnd di semua MovingObjects of Snake sesuai.

BerndBrot
sumber
Katakanlah saya ingin menyeret objek utama saya dengan mouse saya (bukan yang saya inginkan, tetapi katakanlah saya lakukan). Bagaimana itu akan bekerja dengan teladan Anda?
Sidar
Daftar objek dapat bergerak dengan terlebih dahulu membiarkan elemen pertama bergerak dari posisi saat ini dalam arah tertentu (dengan kecepatan tertentu), dan kemudian membiarkan semua elemen lain bergerak dari posisi mereka saat ini dalam arah yang ditentukan oleh posisi mereka saat ini dan $ this-> previousElement-> getPosition (). Jika Anda menyeret elemen pertama Anda ke suatu tempat, Anda hanya perlu memanggil metode setPosition (). Ketika daftar diberikan, objek lain akan mengubah jalurnya untuk mengikuti pendahulunya.
BerndBrot
Koreksi saya jika saya salah tetapi bukankah itu juga mengakibatkan objek mengikuti mengambil pintasan saat mereka berubah arah? (seperti di bagian bawah gambar yang saya berikan). Sepertinya mereka tidak akan mengikuti jalur objek di depan. Sebaliknya mereka akan pergi ke arah objek terkemuka di depan mereka sebanyak mungkin. Menyebabkan benda keluar jalur dan mengambil jalan pintas?
Sidar
Ya, itu memang akan terjadi dengan implementasi khusus ini. Saya memposting jawaban sebelum Anda menambahkan foto Anda, jadi mari kita coba lagi ...
BerndBrot
Baik. Bagaimana dengan ini?
BerndBrot
6

Pada dasarnya Anda akan membutuhkan dua struktur data (logis, intrusif, atau nyata, tergantung pada sisa kode Anda). Yang pertama akan melacak rantai benda, dan yang lainnya jalan.

Rantai Cukup Anda perlu tahu benda mana yang mengikuti benda lain. Dalam kasus paling sederhana, ini hanya akan menjadi A mengikuti B, tetapi dapat mencakup lebih banyak pengikut. Ada pemimpin yang ditunjuk dalam rantai.

Jalan Untuk setiap rantai Anda akan membutuhkan jalan. Bergantung pada bagaimana game Anda bekerja akan menentukan bagaimana ini terstruktur. Dalam kebanyakan kasus itu akan menjadi semacam daftar yang ditautkan. Ini akan melacak posisi yang harus diikuti oleh semua orang dalam rantai.

Sekarang, pemimpin dalam rantai akan menambahkan item ke jalan . Setiap kali bergerak, itu akan menambahkan sesuatu ke kepala daftar. Setiap objek dalam rantai akan mengingat di mana ia berada. Ketika tiba saatnya untuk memindahkannya, ia hanya bergerak ke item berikutnya dalam daftar (diinterpolasi dengan tepat jika perlu). Saat item terakhir dalam rantai bergerak melewati item dalam daftar, item itu dapat dijatuhkan (itu akan berada di bagian ekor).

Secara metaforis pemimpin meninggalkan jejak remah roti bagi para pengikutnya. Pengikut terakhir dalam daftar mengkonsumsi remah roti.

Apakah daftar Anda berisi poin individual, atau hanya simpul jalur, atau sesuatu yang lain, sepenuhnya ditentukan oleh mesin gim Anda. Tetapi bagaimanapun juga saya tidak melihat bahwa Anda dapat menghindari daftar itu sendiri.

edA-qa mort-ora-y
sumber
Ya saya pikir hal seperti itu. Implementasinya yang biasanya merusak pikiran saya. Terima kasih atas jawabannya. Jawaban berndBrots yang disetujui tetapi Anda tervvotasikan.
Sidar
-3

Pencarian A * merintis jalan. Ini adalah cara umum & mudah untuk membuat entitas / objek permainan Anda masuk / mengikuti suatu posisi.

sampai jumpa
sumber
Saya tahu apa A *, bukan apa yang saya cari dan terlalu berat untuk sesuatu yang tampaknya jauh lebih sederhana.
Sidar
jawaban Anda bahkan tidak mendekati jawaban yang benar. A * adalah algoritma untuk menemukan jalur. Meskipun dia tidak ingin menemukan apa pun, dia hanya ingin objek saling mengikuti persis di setiap posisi objek terakhir itu.
Ali1S232
Ketika saya awalnya menjawab pertanyaan itu tidak tetap untuk mengklarifikasi lebih banyak / tidak ada gambar untuk menunjukkan apa yang dia maksud. Saya baru saja membaca 2 kalimat pertama dan membayangkan dia memiliki banyak entitas yang mencoba melacak sesuatu, tidak mengikuti jalan. Maaf untuk jawaban yang buruk kurasa
thedeadlybutter
Saya bilang saling mengikuti = P tidak pindah ke suatu titik.
Sidar
Saya tahu, permintaan maaf saya.
thedeadlybutter