Kovalamaca oyunu oyuncu için düz çizgi düşman hareketi


10

Düşmanların bir harita üzerinde rastgele ortaya çıktığı ve her karede rastgele bir hızla oyuncuya doğru hareket ettiği bir oyun yaratıyorum. Haritanın hiçbir engeli yoktur, bu nedenle düşmanlar her zaman düz bir çizgide hareket etmelidir. Hareket fonksiyonunu birkaç kez yazdım, ancak düşmanların her zaman 0, 45, 90, 135, 180, 225, 270, 315 açılarına çarptığı fark etmeksizin ama asla düz bir çizgi yok. Kodun bir örneği:

    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;

Bu benim oyun programlamaya yönelik ilk denemem. Bresenham Hattı gibi algoritma kullanması gerektiğini tahmin ediyorum ( http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm ) ama uygulama girişimlerimde aynı sorun var. Düşmanları düz bir çizgide nasıl hareket ettirebilirim?

Yanıtlar:


17

Bresenham'ın çizgi algoritması, kayan nokta işlemleri kullanılmadan hızlı çizim çizgileri için geliştirilmiştir (tamsayı işlemleri daha hızlıdır). Tarihsel olarak çok ilginç ama bir oyun için çok iyi bir çözüm değil (özellikle hızı belirleyemediğiniz için).

2B hareket yaparken daima vektörleri kullanın. Bu sizin için her şeyi yapacaktır. Bazen cebir harika.

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

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

Kesinlikle hedef diliniz için bazı vector2D sınıfı olacaktır.


Mükemmel çalıştı. Normalleştirmem gereken işlevdi. Teşekkürler.
user4761

9

Her kareyi mi hesaplıyorsunuz? Kodunuz x_speed veya y_speed'i rastgele bir sayıya, diğeri de sıfıra (veya varsayılan) ayarlar. Diyelim ki düşman 0, 0 ve oyuncu 20, 10. Her kareyi x veya y olarak ayarlayın, böylece 10, 10'a kadar 45 derecelik bir açıda hareket eder.

Notabene'in vektör açıklaması doğru ama işte böyle çalışıyor. Vec2d bir x ve y bileşenine sahip olacaktır. Yukarıdaki örnekte, playerPos - enemyPos size (20, 10) 'un bir vektörünü verecektir. normalize () vektörü uzunluk 1 olacak şekilde değiştirir. Şu anda uzunluk sqrt (20 * 20 + 10 * 10) şeklindedir. Bu yaklaşık 22.36068. normalize etmek hem X hem de Y'yi bu sayıya böler, düşman için oyuncu uzunluğu 1 olan oyuncuya işaret eden bir vektör olan yön için yaklaşık (0.89443, 0.44721) verir. Bunu rastgele hızınızla çarpmak istediğinizi yapar.

Ancak her karede yeni bir rastgele hız hesaplamam. Muhtemelen rastgele hızı bir kez ayarlamak veya her bir kareye yaklaştığınız bir başlangıç ​​hızına ve bir hedef hıza sahip olmak istersiniz. Düşmanınızın başlangıçta 100 mil / saat, daha sonra bir kare için 50 mil ve sonraki kare için 200 mil / saat gitmesi mantıklı değil.

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;

Güzel açıklamalar ve eklemeler Jason, teşekkürler. Senin hızlanma fonksiyonunu seviyorum
Notabene

random () bu kapsamda bir yazım hatasıydı. Notabenin yazdıkları ile ilgili açıklamanız ve kodunuz, oyunu çalıştırmama yardımcı oluyor. Teşekkürler.
user4761
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.