สร้างระบบตามพฤติกรรม / ส่วนประกอบสำหรับเกม


11

พื้นหลัง

ฉันพัฒนาเกมเป็นงานอดิเรกและกำลังมองหาวิธีที่ดีกว่าในการออกแบบพวกเขา ปัจจุบันฉันใช้วิธีมาตรฐาน OOP (ฉันได้ทำการพัฒนาองค์กรเป็นเวลา 8 ปีแล้ว ยกตัวอย่างเช่น "baddie"

public class Baddie:AnimatedSprite //(or StaticSprite if needed, which inherit Sprite)
{
    //sprite base will have things like what texture to use, 
    //what the current position is, the base Update/Draw/GetInput methods, etc..
    //an AnimatedSprite contains helpers to animated the player while 
    //a StaticSprite is just one that will draw whatever texture is there
}

ปัญหา

ให้บอกว่าฉันทำ platformer 2d และต้องการ baddie เพื่อให้สามารถกระโดดได้ โดยปกติสิ่งที่ฉันทำคือการเพิ่มรหัสที่เหมาะสมในวิธีการอัพเดต / GetInput ถ้าฉันต้องการให้ผู้เล่นคลาน, เป็ด, ไต่และอื่น ๆ ... รหัสจะไปที่นั่น

ถ้าฉันไม่ระวังวิธีการเหล่านั้นก็จะยุ่งเหยิงดังนั้นฉันจึงสร้างวิธีการจับคู่แบบนี้

CheckForJumpAction(Input input) และ DoJump()

CheckforDuckAction(Input input) และ DoDuck()

ดังนั้น GetInput จึงดูเหมือนว่า

public void DoInput(Input input)
{
    CheckForJumpAction(input);
    CheckForDuckAction(input);
}

และอัปเดตดูเหมือนว่า

public void Update()
{
    DoJump();
    DoDuck();
}

ถ้าฉันไปและสร้างเกมอื่นที่ผู้เล่นต้องกระโดดและเป็ดฉันมักจะเข้าสู่เกมที่มีฟังก์ชั่นและคัดลอกมัน ยุ่งฉันรู้ ฉันว่าทำไมฉันถึงมองหาสิ่งที่ดีกว่า

วิธีการแก้?

ฉันชอบที่ Blend มีพฤติกรรมที่ฉันสามารถแนบกับองค์ประกอบได้อย่างไร ฉันคิดถึงการใช้แนวคิดเดียวกันนี้ในเกมของฉัน ลองดูตัวอย่างเดียวกัน

ฉันจะสร้างวัตถุฐานพฤติกรรม

public class Behavior
{
    public void Update()
    Public void GetInput()
}

และฉันสามารถสร้างพฤติกรรมโดยใช้สิ่งนั้น JumpBehavior:BehaviorและDuckBehavior:Behavior

ฉันสามารถเพิ่มคอลเลกชันของพฤติกรรมลงใน Sprite base และเพิ่มสิ่งที่ฉันต้องการในแต่ละเอนทิตี

public class Baddie:AnimatedSprite
{
    public Baddie()
    {
        this.behaviors = new Behavior[2];
        this.behaviors[0] = new JumpBehavior();
        //etc...
    }

    public void Update()
    {
        //behaviors.update
    }

    public GetInput()
    {
        //behaviors.getinput
    }
}

ดังนั้นตอนนี้ถ้าฉันต้องการใช้ Jump and Duck ในหลาย ๆ เกมฉันสามารถนำเอาพฤติกรรมไปใช้ ฉันสามารถสร้างห้องสมุดสำหรับคนทั่วไปได้

มันใช้งานได้หรือไม่

สิ่งที่ฉันไม่สามารถหาได้คือวิธีการแบ่งปันสถานะระหว่างพวกเขา การดูที่ Jump and Duck ทั้งคู่ไม่เพียงส่งผลกระทบต่อส่วนปัจจุบันของพื้นผิวที่ถูกวาดเท่านั้น แต่ยังรวมถึงสถานะของผู้เล่นด้วย (การกระโดดจะใช้แรงลดลงตามช่วงเวลาในขณะที่เป็ดกำลังจะหยุดการเคลื่อนไหวเปลี่ยนพื้นผิวและขนาดการชนของ baddie

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

ฉันแน่ใจว่ามีปัญหาเพิ่มเติมที่ฉันกำลังมองหาอยู่ แต่จุดประสงค์ทั้งหมดคือเพื่อให้ฉันสามารถนำพฤติกรรมเหล่านี้กลับมาใช้ใหม่ระหว่างเกมและเอนทิตีในเกมเดียวกันได้อย่างง่ายดาย

ดังนั้นฉันหันไปหาคุณ สนใจที่จะอธิบายว่าสามารถทำได้หรือไม่? คุณมีความคิดที่ดีกว่านี้ไหม? ฉันหูของทุกคน


นี่อาจจะถูกถามที่ดีกว่าที่gamedev.stackexchange.com ?
rcapote

ฉันชอบที่คุณกำลังจะไป แต่ฉันไม่แน่ใจว่าจะจัดการกับปัญหาที่คุณพบได้อย่างไร น่าสนใจมากและมีความหมายมากกว่าการพัฒนาเกม
Edward Strange

@rcapote ไม่ได้เป็นเว็บไซต์นี้สำหรับไวท์บอร์ด / การอภิปราย?

2
@Joe - ไม่ไม่ อย่าพูดถึง "การอภิปราย" ที่นี่ไม่เช่นนั้นคุณจะถูกควบคุมตัวเอง ไซต์นี้มีไว้สำหรับคำถาม -> คำตอบ -> การโต้ตอบประเภทเสร็จสิ้นแล้ว
Edward Strange

ระบบเอนทิตีที่อิงองค์ประกอบเป็นสิ่งที่เริ่มมีแนวโน้มในชุมชนนักพัฒนาเกมเมื่อเร็ว ๆ นี้ดังนั้นฉันคิดว่าคุณอาจได้รับความสนใจมากขึ้นที่นั่น แต่คุณอาจได้รับคำตอบที่ดีที่นี่ นี่คือการสนทนาที่น่าสนใจเกี่ยวกับ gamedev.net เกี่ยวกับปัญหานี้ที่คุณอาจพบว่าน่าสนใจ: gamedev.net/topic/ …
rcapote

คำตอบ:


1

ลองดูที่นี่นำเสนอ ฟังดูใกล้เคียงกับรูปแบบที่คุณต้องการ รูปแบบนี้สนับสนุนพฤติกรรมและคุณสมบัติที่สามารถแนบได้ ฉันไม่คิดว่างานนำเสนอจะกล่าวถึง แต่คุณสามารถสร้างกิจกรรมที่สามารถแนบได้ แนวคิดนี้คล้ายกับคุณสมบัติการพึ่งพาที่ใช้ใน WPF


9

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

ตัวอย่าง (ประดิษฐ์):

// The basic definition of the jump behavior
public interface IJumpBehavior {
    void Jump();
}

ตอนนี้คุณสามารถใช้การข้ามประเภทต่าง ๆ ที่ตัวละครของคุณสามารถใช้ได้โดยไม่จำเป็นต้องทราบรายละเอียดเกี่ยวกับการกระโดดแต่ละครั้ง:

// This is the jump the character may have when first starting
public class NormalJump : IJumpBehavior {

     public void Jump() {
         Console.WriteLine("I am jumping, and being pretty boring about it!");
     }

}

// This is the jump of a character who has consumed a power-up
public class SuperJump : IJumpBehavior {
    public void Jump() { 
         Console.WriteLine("I am all hopped up on star power, now my jumps can do damage!");
     }
}

อักขระใด ๆ ที่คุณต้องการให้มีความสามารถในการข้ามสามารถมีการอ้างอิงถึง IJumpable และสามารถเริ่มใช้งานการใช้งานต่าง ๆ ของคุณได้

public class HeroCharacter {

    // By default this hero can perform normal jump.
    private IJumpBehavior _jumpBehavior = new NormalJump();

    public void Jump() {
        _jumpBehvaior.Jump();
    }

    // If you want to change the hero's IJumpable at runtime
    public void SetJump(IJumpBehavior jumpBehavior) {
      _jumpBehavior = jumpBehavior;
    }

}

จากนั้นโค้ดของคุณจะมีลักษณะดังนี้:

HeroCharacter myHero = new HeroCharacer();

// Outputs: "I am jumping, and being pretty boring about it!"
myHero.Jump()

// After consuming a power-up
myHero.SetJump(new SuperJump());

// Outputs: "I am all hopped up on star power, now my jumps can do damage!"
myHero.Jump();

ตอนนี้คุณสามารถใช้ลักษณะการทำงานเหล่านี้ได้อีกครั้งหรือขยายในภายหลังตามที่คุณต้องการเพิ่มการข้ามประเภทเพิ่มเติมหรือสร้างเกมเพิ่มเติมที่สร้างขึ้นบนแพลตฟอร์มการเลื่อนด้านข้างเดียว


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

1

ดูสถาปัตยกรรม DCIที่น่าสนใจเกี่ยวกับการเขียนโปรแกรม OO ที่อาจช่วยได้

การนำสถาปัตยกรรมสไตล์ DCI มาใช้ใน C # จำเป็นต้องใช้คลาสโดเมนอย่างง่ายและการใช้ออบเจ็กต์บริบท (พฤติกรรม) ด้วยวิธีการส่วนขยายและอินเทอร์เฟซเพื่อให้คลาสโดเมนทำงานร่วมกันภายใต้บทบาทที่แตกต่างกัน อินเทอร์เฟซใช้เพื่อทำเครื่องหมายบทบาทที่จำเป็นสำหรับสถานการณ์ คลาสโดเมนใช้อินเทอร์เฟซ (บทบาท) ที่ใช้กับพฤติกรรมที่ต้องการ การทำงานร่วมกันระหว่างบทบาทจะเกิดขึ้นในวัตถุบริบท (พฤติกรรม)

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

ดูDCI ใน C #สำหรับตัวอย่างรหัสใน C #


0

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

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