체이스 게임에서 플레이어에게 직선으로 적의 움직임


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 's Line ( http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm ) 과 같은 알고리즘을 사용해야한다고 생각 하지만 구현하려는 시도에는 동일한 문제가 있습니다. 적을 직선으로 움직이게하려면 어떻게해야합니까?

답변:


17

Bresenham의 선 알고리즘은 부동 소수점 연산을 사용하지 않고 빠른 선을 그리기 위해 개발되었습니다 (정수 연산이 더 빠름). 그것은 역사적으로 매우 흥미롭지 만 게임을위한 좋은 해결책은 아닙니다 (특히 속도를 지정할 수 없기 때문에).

2D 이동을 수행 할 때는 항상 벡터를 사용하십시오. 이것은 당신을 위해 모든 것을 할 것입니다. 때때로 대수는 정말 대단합니다.

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

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

타겟 언어에 대한 vector2D 클래스가 확실히 있습니다.


완벽하게 작동했습니다. 정규화는 내가 필요한 기능이었습니다. 감사.
user4761

9

모든 프레임을 계산합니까? 코드는 x_speed 또는 y_speed를 임의의 숫자로 설정하고 다른 하나를 0 (또는 기본값)으로 설정합니다. 적이 0, 0에 있고 플레이어가 20, 10에 있다고 가정 해 봅시다. x_speed를 각 프레임의 임의의 숫자로 설정하고 10, 0에 도달 할 때까지 적을 오른쪽으로 움직입니다. x 또는 y는 각 프레임마다 45도 각도에서 최대 10, 10으로 움직이는 것처럼 보입니다.

Notabene의 벡터 설명은 맞지만 작동 방식은 다음과 같습니다. Vec2d에는 x 및 y 구성 요소가 있습니다. 위의 예에서 playerPos-enemyPos는 (20, 10)의 벡터를 제공합니다. normalize ()는 길이가 1이되도록 벡터를 변경합니다. 현재 길이는 sqrt (20 * 20 + 10 * 10)입니다. 약 22.36068입니다. normalize는 X와 Y를이 숫자로 나누고 방향에 대해 약 (0.89443, 0.44721)을 제공합니다. 이는 방향에서 길이가 1 인 적에게 플레이어를 가리키는 벡터입니다.

그러나 각 프레임마다 새로운 임의 속도를 계산하지는 않습니다. 임의 속도를 한 번만 설정하거나 각 프레임에 가까워지는 초기 속도와 목표 속도를 원할 것입니다. 적에게 처음에는 100mph, 그 다음에는 한 프레임에서는 50mph, 다음 프레임에서는 200mph로가는 것은 의미가 없습니다.

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

해당 범위의 random ()은 오타였습니다. notabene이 작성한 내용에 대한 설명과 코드는 게임 작업에 도움이됩니다. 감사.
user4761
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.