在追逐游戏中对玩家的敌人直线运动


10

我正在创建一个游戏,敌人会随机在地图上生成,然后每帧以随机速度向玩家移动。该地图没有障碍,因此敌人应始终沿直线移动。我写了几次移动函数,但是无论敌人总是打0、45、90、135、180、225、270、315角,但绝不打直线。这是代码示例:

    base_speed = random();

    diff_x = abs(enemy_y_pos - player_x_pos);
    diff_y = abs(enemy_x_pos - player_y_pos);
     if (diff_x > diff_y) {
      y_speed = base_speed;
     } else if (diff_y > diff_x) {
      x_speed = base_speed;
     }

     if (enemy_x_pos < player_x_pos) {
      velocity.x = x_speed;
     } else if (enemy_x_pos > player_x_pos) {
      velocity.x = -x_speed;
     } else {
      velocity.x = 0;
     }

     if (enemy_y_pos < player_y_pos) {
      velocity.y = y_speed;
     } else if (enemy_y_pos > player_y_pos) {
      velocity.y = -y_speed;
     } else {
            velocity.y = 0;
    }

    enemy_x_pos = enemy_x_pos + velocity.x;
    enemy_y_pos = enemy_y_pos + velocity.y;

这是我第一次尝试游戏编程。我猜应该使用像Bresenham的Line(http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm)这样的算法,但是我尝试实现的问题也相同。如何使敌人直线移动?

Answers:


17

Bresenham的线算法是为不使用浮点运算(较快的整数运算)而快速绘制线而开发的。历史上这是非常有趣的游戏解决方案,但并不是很好的解决方案(特别是因为您无法指定速度)。

进行2D运动时,请始终使用矢量。这将为您完成所有工作。有时代数只是美好的。

Vec2d playerPos;
Vec2d direction; // always normalized
float velocity;

update()
{
   direction = normalize(playerPos - enemyPos);
   playerPos = playerPos + direction * velocity;
}

肯定会为您的目标语言提供一些vector2D类。


那很好。归一化是我需要的功能。谢谢。
user4761 2011年

9

您正在计算每一帧吗?您的代码将x_speed或y_speed设置为随机数,另一个设置为零(或默认值)。假设敌人位于0,0,玩家位于20,10。这看起来像是将x_speed每帧设置为一个随机数,并将敌人向右移动,直到他位于10,0。然后敌人将移动每帧x或y,所以看起来他以45度角移动到10、10。

Notabene的向量解释是正确的,但这是它的工作原理。Vec2d将具有x和y分量。在上面的示例中,playerPos-敌人位置将为您提供(20,10)的向量。normalize()更改向量,使其长度为1。当前长度为sqrt(20 * 20 + 10 * 10)。大约是22.36068。normalize将X和Y都除以该数字,得到的方向大约为(0.89443,0.44721),该方向是从敌人到玩家的长度为1的向量。将其乘以随机速度即可得到所需的结果。

但是,我不会每帧计算一个新的随机速度。您可能只想设置一次随机速度,或者使初始速度和目标速度接近每一帧。您的敌人最初以100 mph的速度行驶,然后以一帧的速度行驶50 mph,然后以200 mph的速度行驶则没有意义。

float targetSpeed = random(); // do this only rarely, or each frame if you don't mind slowing down and speeding up constantly

float acceleration = max(abs(targetSpeed - speed), 0.5) * sgn(targetSpeed - speed); // cap accel/decel at 0.5 per frame
speed = speed + acceleration;

很好的解释和补充Jason,谢谢。我喜欢您的加速功能
Notabene 2011年

该范围内的random()是一个错字。您的说明和notabene编写的代码有助于我使游戏正常运行。谢谢。
user4761 2011年
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.