Chuyển động của kẻ thù theo đường thẳng đến người chơi trong trò chơi rượt đuổi


10

Tôi đang tạo một trò chơi trong đó kẻ thù sinh ra ngẫu nhiên trên bản đồ, sau đó di chuyển về phía người chơi mọi khung hình với tốc độ ngẫu nhiên. Bản đồ không có chướng ngại vật nên kẻ thù phải luôn di chuyển theo đường thẳng. Tôi đã viết chức năng di chuyển một vài lần nhưng không có vấn đề gì khi kẻ thù luôn đánh 0, 45, 90, 135, 180, 225, 270, 315 góc nhưng không bao giờ là một đường thẳng. Đây là một ví dụ về mã:

    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;

Đây là nỗ lực đầu tiên của tôi tại lập trình trò chơi. Tôi đoán nó nên sử dụng thuật toán như Dòng của Bresenham ( http://en.wikipedia.org/wiki/Bresenham%27s_line_alacticm ) nhưng những nỗ lực của tôi để thực hiện có cùng một vấn đề. Làm thế nào để tôi làm cho kẻ thù di chuyển trên một đường thẳng?

Câu trả lời:


17

Thuật toán dòng của Bresenham được phát triển cho các đường vẽ nhanh mà không sử dụng các phép toán dấu phẩy động (các phép toán số nguyên nhanh hơn). Đây là một giải pháp rất thú vị nhưng không phải là giải pháp tốt cho trò chơi (đặc biệt vì bạn không thể chỉ định tốc độ).

Khi thực hiện chuyển động 2D luôn sử dụng vectơ. Điều này sẽ làm tất cả các công cụ cho bạn. Đôi khi đại số chỉ là tuyệt vời.

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

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

Chắc chắn sẽ có một số lớp vector2D cho ngôn ngữ đích của bạn.


Điều đó đã làm việc hoàn hảo. Bình thường hóa là chức năng tôi cần. Cảm ơn.
dùng4761

9

Bạn đang tính toán mọi khung hình? Mã của bạn đặt x_speed hoặc y_speed thành một số ngẫu nhiên và số khác thành 0 (hoặc mặc định). Giả sử kẻ thù ở 0, 0 và người chơi ở 20, 10. Điều này có vẻ như nó sẽ đặt x_speed thành một số ngẫu nhiên mỗi khung và di chuyển kẻ thù sang phải cho đến khi anh ta ở 10, 0. Sau đó, kẻ địch sẽ di chuyển hoặc x hoặc y mỗi khung hình để có vẻ như anh ta di chuyển trong một góc 45 độ lên đến 10, 10.

Giải thích véc tơ của Notabene là đúng nhưng đây là cách nó hoạt động. Vec2d sẽ có thành phần x và y. Trong ví dụ trên, playerPos - địchPos sẽ cung cấp cho bạn một vectơ (20, 10). normalize () thay đổi vectơ sao cho độ dài là 1. Hiện tại độ dài là sqrt (20 * 20 + 10 * 10). Đó là khoảng 22.36068. bình thường hóa chia cả X và Y cho số này, cung cấp cho bạn khoảng (0,89443, 0,44721) cho hướng, đó là một vectơ chỉ từ kẻ thù đến người chơi với độ dài 1. Nhân số này với tốc độ ngẫu nhiên của bạn làm những gì bạn muốn.

Tuy nhiên tôi sẽ không tính tốc độ ngẫu nhiên mới mỗi khung. Bạn có thể chỉ muốn đặt tốc độ ngẫu nhiên một lần hoặc có tốc độ ban đầu và tốc độ mục tiêu mà bạn tiến gần hơn đến từng khung hình. Không có nghĩa gì khi kẻ thù của bạn đi 100 mph ban đầu, sau đó 50 mph cho một khung hình và 200 mph cho khung hình tiếp theo.

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;

Giải thích tốt đẹp và bổ sung Jason, cảm ơn. Tôi thích chức năng tăng tốc của bạn
Notabene

Random () trong phạm vi đó là một lỗi đánh máy. Giải thích và mã của bạn với những gì notabene đã viết giúp tôi làm cho trò chơi hoạt động. Cảm ơn.
dùng4761
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.