เทคนิคสำหรับวัตถุที่ติดตามซึ่งกันและกันในการเคลื่อนไหวที่สมบูรณ์?


14

ฉันสงสัยว่าวัตถุจะติดตามซึ่งกันและกันเมื่อพวกมันเคลื่อนที่ไปยังตำแหน่งก่อนหน้าของวัตถุที่อยู่ด้านหน้า เมื่อวัตถุนำหยุดทั้งหมดที่ตามมาควรหยุดที่ตำแหน่งของพวกเขา ดังนั้นสิ่งนี้สำเร็จได้อย่างไร

ชอบมาก

ป้อนคำอธิบายรูปภาพที่นี่

แก้ไข:
สิ่งที่ฉันต้องการบรรลุคือวัตถุทั้งหมดต่อไปนี้ "เดิน" เส้นทางที่วัตถุนำหน้าอยู่ วัตถุอื่นทั้งหมดเพียงแค่เคลื่อนที่ด้วยความเร็วของวัตถุนำ (ซึ่งจะเป็นการส่งเวกเตอร์ความเร็วไปยังวัตถุต่อไปนี้ทั้งหมด) แต่ฉันจะปล่อยให้วัตถุทั้งหมดเคลื่อนที่ / หยุดชั่วคราวบนเส้นทางในขณะที่รักษาระยะห่างจากกันและกันได้อย่างไร

คำตอบ:


11

ใช้รายการชื่อ "เส้นทาง" เพื่อจัดเก็บจุดทางที่อธิบายเส้นทางของคุณและรายการที่เชื่อมโยงสองเท่าเรียกว่า "งู" เพื่อเก็บวัตถุที่เคลื่อนไหวและเส้นทาง

วัตถุชั้นนำจะกำหนดจุดทางใหม่ในขณะที่เดินทาง วัตถุต่อไปนี้เคลื่อนที่ไปตามเส้นทางที่กำหนดโดยจุดทางเหล่านี้

แต่ละวัตถุมีเขตความปลอดภัยที่กำหนดโดยระยะทาง หากวัตถุชั้นนำหยุดทำงานวัตถุต่อไปนี้จะเคลื่อนที่ต่อไปจนกว่าพวกเขาจะสัมผัสโซนความปลอดภัยของรุ่นก่อน

ต่อไปนี้เป็นโค้ดหลอกสำหรับวิธีนำสิ่งเหล่านี้ไปปฏิบัติ โปรดทราบว่านี่อาจไม่ใช่โซลูชันที่หรูหราที่สุดในแง่ของการกระจายความรับผิดชอบและการห่อหุ้ม

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 ยิ่งใหญ่ขึ้นเรื่อย ๆ เกมก็จะยิ่งยาวขึ้น หาก Snake ของคุณมีอยู่พักหนึ่งคุณต้องลบ WayPoint สุดท้ายเมื่อใดก็ตามที่องค์ประกอบสุดท้ายของ Snake ผ่าน Waypoint of Path of the Second-to-Last จำไว้ว่าให้ลดระยะห่างจากทุกการเคลื่อนย้ายวัตถุของงูตามลำดับ


สมมติว่าฉันต้องการลากวัตถุนำของฉันด้วยเมาส์ (ไม่ใช่ที่ฉันต้องการ แต่สมมุติว่าฉันทำ) มันจะทำงานอย่างไรกับตัวอย่างของคุณ?
Sidar

รายการของวัตถุสามารถเคลื่อนย้ายได้โดยการปล่อยให้องค์ประกอบแรกเคลื่อนย้ายจากตำแหน่งปัจจุบันในทิศทางที่กำหนด (ด้วยความเร็วที่กำหนด) จากนั้นปล่อยให้องค์ประกอบอื่นทั้งหมดย้ายจากตำแหน่งปัจจุบันในทิศทางที่ระบุโดยตำแหน่งปัจจุบันและ $ this-> previousElement-> getPosition () หากคุณลากองค์ประกอบแรกของคุณไปที่อื่นคุณต้องเรียกใช้เมธอด setPosition () เมื่อรายการถูกแสดงผลวัตถุอื่น ๆ จะเปลี่ยนเส้นทางของพวกเขาไปตามรุ่นก่อน
BerndBrot

แก้ไขให้ถูกต้องหากฉันทำผิด แต่จะไม่ส่งผลให้วัตถุต่อไปนี้ใช้ทางลัดเมื่อพวกเขาเปลี่ยนทิศทางหรือไม่ (เหมือนในส่วนล่างของภาพที่ฉันให้) ดูเหมือนว่าพวกเขาจะไม่เดินไปตามเส้นทางของวัตถุที่อยู่ข้างหน้า แต่พวกเขาจะไปในทิศทางของวัตถุนำหน้าพวกเขาให้มากที่สุด ทำให้วัตถุออกนอกเส้นทางและใช้ทางลัดหรือไม่
Sidar

ใช่ว่าจะเกิดขึ้นจริงกับการใช้งานเฉพาะนี้ ฉันโพสต์คำตอบก่อนที่คุณจะเพิ่มรูปภาพของคุณดังนั้นลองอีกครั้ง ...
BerndBrot

Alright แล้วเรื่องนี้ล่ะ
BerndBrot

6

โดยพื้นฐานแล้วคุณจะต้องมีโครงสร้างข้อมูลสองแบบ (ตรรกะ, ล่วงล้ำหรือจริงขึ้นอยู่กับส่วนที่เหลือของรหัสของคุณ) คนแรกจะติดตามโซ่ของวัตถุและอื่น ๆ เส้นทาง

โซ่เพียงแค่คุณต้องรู้ว่าวัตถุใดกำลังตามวัตถุอื่น ในกรณีที่ง่ายที่สุดสิ่งนี้จะเป็นเพียง A ต่อไปนี้ B แต่อาจรวมผู้ติดตามเพิ่มเติม มีผู้นำที่ได้รับมอบหมายในสายโซ่

Pathสำหรับแต่ละ chain คุณจะต้องมี path ขึ้นอยู่กับว่าเกมของคุณทำงานอย่างไรจะกำหนดว่าสิ่งนี้มีโครงสร้างอย่างไร ในกรณีส่วนใหญ่จะเป็นรายการที่เชื่อมโยงบางชนิด นี้จะติดตามตำแหน่งที่ทุกคนในห่วงโซ่ต้องปฏิบัติตาม

ตอนนี้ผู้นำในห่วงโซ่จะเพิ่มรายการไปยังเส้นทาง ทุกครั้งที่มันขยับมันจะเพิ่มบางอย่างลงในส่วนหัวของรายการ วัตถุแต่ละชิ้นในห่วงโซ่จะจดจำตำแหน่งที่อยู่ในรายการ เมื่อมันมาถึงการเคลื่อนย้ายมันก็จะย้ายไปที่รายการถัดไปในรายการ เป็นรายการสุดท้ายในห่วงโซ่ย้ายรายการในรายการที่ผ่านมารายการนั้นสามารถทิ้ง (มันจะอยู่ที่ท้าย)

ผู้นำเชิงเปรียบเทียบจะทิ้งร่องรอยเอาไว้สำหรับผู้ติดตาม ผู้ติดตามคนสุดท้ายในรายการใช้เส้นทางครัมบ์

ไม่ว่ารายการของคุณจะมีคะแนนเป็นรายบุคคลหรือเพียงแค่จุดยอดของเส้นทางหรืออย่างอื่นถูกกำหนดโดยโปรแกรมเกมของคุณ แต่ในกรณีใด ๆ ฉันไม่เห็นว่าคุณจะสามารถหลีกเลี่ยงรายการได้


ใช่ฉันคิดสิ่งนั้น มันเป็นการใช้งานที่มักจะทำให้จิตใจของฉัน ขอบคุณสำหรับคำตอบว่า อนุมัติ berndBrots แล้ว แต่ให้คะแนนคุณมากกว่า
Sidar

-3

ค้นหา A * pathfinding นี่เป็นวิธีทั่วไป & วิธีง่าย ๆ ในการทำให้เอนทิตีเกม / วัตถุของคุณไปที่ / ติดตามตำแหน่ง


ฉันรู้ว่า A * คืออะไรไม่ใช่สิ่งที่ฉันกำลังมองหาและหนักเกินไปสำหรับบางสิ่งที่ดูเหมือนง่ายกว่า
Sidar

คำตอบของคุณไม่ได้ใกล้เคียงกับคำตอบที่ถูกต้อง A * เป็นอัลกอริทึมในการค้นหาเส้นทาง ในขณะที่เขาไม่ต้องการค้นหาสิ่งใดเขาเพียงต้องการให้วัตถุติดตามซึ่งกันและกันในทุกตำแหน่งที่วัตถุสุดท้ายเป็น
Ali1S232

เมื่อฉันตอบคำถามครั้งแรกมันไม่ได้ถูกกำหนดให้ชัดเจนขึ้น / ไม่มีภาพที่แสดงสิ่งที่เขาหมายถึง ฉันเพิ่งอ่าน 2 ประโยคแรกและคิดว่าเขามีหลายหน่วยงานพยายามติดตามบางสิ่งบางอย่างไม่ปฏิบัติตามเส้นทาง ขออภัยสำหรับคำตอบที่ไม่ดีฉันเดา
thedeadlylybutter

ฉันว่าพูดตามกัน = P ไม่ย้ายไปยังจุด
Sidar

ฉันรู้ว่าฉันขอโทษ
thedeadlybutter
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.