İyi adam saldırılarını nasıl sadece kötü adamlara çarptırabilirim?


11

Oyunumda birçok farklı iyi adam ve birçok farklı kötü adam var. Hepsi birbirlerine mermi fırlatacaklar ama her iki hizalama için de herhangi bir kazara teminat hasarı olmasını istemiyorum. Bu yüzden kötü adamlar diğer kötü adamlara vuramaz / zarar veremez ve iyi adamlar diğer iyi adamlara vuramaz / zarar veremez.

Bunu çözmeyi düşündüğüm şekilde, Unitörneğin (javascript, btw), alignmentya goodda olabilen bir özelliğe sahip olmasını sağlamaktır bad. Ve ben sadece çarpışmanın gerçekleşmesine izin vereceğim.

class Attack

    boolean didAttackCollideWithTarget(target)
        return attack.source.alignment != target.alignment and collisionDetected(attack.source, target)

Elbette bu sahte koddur.

Ama bu soruyu soruyorum çünkü Unitsınıfımı başka bir mülk eklemenin yanı sıra, bunu tasarlamanın çok daha zarif bir yolu olabileceğini anlıyorum .


5
Filtreleme burada tipik bir yaklaşımdır. Aslında bu tarif ettiğiniz şey. Ayrıca katmanlar da var. İki katman, kötü katman ve iyi katman. Kötü adamlar mermileri iyi bir tabakaya ateşlenir ve bunun tersi de geçerlidir.
MichaelHouse

@ Byte56 Bu "katman" konseptini ayrıntılı olarak açıklayabilir misiniz? Ya da en azından bununla ilgili bir şeye bağlantı? Bunu daha önce hiç duymamıştım.
Daniel Kaplan

Aslında bunlar farklı "dünyalar" dır. Katmandaki tüm nesneler birbirleriyle etkileşime girer, ancak diğer katmanlarla etkileşime girmez. Bu, etiketlerle (filtreleme gibi) veya her katman için tamamen farklı veri kümeleriyle yapılabilir.
MichaelHouse

3
Tek kelimeyle, gruplanıyor. İyi mermileri gruplandırın ve sadece kötü adamlara karşı çarpışma olup olmadığını kontrol edin. Flixel'in böyle bir konsepti var.
ashes999

3
Bir nitpicky tasarım notu: 'dost ateşli' atışların vurulmasını istiyor, ancak hasar vermiyor musunuz yoksa müttefiklerini tamamen görmezden gelmelerini mi istiyorsunuz, muhtemelen düşmanları vurmak için onlardan geçiyor musunuz?
Steven Stadnicki

Yanıtlar:


6

Çarpışma Filtreleme

Birçok katmana ölçeklenen daha sağlam bir durum, gruplama ile aynı şey olmayan filtreleme kullanmaktır.

Bu, her nesneye 2 bit maskesi vererek en iyi sonucu verir .

Category
Mask

Ve sadece aşağıdakiler doğruysa bir çarpışmayı tetikler.

(filterA.maskBits & filterB.categoryBits) != 0 &&
(filterA.categoryBits & filterB.maskBits) != 0;

Maskeyi varsayılan olarak 0xFFFF'e ayarlamanın en kolayı, her şeyle çarpışmasına neden olur. Ve Kategori 0x0001 varsayılan. nesneler diğer kategorilerle çarpışırsa maske çarpışma olur.

Bunu düşünmenin başka bir yolu, her nesnenin bir türü ve çarpışabileceği tüm türlerin bir listesi olmasıdır. Sadece iki nesne birbirinin türleriyle çarpıştığında bir çarpışma olur. Bir maske yerine numaralandırma listesine sahip olmakla aynı davranışa sahip olabilirsiniz, ancak maske daha hızlı bir sırada.

Açıkladığınız senaryo

Bu durumda enum'lardan yararlanmayı seviyorum.

Öyleyse söyle.

enum Categories {
    GoodGuy =           0x0001,
    BadGuy =            0x0002,
    Bullet =            0x0004,
    GlassWall =         0x0008,
    Lazer =             0x0010,
    All =               0xFFFF
};

İyi bir adam tarafından ateş kurşun

 Category = Bullet
 Mask = BadGuy | GlassWall

İyi adamlar

 Category = GoodGuy
 Mask = All

Kötü adamlar

 Category = BadGuy
 Mask = All

Hangi iyi bir adam tarafından vurulmuş bir kurşun başka bir iyi adam vurduğunda aşağıdaki sonuçlanır.

(All & GoodGuy) != 0 && <-- Passes
(GoodGuy & (BadGuy | GlassWall)) != 0; <-- This would fail

Ama kötü adamları vuracak.

(All & BadGuy) != 0 && <- Passes
(BadGuy & (BadGuy | GlassWall)) != 0; <-- Passes

Bunu bit aritmetiğinin düşük seviyeli bir detayında açıklamak yerine kavramsal olarak açıklar mısın?
Daniel Kaplan

@tieTYT emin 5 dakika içinde tekrar kontrol
ClassicThunder

2

Mevcut projemde de aynı sorunu yaşadım (Java'da). Bir kaç denemeden sonra dört liste oluşturarak çözülür. Bu çözüm Java ve bir 2D Oyun için oluşturulur, ancak aynı şekilde JavaScript'te de çalışmalıdır.

public static main (String [] args)
{
    private List<Bullets> bullets_GoodGuys = new LinkedList <Bullet>(); //List of all bullets fired by good guys
    private List<Bullets> bullets_BadGuys  = new LinkedList <Bullet>(); //List of all bullets fired by bad guys
    private List<Guys> goodGuys  = new LinkedList <Guys>(); //List of all good guys
    private List<Guys> badGuys  = new LinkedList <Guys>();  //List of all good guys

    init();
    ...
    while(game_is_running)
    {
        ... 
        for(int i=0;i>=goodGuys.length;i++)
        {
            for(int j=0;j>=bullets_BadGuys.length;i++)
            {
                if(goodGuys.get(i).getBounding().interacts(bullets_BadGuys.get(i).getBounding()))
                {// If a good guy was hit by a bullet from a bad guy
                    goodGuys.get(i).getDamage();
                    bullets_BadGuys.remove((bullets_BadGuys.get(i));
         }   }   }
       for(...) //same for the bad guys
       {...}
}

yalancı kod

class Guys
{
   private float xkoordinate;
   private float ykoordinate;
   private BufferedImage look;
   private Rectangle bounding = new Rectangle(xkoordinate,ykoordinate,look.getWith(),look.getHight())
   ...
}

sözde kod, Bullets sınıfı için aynı

Bu en iyi veya en hızlı çözüm olmayabilir, ancak size şu anda yardımcı olacaktır. JavaScript'te size bir çözüm veremediğim için özür dilerim, umarım size yardımcı olabilirim

Bu arada İngilizcem iyi değil ama umarım açıklamamı takip edebilirsin

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.