나는 적들이 맵에서 무작위로 스폰하고 무작위 프레임으로 모든 프레임마다 플레이어를 향해 움직이는 게임을 만들고 있습니다. 지도에는 장애물이 없으므로 적들은 항상 직선으로 움직여야합니다. 나는 운동 기능을 몇 번 썼지 만 적들이 항상 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 ) 과 같은 알고리즘을 사용해야한다고 생각 하지만 구현하려는 시도에는 동일한 문제가 있습니다. 적을 직선으로 움직이게하려면 어떻게해야합니까?
답변
Bresenham의 선 알고리즘은 부동 소수점 연산을 사용하지 않고 빠른 선을 그리기 위해 개발되었습니다 (정수 연산이 더 빠름). 그것은 역사적으로 매우 흥미롭지 만 게임을위한 좋은 해결책은 아닙니다 (특히 속도를 지정할 수 없기 때문에).
2D 이동을 수행 할 때는 항상 벡터를 사용하십시오. 이것은 당신을 위해 모든 것을 할 것입니다. 때때로 대수는 정말 대단합니다.
Vec2d playerPos;
Vec2d direction; // always normalized
float velocity;
update()
{
direction = normalize(playerPos - enemyPos);
playerPos = playerPos + direction * velocity;
}
타겟 언어에 대한 vector2D 클래스가 확실히 있습니다.
답변
모든 프레임을 계산합니까? 코드는 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;