簡體   English   中英

游戲架構

[英]Game Architecture

我對我正在制作的XNA游戲有疑問,但它也是未來游戲的一般問題。 我正在制作Pong游戲而且我不確切知道要在哪里更新,所以我會更好地解釋我的意思。 我有一個類Game,Paddle和Ball,例如,我想驗證球與屏幕限制或槳之間的碰撞,但我遇到了兩種方法來做到這一點:

更高級別的方法 - 將槳和球屬性公開,並在Game.Update上檢查碰撞?

低級方法 - 我提供我需要的每個信息(屏幕限制和撥片信息)到球類(通過參數,或在公共公共靜態類)和Ball.Update我檢查碰撞?

我想我的問題以更通用的方式是:

對象是否需要知道如何更新和繪制自己,甚至是從某種程度上提供給它們的更高級別的依賴項?

要么

最好在Game.Update或Game.Draw中使用更高級別處理它,還是使用Managers來簡化代碼?

我認為這是一個適用於每個游戲的游戲邏輯模型問題。 我不知道我的問題是否清楚,如果沒有,請隨便問。

回答你的問題的困難部分是你要問兩個:“我現在應該做什么,對於乒乓球”和“我應該在以后做什么,在一些通用游戲上”。


要制作Pong你甚至不需要Ball和Paddle課程,因為他們基本上只是位置。 在你的Game類中堅持這樣的東西:

Vector2 ballPosition, ballVelocity;
float leftPaddlePosition, rightPaddlePosition;

然后只需在游戲的UpdateDraw功能中以適合您的順序更新並繪制它們。 簡單!


但是,假設您想要創建多個球,並且球具有許多屬性(位置,速度,旋轉,顏色等):您可能想要制作可以實例化的Ball類或結構(同樣適用於槳)。 您甚至可以將某些函數移動到它們自包含的類中( Draw函數就是一個很好的例子)。

但保持設計概念相同 - 所有對象 - 對象交互處理(即:游戲玩法)都發生在您的Game類中。

如果您有兩個或三個不同的游戲元素(或類),這一切都很好。


但是,讓我們假設一個更復雜的游戲。 讓我們采取基本的乒乓球比賽,添加一些彈球元素,如多球和球員控制的腳蹼。 讓我們從Snake中添加一些元素,比如我們有一個AI控制的“蛇”以及一些球或蛇可以擊中的拾取物。 並且為了更好的衡量,我們可以說槳也可以像太空侵略者一樣射擊激光器,激光螺栓根據它們擊中的東西做不同的事情。

Golly這是一個巨大的互動混亂! 我們如何應對呢? 我們不能把它全部放在游戲中!

簡單! 我們創建一個接口(或抽象類或虛擬類),我們的游戲世界中的每個“東西”(或“演員”)將來自。 這是一個例子:

interface IActor
{
    void LoadContent(ContentManager content);
    void UnloadContent();

    void Think(float seconds);
    void UpdatePhysics(float seconds);

    void Draw(SpriteBatch spriteBatch);

    void Touched(IActor by);

    Vector2 Position { get; }
    Rectangle BoundingBox { get; }
}

(這只是一個例子。沒有“ 一個真正的演員界面 ”可以適用於每個游戲,你需要自己設計。這就是我不喜歡DrawableGameComponent 。)

擁有一個通用界面允許Game只談論Actors - 而不需要知道游戲中的每一種類型。 只剩下每種類型的共同事物 - 碰撞檢測,繪圖,更新,加載,卸載等。

一旦你演員的時候,你可以開始擔心特定類型的演員。 例如,這可能是Paddle一個方法:

void Touched(IActor by)
{
    if(by is Ball)
         ((Ball)by).BounceOff(this.BoundingBox);
    if(by is Snake)
         ((Snake)by).Kill();
}

現在,我喜歡讓球被槳反彈,但這真的是一個品味問題。 你可以反過來做。

最后,您應該能夠將所有演員都放在一個大型列表中,您可以在游戲中輕松迭代。

實際上,出於性能或代碼簡單性的原因,最終可能會有多個不同類型的actor列表。 這沒關系 - 但總的來說,我只是堅持游戲的原則只知道通用演員。

演員也可能想要查詢出於各種原因存在的其他演員。 因此,給每個演員提供一個游戲參考,並在游戲中公開演員列表(當你編寫游戲代碼並且它是你自己的內部代碼時,不需要對公共/私人超級嚴格。)


現在,您甚至可以更進一步,擁有多個接口。 例如:一個用於渲染,一個用於腳本和AI,一個用於物理等。然后有多個實現可以組成對象。

本文將對此進行詳細介紹 我在這個答案中有一個簡單的例子。 如果您開始發現您的單個actor接口開始變成更多抽象類的“樹”,那么這是一個合適的下一步。

您也可以選擇開始考慮游戲的不同組件如何相互通信。

Ball和Paddle都是游戲中的對象,在這種情況下,是Renderable,Movable對象。 Paddle具有以下標准

它只能上下移動

  1. 槳葉固定在屏幕的一側或底部
  2. Paddle可能由用戶控制(1對計算機或1 vs 1)
  3. 可以渲染球拍
  4. 槳只能移動到屏幕的底部或頂部,它不能通過它的邊界

球具有以下標准

它不能離開屏幕的邊界

  1. 它可以呈現
  2. 根據它在槳上的位置,您可以間接控制它(一些簡單的物理)
  3. 如果它落在槳的后面,那么圓就完成了
  4. 當比賽開始時,球通常附着在丟失的人的槳上。

確定可以提取界面的通用標准

public interface IRenderableGameObject
{
   Vector3 Position { get; set; }
   Color Color { get; set; }
   float Speed { get; set; }
   float Angle { get; set; }
}

你也有一些GamePhysics

public interface IPhysics
{
    bool HasHitBoundaries(Window window, Ball ball);
    bool HasHit(Paddle paddle, Ball ball);
    float CalculateNewAngle(Paddle paddleThatWasHit, Ball ball);
}

然后有一些游戲邏輯

public interface IGameLogic
{
   bool HasLostRound(...);
   bool HasLostGame(...);
}

這不是所有邏輯,但它應該讓您了解要查找的內容,因為您正在構建一組庫和函數,您可以使用它們來確定將要發生的事情以及可能發生的事情以及您需要當事情發生時采取行動。

另外,看看這個,你可以改進和重構它,這樣它就是一個更好的設計。

了解您的域名並寫下您的想法。 計划失敗正計划失敗

您可以將球和球拍視為游戲的一個組成部分,XNA為您提供基類GameComponent ,它具有您可以覆蓋的Update(GameTime gameTime)方法來執行邏輯。 此外,還有DrawableGameComponent類,它帶有自己的Draw方法來覆蓋。 每個GameComponent類都有一個Game屬性,它保存創建它們的游戲對象。 在那里,您可以添加一些服務,您的組件可以使用它來自己獲取信息。

您想要制作哪種方法,要么具有處理每次交互的“主”對象,要么向組件提供信息並讓它們自己做出反應,這完全取決於您。 后一種方法在大型項目中是首選。 此外,這將是面向對象的處理事物的方式,為每個實體提供自己的Update和Draw方法。

我同意安德魯所說的話。 我也在學習XNA和我的課程,例如你的球類。 我至少有一個更新(游戲時間)方法和一個Draw()方法。 通常是Initialize(),Load()。 然后從主游戲課我將從他們各自的表兄弟那里調用這些方法。 這是在我了解GameComponent之前。 這是一篇關於你是否應該使用它的好文章。 http://www.nuclex.org/blog/gamedev/100-to-gamecomponent-or-not-to-gamecomponent

暫無
暫無

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

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