如果玩家在附近,将幽灵移向迷宫中的玩家?
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;
}
解决方案:
对于每次更新的每个幽灵:
- 尝试获取玩家位置。
- 如果无法获取玩家位置(被墙挡住),则在本次更新中不对这个幽灵做任何事情(
return
/continue
)
- 测量到玩家的距离。
- 如果距离大于最大值"awareness range",在本次更新中不对这个幽灵做任何事情(
return
/continue
)
- 朝玩家的方向移动。
此外,请勿在您的代码中使用 "magic numbers" (case 0:
)。使用枚举或常量。
因此,去掉 "nearby" 并将其替换为 returns 玩家位置的函数。
我认为这是一件相当容易实现的事情,但我只想让鬼魂一次开始向玩家移动一个 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;
}
解决方案:
对于每次更新的每个幽灵:
- 尝试获取玩家位置。
- 如果无法获取玩家位置(被墙挡住),则在本次更新中不对这个幽灵做任何事情(
return
/continue
) - 测量到玩家的距离。
- 如果距离大于最大值"awareness range",在本次更新中不对这个幽灵做任何事情(
return
/continue
) - 朝玩家的方向移动。
此外,请勿在您的代码中使用 "magic numbers" (case 0:
)。使用枚举或常量。
因此,去掉 "nearby" 并将其替换为 returns 玩家位置的函数。