การเคลื่อนไหวของศัตรูเป็นเส้นตรงต่อผู้เล่นในเกมการไล่ล่า


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ของ Bresenham ) แต่ความพยายามของฉันที่จะใช้งานมีปัญหาเดียวกัน ฉันจะทำให้ศัตรูเคลื่อนที่เป็นเส้นตรงได้อย่างไร

คำตอบ:


17

อัลกอริธึมไลน์ของ Bresenham ได้รับการพัฒนาสำหรับการวาดเส้นที่รวดเร็วโดยไม่ต้องใช้การดำเนินการจุดลอยตัว (การดำเนินการจำนวนเต็มจะเร็วกว่า) มันเป็นเรื่องที่น่าสนใจมากในประวัติศาสตร์ แต่ไม่ได้เป็นทางออกที่ดีสำหรับเกม (โดยเฉพาะเพราะคุณไม่สามารถระบุความเร็วได้)

เมื่อทำการเคลื่อนไหวแบบ 2 มิติให้ใช้เวกเตอร์เสมอ สิ่งนี้จะทำทุกอย่างให้คุณ บางครั้งพีชคณิตก็วิเศษจริงๆ

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 และผู้เล่นอยู่ที่ 20, 10 ดูเหมือนว่าจะตั้งค่า x_speed เป็นจำนวนสุ่มในแต่ละเฟรมและย้ายศัตรูไปทางขวาจนกว่าเขาจะอยู่ที่ 10, 0 จากนั้นศัตรูจะเคลื่อนที่ ไม่ว่าจะเป็น x หรือ y ในแต่ละเฟรมดังนั้นดูเหมือนว่าเขาจะเคลื่อนไหวในมุม 45 องศาสูงถึง 10, 10

คำอธิบายเวกเตอร์ของ Notabene นั้นถูกต้อง แต่นี่เป็นวิธีการทำงาน Vec2d จะมีองค์ประกอบ x และ y ในตัวอย่างด้านบน playerPos - combatPos จะให้เวกเตอร์ของ (20, 10) normalize () เปลี่ยนเวคเตอร์เพื่อให้ความยาวคือ 1 ในปัจจุบันความยาวคือ sqrt (20 * 20 + 10 * 10) นั่นคือประมาณ 22.36068 normalize หารทั้ง X และ Y ด้วยหมายเลขนี้ทำให้คุณประมาณ (0.89443, 0.44721) สำหรับทิศทางซึ่งเป็นเวกเตอร์ที่ชี้จากศัตรูไปยังผู้เล่นด้วยความยาว 1 คูณกับสิ่งนี้โดยการสุ่มของคุณทำสิ่งที่คุณต้องการ

อย่างไรก็ตามฉันจะไม่คำนวณความเร็วแบบสุ่มใหม่ในแต่ละเฟรม คุณอาจต้องการตั้งค่าความเร็วแบบสุ่มหนึ่งครั้งหรือมีความเร็วเริ่มต้นและความเร็วเป้าหมายที่คุณเข้าใกล้แต่ละเฟรมมากขึ้น ในตอนแรกมันไม่สมเหตุสมผลเลยที่ศัตรูของคุณจะไป 100 ไมล์ต่อชั่วโมงจากนั้น 50 ไมล์ต่อชั่วโมงสำหรับหนึ่งเฟรมและ 200 ไมล์ต่อชั่วโมงสำหรับครั้งต่อไป

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;

คำอธิบายและส่วนเพิ่มเติมของเจสันขอบคุณ ฉันชอบฟังก์ชั่นเร่งความเร็วของคุณ
Notabene

Random () ในขอบเขตนั้นเป็นตัวพิมพ์ผิด คำอธิบายและรหัสของคุณพร้อมกับสิ่งที่ notabene เขียนช่วยฉันทำให้เกมทำงานได้ ขอบคุณ
user4761
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.