物体在完全运动中彼此跟随的技术?


14

我想知道对象如何在它们前面的对象先前位置上方移动时彼此跟随。当引导对象停止时,所有跟随的对象应停止在其位置。那么如何实现呢?

像这样:

在此处输入图片说明

编辑:
我要实现的是,以下所有对象“走”前面的领先对象所走的路径。所有其他对象仅以领先对象的速度移动(这可以通过将速度矢量传递给所有后续对象)来实现。但是,如何让所有对象在路径上移动/暂停,同时又保持它们彼此之间的距离。

Answers:


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存在了很长一段时间,则每当Snake的最后一个元素经过路径的倒数第二WayPoint时,您都需要删除最后一个WayPoint。请记住,还要相应地减少Snake的所有MovingObjects中的distanceFromEnd。


假设我想用鼠标拖动我的前导对象(不是我想要的,而是我这样做)。您的示例如何使用?
Sidar 2012年

通过首先让第一个元素从其当前位置沿给定方向(以给定速度)移动,然后让所有其他元素从其当前位置沿其当前位置和$指定的方向移动,可以移动对象列表此-> previousElement-> getPosition()。如果将第一个元素拖到某个位置,则只需调用其setPosition()方法。呈现列表时,其他对象将更改其路径以遵循其前身。
2012年

如果我错了,请纠正我,但是这样会不会导致对象跟随快捷方式改变方向?(就像我给出的图像的下部)。听起来好像他们不会沿着对象的路径前进。取而代之的是,它们将尽可能多地朝着它们前面的引导对象的方向前进。是否导致对象偏离路径并采用快捷方式?
Sidar 2012年

是的,在此特定实现中确实会发生这种情况。在您添加图片之前,我已经发布了答案,所以让我们再试一次...
BerndBrot 2012年

好的。那这个呢?
2012年

6

本质上,您将需要两个数据结构(逻辑的,侵入的或实际的,具体取决于您的其余代码)。第一个将跟踪对象链,第二个将跟踪路径。

简单地,您需要知道哪些对象跟随其他对象。在最简单的情况下,这将是A跟随B,但可能包括更多的追随者。链中有指定的领导者

路径对于每个链,您都需要一个路径。根据游戏的工作方式,将决定游戏的结构。在大多数情况下,它将是某种链表。这将跟踪链中每个人需要遵循的位置。

现在,链中的领导者将在路径中添加项目。每次移动都会在列表的开头添加一些内容。链中的每个对象都会记住它在列表上的位置。谈到移动时,它仅移动到列表中的下一项(必要时进行适当插值)。当链中的最后一个项目经过列表中的一个项目时,该项目可以被删除(它将位于末尾)。

隐喻上,领导者为其追随者留下了一条面包屑的痕迹。列表中的最后一个关注者消耗了面包屑。

您的列表中是否包含单个点,还是仅包含路径的顶点,还是其他内容,完全由游戏引擎决定。但无论如何,我看不到您可以避免使用列表本身。


是的,我想到了这样的事情。通常是让我震惊的实现。谢谢你的回答。批准的berndBrots可以回答您的问题。
Sidar 2012年

-3

查找A *寻路。这是让您的游戏实体/对象去到/跟随位置的一种通用且简便的方法。


我知道A *是什么,而不是我要寻找的东西,而且对于看起来似乎更简单的东西来说太重了。
Sidar 2012年

您的答案甚至接近正确答案。A *是找到路径的算法。虽然他什么也不想发现,但他只是希望对象在最后一个对象所处的每个位置都能够准确地彼此跟随。
Ali1S232

当我最初回答这个问题时,并不确定要进一步澄清/没有图片显示他的意思。我刚读了前两句话,就发现他有多个实体试图追踪某些东西,而不是遵循路径。对不起,我猜错了答案
thedeadlybutter

我确实说过互相追随= P不能走到一点。
西达尔

我知道,很抱歉。
thedeadlybutter 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.