Kỹ thuật cho các đối tượng theo nhau trong chuyển động hoàn chỉnh?


14

Tôi đang tự hỏi làm thế nào các vật thể theo dõi nhau khi chúng di chuyển qua vị trí trước đó của vật thể trước mặt chúng. Khi đối tượng dẫn đầu dừng lại, tất cả những gì đang theo sau sẽ dừng ở vị trí của chúng. Vậy làm thế nào để đạt được điều này?

Thích như vậy:

nhập mô tả hình ảnh ở đây

Chỉnh sửa:
Điều tôi muốn đạt được là tất cả các đối tượng sau đây "đi" theo con đường mà đối tượng dẫn đầu ở phía trước đang đi. Tất cả các vật thể khác chỉ di chuyển với tốc độ của vật thể dẫn đầu (điều này sẽ bằng cách chuyển vectơ vận tốc cho tất cả các vật thể sau). Nhưng làm thế nào để tôi để tất cả các đối tượng di chuyển / tạm dừng trên đường đi trong khi vẫn duy trì khoảng cách với nhau.

Câu trả lời:


11

Sử dụng Danh sách được gọi là "Đường dẫn" để lưu trữ các điểm mô tả đường dẫn của bạn và danh sách được liên kết đôi có tên là "Rắn" để lưu trữ các đối tượng và Đường dẫn di chuyển.

Đối tượng hàng đầu định nghĩa các điểm mới khi nó di chuyển. Các đối tượng sau di chuyển dọc theo đường dẫn như được xác định bởi các điểm này.

Mỗi đối tượng có một vùng bảo mật được xác định bởi một số khoảng cách. Nếu đối tượng dẫn đầu dừng lại, các đối tượng sau chỉ di chuyển cho đến khi chúng chạm vào vùng bảo mật của người tiền nhiệm.

Đây là một số mã giả cho cách thực hiện những điều này. Xin lưu ý rằng đây có thể không phải là giải pháp tao nhã nhất về mặt phân phối trách nhiệm và đóng gói.

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

Đường dẫn-> WayPoints trở nên lớn hơn và lớn hơn khi trò chơi diễn ra lâu hơn. Nếu Snake của bạn tồn tại khá lâu, bạn cần xóa Waypoint cuối cùng bất cứ khi nào phần tử cuối cùng của Snake vượt qua Waypoint của đường dẫn thứ hai đến cuối cùng. Hãy nhớ cũng giảm khoảng cáchFromEnd trong tất cả các MoveObjects của Snake tương ứng.


Giả sử tôi muốn kéo đối tượng hàng đầu của mình bằng chuột (không phải tôi muốn, nhưng hãy nói rằng tôi làm như vậy). Làm thế nào mà làm việc với ví dụ của bạn?
Sidar

Danh sách các đối tượng có thể di chuyển bằng cách trước tiên cho phép phần tử đầu tiên di chuyển từ vị trí hiện tại của nó theo một hướng nhất định (với tốc độ nhất định), sau đó cho phép tất cả các phần tử khác di chuyển từ vị trí hiện tại của chúng theo hướng được chỉ định bởi vị trí hiện tại của chúng và $ this-> trướcEuity-> getP vị trí (). Nếu bạn kéo phần tử đầu tiên của mình ở đâu đó, bạn chỉ cần gọi phương thức setPocation () của nó. Khi danh sách được hiển thị, các đối tượng khác sẽ thay đổi đường dẫn của chúng để đi theo người tiền nhiệm.
BerndBrot

Chỉnh sửa cho tôi nếu tôi sai nhưng điều đó cũng sẽ dẫn đến các đối tượng sau khi dùng phím tắt khi chúng đổi hướng? (giống như ở phần dưới của hình ảnh tôi đã đưa ra). Có vẻ như họ sẽ không đi theo con đường của đối tượng lên phía trước. Thay vào đó, họ sẽ đi vào hướng của đối tượng dẫn đầu trước mặt họ càng nhiều càng tốt. Làm cho các đối tượng đi ra khỏi đường dẫn và đi đường tắt?
Sidar

Vâng, điều đó thực sự sẽ xảy ra với việc thực hiện cụ thể này. Tôi đã đăng câu trả lời trước khi bạn thêm hình ảnh của mình, vì vậy hãy thử lại ...
BerndBrot

Ổn thỏa. Cái này thì sao?
BerndBrot

6

Về cơ bản, bạn sẽ cần hai cấu trúc dữ liệu (logic, xâm nhập hoặc thực, tùy thuộc vào phần còn lại của mã của bạn). Đầu tiên sẽ theo dõi chuỗi các đối tượng, và đường dẫn khác.

Chuỗi Đơn giản là bạn cần biết những đối tượng nào đang theo dõi các đối tượng khác. Trong trường hợp đơn giản nhất, đây sẽ chỉ là A theo B, nhưng có thể bao gồm nhiều người theo dõi hơn. Có một nhà lãnh đạo được chỉ định trong chuỗi.

Đường dẫn Đối với mỗi chuỗi bạn sẽ cần một đường dẫn. Tùy thuộc vào cách trò chơi của bạn hoạt động sẽ xác định cách cấu trúc này. Trong hầu hết các trường hợp, nó sẽ là một số loại danh sách liên kết. Điều này sẽ theo dõi các vị trí mà mọi người trong chuỗi cần phải tuân theo.

Bây giờ, người lãnh đạo trong chuỗi sẽ thêm các mục vào đường dẫn . Mỗi khi nó di chuyển nó sẽ thêm một cái gì đó vào đầu danh sách. Mỗi đối tượng trong chuỗi ghi nhớ vị trí trong danh sách. Khi nói đến việc di chuyển, nó chỉ cần di chuyển đến mục tiếp theo trong danh sách (được nội suy một cách thích hợp nếu cần thiết). Khi mục cuối cùng trong chuỗi di chuyển qua một mục trong danh sách, mục đó có thể bị hủy (mục này sẽ ở phần đuôi).

Nói một cách ẩn dụ, nhà lãnh đạo để lại dấu vết vụn bánh mì cho những người theo dõi nó. Người theo dõi cuối cùng trong danh sách tiêu thụ mẩu bánh mì.

Cho dù danh sách của bạn có chứa các điểm riêng lẻ hay chỉ các đỉnh của một đường dẫn hoặc thứ gì khác, được xác định hoàn toàn bởi công cụ trò chơi của bạn. Nhưng trong mọi trường hợp tôi không thấy rằng bạn sẽ có thể tránh danh sách đó.


Vâng, tôi đã tìm ra điều đó. Đó là việc thực hiện thường làm tôi suy nghĩ. Cảm ơn vì câu trả lời. BerndBrots đã chấp thuận trả lời nhưng nâng cấp của bạn.
Sidar

-3

Tra cứu A * tìm đường. Đây là một cách chung & dễ dàng để đưa các thực thể / đối tượng trò chơi của bạn đến / theo dõi một vị trí.


Tôi biết A * là gì, không phải thứ tôi đang tìm kiếm và quá nặng nề cho một thứ dường như đơn giản hơn nhiều.
Sidar

câu trả lời của bạn thậm chí không gần với câu trả lời đúng. A * là một thuật toán để tìm đường dẫn. Trong khi anh ta không muốn tìm thấy bất cứ điều gì, anh ta chỉ muốn đối tượng theo dõi nhau chính xác ở mọi vị trí đối tượng cuối cùng.
Ali1S232

Khi tôi ban đầu trả lời câu hỏi, nó không cố định để làm rõ hơn / không có hình ảnh để cho biết ý của anh ấy. Tôi mới đọc 2 câu đầu tiên và hình dung anh ta đang có nhiều thực thể cố gắng theo dõi thứ gì đó, không đi theo một con đường. Xin lỗi vì câu trả lời tệ mà tôi đoán
thedeadlybutter

Tôi đã nói theo nhau = P không di chuyển đến một điểm.
Sidar

Tôi biết, lời xin lỗi của tôi.
thedeadlybutter
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.