Cep telefonlarını bir başkasını çevrelemek için ne tür bir direksiyon davranışı veya mantığı kullanabilirim?


10

Oyunumda başka bir oyuncuya bir çeteyi yönlendirmek için yol bulmayı kullanıyorum (onları takip etmek için). Bu, onları oyuncunun üstesinden gelmek için çalışır, ancak hedeflerinden önce biraz durmalarını istiyorum (bu nedenle sondan önceki düğümü seçmek iyi çalışır).

Bununla birlikte, birden fazla çetenin cep telefonu peşinde koşarken bazen "birbirinin üzerine istiflenir". Bundan kaçınmanın en iyi yolu nedir? Çetelere opak ve bloke gibi davranmak istemiyorum (çünkü değiller, onlardan geçebilirsiniz) ama çetelerin bir yapı hissine sahip olmasını istiyorum.

Misal:

Her yılanın bana rehberlik ettiğini ve "Setsuna" yı kuşatması gerektiğini düşünün. Her iki yılanın da bana nasıl yaklaştığını fark ettiniz mi? Bu katı bir gereklilik değildir; hatta biraz ofset olmak iyidir. Ama Setsuna'yı "kuşatmalılar".

resim açıklamasını buraya girin


1
İstifleme sadece varış noktasında mı yoksa taşıma sırasında mı? Ben ikincisini tahmin ediyorum.
SpartanDonut

İkincisi, @SpartanDonut
Vaughan

@KromStern Bir resim ekledim, umarım yardımcı olur.
Vaughan Hilts

Yanıtlar:


15

Temsilcilerinize Coulomb yasası boyunca birbirlerini itmeleri için zayıf bir "elektrostatik yük" verin .

Mafyaların birbirlerini eşdeğer kuvvetle itmeleri gerektiği basitliği varsayarsak some_constant / distance^2, some_constantyapılandırılabilir bir itme kuvveti ve distanceonları ayıran mesafe olan her bir mafya çifti arasında bir kuvvet uygulamak yeterlidir .

İtme kuvvetleri daha sonra mesafenin karesiyle düşer.

Code of Nature'ın burada harika bir örneği var (canlı demo ile). Şöyle görünüyor:

birleşik takip ve ayrı davranışlar

Her öğeyi birbiriyle eşleştirmek, ikinci dereceden bir zaman ( O(n^2)) işlemidir. Eğer varsa gerçekten birçok maddeler, bir ile kuvvet hesaplamalarını optimize etmek isteyebilirler Barnes-Hut yakınlaştırılması log-lineer için aşağı alır ( O(n log n)) ancak bir gerektiriyor quadtree .


Harika bağlantı, Anko. Çok takdir! Ben kesinlikle bu sitenin tamamını bir okuma vermek zorunda kalacağım.
Vaughan Hilts

Starcraft (en azından 1) uçan birimleriyle benzer bir şey yapar. Ancak bunu sadece hareket etmeyi bıraktıklarında yapar, yani hareket halindeyken üst üste toplanırlar (birbirlerini tamamen engel olarak görmezden gelirler), ancak durduklarında hepsi gibi görünen şeylerden yayılmaya başlarlar. onları kapsayan bazı normal alanın (muhtemelen kare / daire) yerel merkezi. Bu, yanıttaki örnek kadar güzel görünmüyor, ancak muhtemelen daha az CPU kaynağı kullanıyor ve muhtemelen kodlamak da daha kolay ...
Shivan Dragon

@ShivanDragon SC2 aynı davranışı sunar, hepsi bir kalabalığın içinde hedefe yaklaşır, daha sonra gerçekçi ve estetik açıdan hoş görünümler için yer açar (böylece parçaları etrafta dolaşmaz).
Kroltan

2
Bir çeşit itici güç iyi bir fikir olabilir, ancak detaylar zor. Bunları uzay temalı bir RTS'de denedim ve fiziği çok yakından takip etmemeyi ve güzel davranmasını modellemeyi tavsiye ederim. Bazı gözlemler: 1) Bu bir fizik simülasyonu olmadığından, kuvveti sadece kısa mesafelere uygularım. 2) Bu, sonlu cisimlerin üst üste binmesini önleyemez 3) Sert potansiyel, parçacıkların yüksek hızlarda kırılması gibi sayısal hatalara kolayca neden olur. 4) Orta yükselişte önemli sayıda parçacık ve basınç olduğunda, işler çirkinleşir.
CodesInChaos

1

Yaklaşımım @ Anko'nunkine benziyor, ancak Oyunlar için Yapay Zeka'dan Millington ve Funge'nin çalışmalarına dayanıyor .

Bir Ayırma davranışı böyle görünecektir, ancak bu hızın, Güncelleme işlevinde aracının hızı ile hesaplanması gerektiğini dikkate almanız gerekir.

public Vector3 GetSeparationVel (float threshold, float decayCoefficient)
{
    threshold = threshold * threshold;
    Vector3 separationVelocity = Vector3.Zero;
    for (int i = 0; i < enemies.Length; i++) {
        if (enemies[i] == this) {
            continue;
        }
        Vector3 direction = this.position - enemies[i].position;
        float distance = direction.LengthSquared();
        float strenght = 0.0f;
        if (distance < (threshold)) {
            strenght = Math.Min(decayCoefficient / distance, this.maxAccel);
            direction.Normalize();
            separationVelocity += strenght * direction;
        }
    }
}
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.