簡體   English   中英

2D游戲中對象的C#結構

[英]C# Structure for objects in a 2D game

首先,讓我為提出一個看似模糊(或形式化不佳)的問題道歉,但我缺乏提出任何更具體問題的經驗。

我正在構建一個引擎,用於使用C#玩2D冒險游戲(單擊對象和某物時單擊),並且我正在考慮采用最佳結構。 可以想象,與對象交互時會發生不同的事情:如果是一扇門,您希望進入另一個房間,如果是一個人,您希望開始與他們交談,等等。我的想法是實現這種行為與代表,像這樣:

public abstract class GameObject {
    public delegate void onAction();
    public onAction Click;
}

public class Door : GameObject {
    public Door() {
        Click = new onAction(ChangeRoom);
    }
    private void ChangeRoom() {
        //code to change room here
    }
}

public class Person : GameObject {
    public Person() {
        Click = new onAction(StartTalking);
    }
    private void StartTalking() {
        //code to display dialogue here
    }
}

我發現此解決方案非常優雅,因為如果我想創建一個特殊的對象,但其行為未包含在其類中,則可以執行以下操作:

specialObject.Click += new onAction(SpecialMethod);

但這也是事情變得復雜的地方。 我希望我的引擎能夠簡單地通過加載不同的數據來玩不同的游戲,而無需更改引擎本身,因此硬編碼SpecialMethod在引擎內部某處不是一種選擇,它必須是數據的一部分。 對於普通對象,都可以使用(反)序列化來完成,但是據我所讀,這對於委托人來說是有問題的。 您能建議一種方法嗎?

PS:由於我仍處於概念層次,並且上面的代碼尚未實現,因此您可以自由地提出最能找到的最佳解決方案,甚至可以完全避免委托的方案。

您需要的是腳本編制

本質上,腳本是外部資源(即外部文件),其中包含描述操作的源代碼。

C#為此有不同的選擇。

您可以從.NET語言發出程序集。 或者,您可以集成另一種語言(例如python)並在運行時在腳本中執行。 本質上,腳本是在正確的時間加載,解釋或編譯並執行的。 如果腳本能夠修改應用程序狀態(數據結構),則可以使用外部數據定義對象行為(數據驅動的開發)。

關於此問題的文獻很多,但我建議您使用GPU Programming Gems 6 (第4節)。 但是,集成出色的腳本引擎所需的工作量很大。 這樣,我試圖找出一個基於XML文件的簡單邏輯( 是我的問題,加入另一個問題來定義XML內容); 可悲的是,我發現這幾乎取決於您所需的靈活性。

您無需將SpecialMethod函數硬編碼到引擎中,可以在使用引擎的其他游戲中使用它:

var medievalDoor = new Door();
medievalDoor.Click += OpenDoorNormally;

但是在另一個游戲中:

var starTrekDoor = new Door();
starTrekDoor.Click += SlideDoorUpward;

只要公開Click事件,就無需將任何內容硬編碼到引擎中。 它可以放入您的游戲中,該游戲可能會將您的引擎作為DLL參考。

首先,當您缺乏經驗時,編寫引擎可能會比您想的要難。 我建議您編寫第一部沒有引擎和硬編碼的游戲,然后從經驗中學習並編寫引擎...我知道那不是您想要的:D

如果尚未檢查,請訪問http://www.adventuregamestudio.co.uk/ ,與編輯器一起玩,並思考下面的對象模型。 我會幫你的。

由於您希望游戲是數據驅動的,因此必須能夠動態加載和執行代碼。 “它不必是腳本語言。” 建議添加腳本語言並在學習如何構建引擎的同時進行學習是違背我的本性的。 .NET Framework具有出色的反射系統,可讓您加載C#代碼並在運行時進行編譯。 我必須指出,這是使用C#編寫的腳本,但是缺少適當的腳本語言定義。

由於您沒有太多的經驗,我的建議是使用XML文件來定義您的房間,並使用基本的節點(命令)序列來定義單擊某些內容時應發生的情況。 您應該在“引擎”中實現所有命令,但是您將能夠輕松創建新的游戲室,從而實現類似的游戲。 XML也將是非常可擴展的方法,因為它具有分層結構,它使您可以添加條件,循環等,從而擴展引擎的“腳本”功能。

如果執行某些特殊行為的“決定”留給游戲對象本身,我看不到問題。 我想,如果您希望引擎做出決定,那么您將擁有不兼容的設計規范,因為您將有效地使引擎做出游戲定義的決定,而這正是您不想要的。

在游戲對象中創建ISpecialBehaviorProvider字段,並在必要時將其設置為適當的值(通過構造函數,公共屬性,您擁有什么)。

每當用戶單擊時,您的引擎將始終執行GameObject.Click 但是,如果specialBehaviorProvider為null,使GameObject.Click執行“類”的代碼,否則調用ISpecialBehaviorProvider.SpecialMethod

這樣,引擎就不會決定要調用哪種方法。

我首先要注意的是, 由於這些是類 ,因此多態在這里非常理想-例如,使用虛擬Click方法。

對於序列化程序,委托確實確實很棘手,具體取決於序列化方法。 BinaryFormatter 可以做到這一點,但是作為一般規則,我傾向於不惜一切代價避免使用該序列化程序。

如果可能的話,我建議您只將您的定制子類化為標准實現,並使用多態性。 如果必須通過數據定義它,則實際上將在實現腳本引擎。 .NET中提供了許多這樣的工具-IronPython可能會有用,盡管對於游戲lua非常普遍(您應該能夠輕松使用Lua.NET)。 然后,您只需將一個可選腳本與該操作關聯,然后調用該腳本(在數據中定義)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM