완벽한 움직임으로 서로를 따르는 물체를위한 기술?


14

물체가 물체의 이전 위치 위로 움직일 때 물체가 서로 어떻게 따라 가는지 궁금합니다. 선행 객체가 중지되면 다음에 오는 모든 것이 해당 위치에서 중지됩니다. 어떻게 이것이 달성됩니까?

이렇게 :

여기에 이미지 설명을 입력하십시오

편집 :
내가 달성하고자하는 것은 다음의 모든 객체가 앞의 객체가 앞을 향하는 길을 "걷는"것입니다. 다른 모든 객체는 선행 객체의 속도로 이동합니다 (속도 벡터를 다음의 모든 객체에 전달 함). 그러나 모든 객체가 서로 거리를 유지하면서 경로 위로 이동 / 일시 중지시키는 방법은 무엇입니까?

답변:


11

"Path"라는 목록을 사용 하여 경로를 설명하는 웨이 포인트 를 저장하고 "Snake"라는 이중 연결 목록 을 사용하여 움직이는 객체와 경로를 저장하십시오.

선행 객체는 여행 할 때 새로운 웨이 포인트를 정의합니다. 다음 객체는 이러한 웨이 포인트로 정의 된 경로를 따라 이동합니다.

각 개체에는 일정한 거리로 정의 된 보안 영역이 있습니다. 선행 개체가 중지되면 다음 개체는 이전 보안 영역에 닿을 때까지만 이동합니다.

이러한 것들이 어떻게 구현 될 수 있는지에 대한 의사 코드가 있습니다. 이것은 책임 분배 및 캡슐화 측면에서 가장 우아한 솔루션이 아닐 수도 있습니다.

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는 게임이 계속 될수록 커지고 커집니다. 스네이크가 꽤 오랫동안 존재하는 경우 스네이크의 마지막 요소가 경로의 두 번째에서 마지막 웨이 포인트를 지날 때마다 마지막 WayPoint를 삭제해야합니다. 또한 모든 Snake 이동 오브젝트에서 distanceFromEnd를 줄여야합니다.


마우스로 주요 객체를 드래그하고 싶다고 가정 해 봅시다 (원하는 것이 아니라 수행한다고 가정 해 봅시다). 그것은 당신의 모범과 어떻게 작동합니까?
Sidar

객체 목록은 먼저 첫 번째 요소가 주어진 방향으로 주어진 방향으로 현재 위치에서 이동하게 한 다음 다른 모든 요소가 현재 위치에서 현재 위치와 $로 지정된 방향으로 이동하게하여 이동할 수 있습니다 this-> previousElement-> getPosition (). 첫 번째 요소를 어딘가로 드래그하면 setPosition () 메서드를 호출하기 만하면됩니다. 목록이 렌더링 될 때 다른 객체는 선행 작업을 따르도록 경로를 변경합니다.
BerndBrot

내가 틀렸다면 수정하십시오. 그러면 객체가 방향을 바꿀 때 단축키를 따르는 결과를 얻지 않습니까? (내가 제공 한 이미지의 하단 부분과 같이). 물체의 경로를 따라 가지 않는 것처럼 들립니다. 대신 그들은 가능한 한 앞선 물체의 방향으로 들어갔다. 경로에서 벗어난 객체를 발생시키고 바로 가기를 수행합니까?
Sidar

그렇습니다. 이것은 실제로이 특정 구현에서 일어날 것입니다. 나는 당신이 당신의 사진을 추가하기 전에 답변을 게시했습니다, 다시 시도하자 ...
BerndBrot

좋구나. 이건 어때?
BerndBrot

6

기본적으로 두 가지 데이터 구조 (나머지 코드에 따라 논리, 침입 또는 실제)가 필요합니다. 첫 번째는 객체의 체인을 추적하고 다른 하나는 경로를 추적합니다.

체인 단순히 다른 개체를 따르는 개체를 알아야합니다. 가장 간단한 경우에는 단순히 A 다음에 B가되지만 더 많은 추종자를 포함 할 수 있습니다. 체인에 지정된 리더 가 있습니다.

경로 각 체인마다 경로가 필요합니다. 게임 작동 방식에 따라 이것이 어떻게 구성되는지가 결정됩니다. 대부분의 경우 일종의 연결 목록이됩니다. 체인의 모든 사람이 따라야 할 위치를 추적합니다.

이제 체인 의 리더경로에 항목을 추가합니다 . 움직일 때마다 목록의 머리 부분에 무언가가 추가됩니다. 체인의 각 개체는 목록의 위치를 ​​기억합니다. 이동할 때 간단히 목록의 다음 항목으로 이동합니다 (필요한 경우 적절하게 보간 됨). 체인의 마지막 항목이 목록의 항목을 지나갈 때 해당 항목을 놓을 수 있습니다 (꼬리에 있음).

은유 적으로 지도자는 추종자들을 위해 빵 부스러기 흔적을 남깁니다. 목록의 마지막 팔로어는 이동 경로를 사용합니다.

목록에 개별 지점이 포함되어 있는지 또는 경로의 정점 또는 기타가 포함되어 있는지 여부는 전적으로 게임 엔진에 의해 결정됩니다. 그러나 어쨌든 목록 자체를 피할 수는 없습니다.


그래 그런 걸 알아 냈어 일반적으로 내 마음을 암시하는 구현입니다. 그래도 답변 주셔서 감사합니다. 승인 된 berndBrots는 응답하지만 귀하의 의견을 올렸습니다.
Sidar

-3

조회 A * 경로 찾기. 게임 엔터티 / 객체가 위치를 이동하거나 따라 가도록하는 일반적이고 쉬운 방법입니다.


나는 A *가 무엇인지, 내가 찾고있는 것이 아니라 훨씬 더 무거운 것으로 너무 무겁습니다.
Sidar

당신의 대답은 정답에 가깝지 않습니다. A *는 경로를 찾기위한 알고리즘입니다. 그는 아무것도 찾고 싶지 않지만, 마지막 물체가 있었던 모든 위치에서 물체가 서로를 정확히 따르기를 원합니다.
Ali1S232

원래 질문에 대답했을 때 더 명확하게 설명하지 않았으며 / 그가 무엇을 의미하는지 보여주는 그림이 없었습니다. 방금 처음 두 문장을 읽었으며 경로를 따르지 않고 여러 엔티티가 무언가를 추적하려고한다고 생각했습니다. 내가 생각하는 나쁜 대답에 대해 죄송합니다
deaddeadbutter

나는 서로를 따라 = P 지점으로 이동하지 말라고 말했다.
Sidar

나는 사과한다.
thedeadlybutter
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.