ฉันจะทำให้การโจมตีของผู้ชายที่ดีได้เพียงแค่โจมตีคนเลวและในทางกลับกันได้อย่างไร


11

เกมของฉันมีคนดีหลายประเภทและผู้ชายเลวหลายประเภท พวกเขาทั้งหมดจะทำการยิงขีปนาวุธใส่กัน แต่ฉันไม่ต้องการให้เกิดความเสียหายจากหลักประกันใด ๆ ที่เกิดขึ้นสำหรับการจัดเรียงอย่างใดอย่างหนึ่ง ดังนั้นคนเลวจึงไม่สามารถตี / ทำลายคนเลวคนอื่นและคนดีไม่ควรที่จะตี / ทำความเสียหายคนดีคนอื่น

วิธีที่ฉันคิดว่าการแก้ปัญหานี้คือการทำให้มันเพื่อให้Unitอินสแตนซ์ (นี่คือ javascript, BTW) มีalignmentคุณสมบัติที่สามารถเป็นได้ทั้งหรือgood badและฉันจะปล่อยให้การปะทะเกิดขึ้นถ้า

class Attack

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

นี่คือรหัสหลอกแน่นอน

แต่ฉันถามคำถามนี้เพราะฉันเข้าใจว่าอาจมีวิธีที่สง่างามกว่านี้ในการออกแบบนอกเหนือจากการเพิ่มคุณสมบัติอื่นให้กับUnitชั้นเรียน ของฉัน


5
การกรองเป็นวิธีการทั่วไปที่นี่ เป็นหลักนั่นคือสิ่งที่คุณได้อธิบาย นอกจากนี้ยังมีเลเยอร์ สองชั้นชั้นที่ไม่ดีและชั้นที่ดี ขีปนาวุธคนเลวถูกยิงเข้าสู่ชั้นที่ดีและในทางกลับกัน
MichaelHouse

@ Byte56 คุณช่วยอธิบายแนวคิด "เลเยอร์" นี้ได้ไหม? หรืออย่างน้อยลิงค์ไปยังบางสิ่งเกี่ยวกับมัน ฉันไม่เคยได้ยินเรื่องนี้มาก่อน
Daniel Kaplan

โดยพื้นฐานแล้วพวกมันต่างกัน "โลก" วัตถุทั้งหมดในเลเยอร์โต้ตอบซึ่งกันและกัน แต่อย่าโต้ตอบกับเลเยอร์อื่น ๆ สิ่งนี้สามารถทำได้ด้วยแท็ก (เช่นการกรอง) หรือโดยชุดข้อมูลที่แตกต่างกันโดยสิ้นเชิงสำหรับแต่ละชั้น
MichaelHouse

3
คำหนึ่งมันคือการจัดกลุ่ม จัดกลุ่มสัญลักษณ์แสดงหัวข้อย่อยที่ดีและตรวจสอบเฉพาะการปะทะกับคนร้าย Flixel มีแนวคิดเช่นนี้
ashes999

3
หนึ่งทราบการออกแบบ nitpicky: คุณต้องการ 'มิตรไฟ' นัดตีแต่ไม่มีความเสียหายหรือไม่หรือคุณต้องการให้พวกเขาสมบูรณ์ไม่สนใจพันธมิตรอาจจะผ่านพวกเขาจะตีศัตรูแทน?
Steven Stadnicki

คำตอบ:


6

การกรองการชนกัน

สถานการณ์ที่มีเสถียรภาพมากขึ้นที่ขยายเป็นหลายเลเยอร์คือการใช้การกรองซึ่งไม่เหมือนกับการจัดกลุ่ม

นี้ทำงานได้ดีโดยให้วัตถุทุก 2 bitmasks

Category
Mask

และก่อให้เกิดการชนกันหากด้านล่างเป็นจริงเท่านั้น

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

มันง่ายที่สุดในการเริ่มต้น Mask เป็น 0xFFFF ซึ่งส่งผลให้มันชนกับทุกสิ่ง และเริ่มต้นหมวดหมู่เป็น 0x0001 วัตถุที่ขัดแย้งกับหมวดหมู่ในรูปแบบอื่น ๆ จะมีการชนกัน

วิธีคิดอีกอย่างคือวัตถุแต่ละชนิดมีชนิดและรายการประเภททั้งหมดที่สามารถชนกันได้ เมื่อทั้งสองวัตถุชนกันกับชนิดของกันและกันจะมีการชนกัน คุณอาจมีพฤติกรรมเหมือนกันที่มีรายการ enums แทนหน้ากาก แต่เป็นหน้ากากที่มีขนาดเร็วขึ้น

สถานการณ์ที่คุณอธิบาย

ฉันชอบที่จะใช้ประโยชน์จาก enums ในสถานการณ์นี้

สมมติว่าเรามี

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

กระสุนถูกยิงโดยคนดี

 Category = Bullet
 Mask = BadGuy | GlassWall

คนดี

 Category = GoodGuy
 Mask = All

คนเลว

 Category = BadGuy
 Mask = All

ซึ่งส่งผลให้ด้านล่างเมื่อกระสุนถูกยิงโดยคนดีตีคนดีอีกคน

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

แต่มันจะตีคนเลว

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

คุณจะอธิบายความคิดนี้แทนการอธิบายในระดับต่ำของเลขคณิตบิตหรือไม่?
Daniel Kaplan

@ แน่ใจว่าตรวจสอบอีกครั้งใน 5 นาที
ClassicThunder

2

ฉันมีปัญหาเดียวกันกับโครงการปัจจุบันของฉัน (ใน Java) หลังจากความพยายามสองสามครั้งถูกแก้ไขโดยสร้างสี่รายการ โซลูชันนี้สร้างขึ้นใน Java และสำหรับเกม 2D แต่ก็ควรใช้งานได้เช่นเดียวกันใน 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
       {...}
}

หลอกรหัส

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

รหัสหลอกเดียวกันสำหรับชั้นกระสุน

นี่อาจไม่ใช่ทางออกที่ดีที่สุดหรือเร็วที่สุด แต่จะช่วยคุณได้ในทันที ฉันขอโทษที่ฉันไม่สามารถให้ทางออกคุณใน JavaScript ได้ แต่ฉันหวังว่าฉันจะช่วยคุณได้

โดยวิธีภาษาอังกฤษของฉันไม่ดีที่สุด แต่ฉันหวังว่าคุณสามารถปฏิบัติตามคำอธิบายของฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.