Bagaimana cara membuat serangan orang baik hanya mengenai orang jahat dan sebaliknya?

11

Game saya memiliki banyak tipe orang baik dan berbagai tipe orang jahat. Mereka semua akan menembakkan proyektil satu sama lain, tetapi saya tidak ingin ada kerusakan agunan yang tidak disengaja terjadi untuk kedua penyelarasan. Jadi orang jahat seharusnya tidak dapat memukul / merusak orang jahat lainnya dan orang baik seharusnya tidak dapat memukul / merusak orang baik lainnya.

Cara saya berpikir untuk menyelesaikan ini adalah dengan membuatnya sehingga Unitinstance (ini adalah javascript, btw), memiliki alignmentproperti yang dapat berupa goodatau bad. Dan saya hanya akan membiarkan tabrakan terjadi jika

class Attack

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

Ini adalah pseudo-code, tentu saja.

Tapi saya mengajukan pertanyaan ini karena saya merasa mungkin ada cara yang jauh lebih elegan untuk mendesain ini selain menambahkan properti lain ke Unitkelas saya .

Daniel Kaplan
sumber
5
Penyaringan adalah pendekatan khas di sini. Intinya itulah yang sudah Anda jelaskan. Ada juga lapisan. Dua lapisan, lapisan buruk dan lapisan baik. Proyektil orang jahat ditembakkan ke lapisan yang bagus dan sebaliknya.
MichaelHouse
@ Byte56 Bisakah Anda menguraikan konsep "lapisan" ini? Atau setidaknya tautan ke sesuatu tentang itu? Saya belum pernah mendengarnya sebelumnya.
Daniel Kaplan
Pada dasarnya mereka berbeda "dunia". Semua objek dalam satu layer berinteraksi satu sama lain, tetapi tidak berinteraksi dengan layer lain. Ini dapat dilakukan dengan tag (seperti pemfilteran), atau dengan set data yang sangat berbeda untuk setiap lapisan.
MichaelHouse
3
Singkatnya, itu pengelompokan. Kelompokkan peluru yang bagus dan hanya periksa tabrakan terhadap orang jahat. Flixel memiliki konsep seperti ini.
ashes999
3
Satu catatan desain yang lucu: apakah Anda ingin tembakan 'ramah-tembakan' mengenai tetapi tidak merusak, atau Anda ingin mereka benar-benar mengabaikan sekutu, mungkin melewati mereka untuk menyerang musuh sebagai gantinya?
Steven Stadnicki

Jawaban:

6

Penyaringan Tabrakan

Situasi yang lebih kuat yang berkembang menjadi banyak lapisan adalah menggunakan pemfilteran, yang tidak sama dengan pengelompokan.

Ini bekerja paling baik dengan memberikan setiap objek 2 bitmask .

Category
Mask

Dan hanya memicu tabrakan jika di bawah ini benar.

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

Yang termudah adalah default Mask ke 0xFFFF yang menghasilkan itu bertabrakan dengan segalanya. Dan default Kategori ke 0x0001. benda bertabrakan dengan kategori topeng lainnya akan ada tabrakan.

Cara lain untuk memikirkannya adalah setiap objek memiliki tipe dan daftar semua tipe yang dapat bertabrakan dengannya. Hanya ketika dua benda saling bertabrakan dengan jenis satu sama lain ada tabrakan. Anda bisa memiliki perilaku yang sama memiliki daftar enum bukan topeng tetapi topeng dengan urutan besarnya lebih cepat.

Skenario yang Anda gambarkan

Saya suka memanfaatkan enum dalam situasi ini.

Jadi katakan kita punya.

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

Tembakan peluru oleh orang baik

 Category = Bullet
 Mask = BadGuy | GlassWall

Orang baik

 Category = GoodGuy
 Mask = All

Orang jahat

 Category = BadGuy
 Mask = All

Yang menghasilkan di bawah ini ketika peluru yang ditembakkan oleh pria baik memukul pria baik lain.

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

Tapi itu akan menimpa orang jahat.

(All & BadGuy) != 0 && <- Passes
(BadGuy & (BadGuy | GlassWall)) != 0; <-- Passes
Klasik
sumber
Maukah Anda menjelaskan ini secara konseptual alih-alih menjelaskannya pada detail aritmatika bit level rendah?
Daniel Kaplan
@tieTYT yakin periksa lagi dalam 5 menit
ClassicThunder
2

Saya memiliki masalah yang sama pada proyek saya saat ini (di Jawa). Setelah beberapa percobaan diselesaikan dengan membuat empat daftar. Solusi ini dibuat di Jawa dan untuk Game 2D tetapi juga harus berfungsi, dengan cara yang sama, dalam JavaScript

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
       {...}
}

kode semu

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

pseudo-code, sama untuk Bullets kelas

Ini mungkin bukan solusi terbaik atau tercepat tetapi ini akan membantu Anda saat ini. Maaf saya tidak bisa memberi Anda solusi dalam JavaScript tetapi saya harap saya bisa membantu Anda

Ngomong-ngomong bahasa Inggris saya bukan yang terbaik tetapi saya harap Anda bisa mengikuti penjelasan saya

Jonniy
sumber