如果玩家在附近,将幽灵移向迷宫中的玩家?

Move ghost toward player in maze if player is nearby?

我认为这是一件相当容易实现的事情,但我只想让鬼魂一次开始向玩家移动一个 space,如果玩家在 5 space 秒内鬼。在我的 if 语句中 move_to_x_y 是应该添加更改的地方。我怎样才能让 if 语句根据玩家所在的位置移动?

这是检查幽灵是否在五 space 秒内的函数:

bool Game::nearby (Ghost & ghost) const
{
if (abs(m_player->get_x() - ghost.get_x()) < 5)
    return true;
if (abs(m_player->get_y() - ghost.get_y()) < 5)
    return true;
return false;
}

然后是幽灵的移动功能,他通常只是随机移动,当玩家不在五个space秒内时是else情况:

void Ghost::move (Game & game) {
Floor *     floor;
int         r;
bool        moved = false;

floor = game.get_curr_floor();
do
{
    if (game.nearby(*this))
        r = //WHAT TO ADD HERE???
    else {
    r = rand() % 4;
    switch (r)
    {
    case 0:
        moved = floor->move_to_x_y (game, *this, 1, 0);
        break;
    case 1:
        moved = floor->move_to_x_y (game, *this, 0, -1);
        break;
    case 2:
        moved = floor->move_to_x_y(game, *this, -1, 0);
        break;
    case 3:
        moved = floor->move_to_x_y(game, *this, 0, 1);
        break;
    }
    }
}
while (! moved);
}

所以根据玩家的位置,向上、向下、向左或向右移动,朝向他们。

感谢您的帮助!

你的函数 return 判断玩家是否在附近,但没有给出玩家所在方向的信息。将 return 值从 bool 更改为 int,或者指示方向的东西。例如:

int Game::nearby (Ghost & ghost) const
{
if (ghost.get_x() - m_player->get_x() < 5 && ghost.get_x() - m_player->get_x() > 0)
    return 2;
if (m_player->get_x() - ghost.get_x() < 5 && m_player->get_x() - ghost.get_x() > 0)
    return 0;
if (ghost.get_y() - m_player->get_y() < 5 && ghost.get_y() - m_player->get_y() > 0)
    return 3;
if (m_player->get_y() - ghost.get_y() < 5 && m_player->get_y() - ghost.get_y() > 0)
    return 1;
return -1;
}

这将return已经对应你希望他在你的switch语句中移动的方向的数字。因此,您在移动函数中所要做的就是将 r 设置为 int "nearby" returns,如果它是 returns -1,则像以前一样将其设置为随机方向。

r = game.nearby(*this);
if (r == -1)
    r = rand() % 4;

switch (r) .... etc

如果玩家在附近,我会将 bool Game::nearby 更改为 return 罗盘点。


编辑:对设计误解的评论

Game::nearby()并不是要强行搬鬼。它旨在为幽灵提供有关玩家位置的信息。如何使用这些信息取决于幽灵策略。所以附近应该 return 以度数、罗盘点或作为距离矢量的方向。然后幽灵可能会决定接近玩家或坐下来躲避。在吃豆子游戏中,所有 4 个怪物都可以使用此功能,但应用不同的策略。

两部分。首先,尽量靠近玩家

void Ghost::move (Game & game) {
    Floor *     floor game.get_curr_floor();
    bool        moved = false;

    if (game.nearby(*this)) {
        //try to move closer in x direction
        if (game.get_player()->get_x() > ghost.get_x())
            moved = floor->move_to_x_y (game, *this, 1, 0);
        else if (ghost.get_x() > game.get_player()->get_x())
            moved = floor->move_to_x_y (game, *this, -1, 0);
        //if we haven't moved, try to move closer in y direction
        if (!moved && game.get_player()->get_y() > ghost.get_y())
            moved = floor->move_to_x_y (game, *this, 0, 1);
        else if (!moved && ghost.get_y() > game.get_player()->get_y())
            moved = floor->move_to_x_y (game, *this, 0, -1);
    }

如果失败或玩家距离太远,请尝试随机移动。如果随机方向失败,则按顺序尝试下一个方向。这意味着我们将最多尝试四个方向,没有无限循环的机会。这在三路交叉口有轻微的偏差,但这可能并不明显。它还有一个副作用,如果幽灵真的不能移动,游戏就不会卡住。

    //if not moved closer, move randomly
    if (!moved) {
        int r = rand() % 4; //pick random direction
        switch(r) {
        case 0: 
            if(floor->move_to_x_y (game, *this, 1, 0))
                break; //if it failed, try the next one
        case 1: 
            if(floor->move_to_x_y (game, *this, -1, 0))
                break; //if it failed, try the next one
        case 2: 
            if(floor->move_to_x_y (game, *this, 0, 1))
                break; //if it failed, try the next one
        case 3: 
            if(floor->move_to_x_y (game, *this, 0, -1))
                break; //if it failed, try the next one
        default: 
            //if it was case 3, need to try all other directions still
            if(floor->move_to_x_y (game, *this, 1, 0))
                break; //if it failed, try the next one
            if(floor->move_to_x_y (game, *this, -1, 0))
                break; //if it failed, try the next one
            floor->move_to_x_y (game, *this, 0, 1);
            //at this point, all directions have been tried. We're done.
        }//switch             
    } //if
}

评论指出 nearby 函数中存在错误,它将同一 x 轴上的任何内容视为 "close"。

我可能会这样做:

if (game.nearby(*this))
{
    int x = player_position_x - ghost_position_x;
    int y = player_position_y - ghost_position_y;

    if (abs(x) > abs(y))
    {
        assert(x != 0);
        x = x / abs(x);
        y = 0;
    }
    else
    {
        assert(y != 0);
        x = 0;
        y = y / abs(y);
    }

    floor->move_to_x_y (game, *this, x, y);
    moved = true;
}

解决方案:

对于每次更新的每个幽灵:

  1. 尝试获取玩家位置。
  2. 如果无法获取玩家位置(被墙挡住),则在本次更新中不对这个幽灵做任何事情(return/continue
  3. 测量到玩家的距离。
  4. 如果距离大于最大值"awareness range",在本次更新中不对这个幽灵做任何事情(return/continue)
  5. 朝玩家的方向移动。

此外,请勿在您的代码中使用 "magic numbers" (case 0:)。使用枚举或常量。

因此,去掉 "nearby" 并将其替换为 returns 玩家位置的函数。