Làm thế nào để tôi làm cho kẻ tốt tấn công chỉ đánh kẻ xấu và ngược lại?


11

Trò chơi của tôi có nhiều loại người tốt khác nhau và nhiều loại người xấu khác nhau. Tất cả chúng sẽ bắn các viên đạn vào nhau nhưng tôi không muốn bất kỳ thiệt hại tài sản thế chấp ngẫu nhiên nào xảy ra cho một trong hai hướng. Vì vậy, kẻ xấu không thể đánh / gây sát thương cho kẻ xấu khác và kẻ tốt không nên đánh / gây sát thương cho kẻ tốt khác.

Cách tôi nghĩ để giải quyết vấn đề này là làm cho nó trở thành Unitví dụ (đây là javascript, btw), có một thuộc alignmenttính có thể là goodhoặc bad. Và tôi sẽ chỉ để va chạm xảy ra nếu

class Attack

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

Đây là mã giả, tất nhiên.

Nhưng tôi đang hỏi câu hỏi này bởi vì tôi có cảm giác rằng có thể có một cách thanh lịch hơn nhiều để thiết kế nó ngoài việc thêm một tài sản khác vào Unitlớp của tôi .


5
Lọc là cách tiếp cận điển hình ở đây. Thực chất đó là những gì bạn đã mô tả. Ngoài ra còn có các lớp. Hai lớp, lớp xấu và lớp tốt. Tên lửa kẻ xấu được bắn vào lớp tốt và ngược lại.
MichaelHouse

@ Byte56 Bạn có thể giải thích khái niệm "lớp" này không? Hoặc ít nhất là liên kết đến một cái gì đó về nó? Tôi chưa bao giờ nghe nói về điều đó trước đây.
Daniel Kaplan

Về cơ bản chúng là những "thế giới" khác nhau. Tất cả các đối tượng trong một lớp tương tác với nhau, nhưng không tương tác với bất kỳ lớp nào khác. Điều này có thể được thực hiện với các thẻ (như lọc) hoặc bằng các bộ dữ liệu hoàn toàn khác nhau cho mỗi lớp.
MichaelHouse

3
Nói một cách dễ hiểu, đó là nhóm. Nhóm đạn tốt và chỉ kiểm tra va chạm với kẻ xấu. Flixel có một khái niệm như thế này.
tro999

3
Một thiết kế lưu ý nitpicky: bạn có muốn 'thân thiện với bắn đạn thật' bức ảnh để đánh nhưng làm không có thiệt hại, hoặc làm bạn muốn họ hoàn toàn bỏ qua các đồng minh, có thể đi qua chúng để tấn công kẻ thù thay vì?
Steven Stadnicki

Câu trả lời:


6

Lọc va chạm

Một tình huống mạnh mẽ hơn quy mô thành nhiều lớp là sử dụng bộ lọc, điều này không giống với nhóm.

Điều này hoạt động tốt nhất bằng cách cung cấp cho mọi đối tượng 2 bitmasks .

Category
Mask

Và chỉ kích hoạt một vụ va chạm nếu điều dưới đây là đúng.

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

Dễ dàng nhất để mặc định Mặt nạ thành 0xFFFF, kết quả là nó va chạm với mọi thứ. Và mặc định Danh mục thành 0x0001. các đối tượng va chạm với các loại trong mặt nạ khác sẽ có một vụ va chạm.

Một cách khác để nghĩ về nó là mỗi đối tượng có một loại và một danh sách tất cả các loại mà nó có thể va chạm. Chỉ khi hai vật thể va chạm với các loại của nhau thì mới có va chạm. Bạn có thể có hành vi tương tự có một danh sách các enum thay vì mặt nạ nhưng mặt nạ theo thứ tự độ lớn nhanh hơn.

Kịch bản bạn mô tả

Tôi thích tận dụng lợi thế của enums trong tình huống này.

Vì vậy, nói rằng chúng ta có.

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

Đạn bắn bởi một chàng trai tốt

 Category = Bullet
 Mask = BadGuy | GlassWall

Người tốt

 Category = GoodGuy
 Mask = All

Kẻ xấu

 Category = BadGuy
 Mask = All

Kết quả dưới đây khi một viên đạn của một người tốt bắn trúng một người tốt khác.

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

Nhưng nó sẽ đánh kẻ xấu.

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

Bạn có phiền giải thích điều này về mặt khái niệm thay vì giải thích nó ở mức độ chi tiết thấp của số học bit?
Daniel Kaplan

@tieTYT chắc chắn kiểm tra lại sau 5 phút
ClassicThunder

2

Tôi đã có cùng một vấn đề tại dự án hiện tại của tôi (trong Java). Sau một vài lần thử được giải quyết bằng cách tạo bốn danh sách. Giải pháp này được tạo bằng Java và cho Trò chơi 2D nhưng cũng hoạt động theo cách tương tự, trong 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
       {...}
}

mã giả

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

mã giả, tương tự cho các viên đạn lớp

Đây có thể không phải là giải pháp tốt nhất hoặc nhanh nhất nhưng nó sẽ giúp bạn trong lúc này. Tôi xin lỗi vì tôi không thể cung cấp cho bạn một giải pháp bằng JavaScript nhưng tôi hy vọng tôi có thể giúp bạn

Bằng cách này, tiếng Anh của tôi không phải là tốt nhất nhưng tôi hy vọng bạn có thể làm theo lời giải thích của tôi

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.