1. 程式人生 > >遊戲引擎程式設計

遊戲引擎程式設計

     如何組織一個引擎的架構。這是引擎最重要的部分,為什麼重要呢?如果我們把引擎看作一間房子的話,那麼架構可以看作是房子的框架,當你完成這個框架後就可以向框架內添磚加瓦蓋房子了。下面讓我們來看看如何構建這個框架,通常一個大型的軟體工程是按照模組化的方式來構建的,程式設計之前要進行必要的需求分析,將軟體工程根據不同的功能劃分為幾個較大的功能模組,對比較複雜的模組你可能還需要將它分為幾個子模組,並需要給出各個模組之間的邏輯關係。當你編寫一個引擎時也需要進行相應的功能分析,讓我們看看如何來劃分引擎的功能模組,如果按照上面的遊戲無關性和相關性進行分析的話我們可以發現它可以分為遊戲相關層和無關層兩層,遊戲相關層由於包含了遊戲的邏輯性程式碼也被稱為邏輯層。邏輯層應該位於引擎的最頂層,如果你在開發一個區域網或線上遊戲的話,按照網路程式的C/S開發模式,這一層應該分為兩個模組,伺服器和客戶端模組,它包含了和特定遊戲相關的所有功能,如AI,遊戲角色,遊戲事件管理,網路管理等等。在它下面就是遊戲無關層了,包括了引擎核心模組,GUI模組,檔案系統管理模組等等,其中引擎的核心模組是最重要的部分,邏輯層主要通過它來和底層的模組打交道,它應該包含場景管理,特效管理,控制檯管理,圖形處理等等內容。在向下就是一些底層模組了,如圖形渲染模組,輸入裝置模組,聲音模組,網路模組,物理模組,角色模型模組等等,所有的這些底層模組必須通過核心模組來和邏輯層進行互動,因此核心模組是整個引擎的樞紐,所有的模組都通過它來進行互動。

下面看看應該如何來進行模組的設計,這裡有一些通用的規則是你應當遵守的:

1、減少模組之間的關係複雜度。我們知道通常每一個模組內部都存在大量的物件需要在各個模組之間進行相互的呼叫,如果我們假設每一個模組內部物件的數量為N的話,那麼每兩個模組之間的關係複雜度為N*N,這樣的複雜度是不可接受的,為什麼呢?首先是它非常不利於管理,由於各個模組都存在大量的全域性物件,並存在相互依存的關係,並且各自建立的時間各不相同,這就存在初始化順序的矛盾,考慮這種情況,一個模組中存在一個物件需要另外一個模組中的物件才能進行初始化,當這個物件進行初始化時而另外的物件在之前並沒有初始化就會引發程式的崩潰。其次,不利於多人進行同時的開發,由於各個模組存在相互依存的關係,當複雜度非常高時就會出現模組與模組的高度依存,也就是說一個模組沒有完成下一個模組就無法完成,因此就需要一個模組一個模組按照它的依存關係進行程式設計,而無法同步進行。因此在設計模組時的第一件事情是減少模組之間的複雜度,為此你在設計模組時必須為模組設計一個互動介面,並約定所有模組之間的互動必須通過這個介面來進行,這樣模組之間的關係複雜度就降低為1*1了,非常方便管理,同
時這非常利於多人之間進行開發,假如每個人負責一個模組的開發的話,那麼你只需要先完成這個介面類,其他人就可以利用這個介面進行其他模組的開發,而不必等到你完成所有的類再進行,這樣所有的模組都是同步進行,可以節省大量寶貴的開發時間。

2、對類的抽象介面而不是類的實現程式設計。這是《Design Patten》一書作者對所有軟體程式設計者的建議,它也對遊戲程式設計有很大的指導意義。對模組中所有被其它模組使用的類都要建立一個抽象介面,其它模組要使用這個抽象介面進行程式設計,這樣其它模組就可以在不需要知道類是如何實現的情況下進行程式設計。這樣做的好處是在介面不改變的情況下任意對類的實現進行改變而不必通知其它人,這對多人開發非常有用。

3、根據呼叫物件的不同對類進行分層。實際上本條還是對第2條的補充,分層還是為了更好隱藏底層的實現。通常一個類不僅被其它模組使用還要被自身模組所呼叫,而且它們需要的功能也不同,因此我們可以讓一個類對外部顯現一個介面而對內部也顯現一個介面,這樣做的好處和上面一樣,因為一個複雜的模組也是多人在進行程式設計的。

4、通過讓一個類對外顯現多個介面來減少類的數量。減少關係複雜度的一個方法是減少類的數量,因此我們可以把完成不同功能的類合併成一個類,並讓它對外表現為多個介面,也就是一個類的實現可以繼承多個介面。

上面的建議只是起到參考作用,具體實現時你應該根據情況靈活使用,而不是任意亂用。

  下面的內容涉及到具體的程式設計技巧,對於引擎中的全域性物件你可以使用Singleton,如果你不瞭解它是什麼可以閱讀《Design Patten》,裡面有對它的詳細介紹,具體的使用可以通過OGRE引擎獲得。

  呼叫模組內的物件可以通過類廠來實現。COM可以看作是一種典型的類廠,DX就是使用它來進行設計的,而著名的開源引擎Crystle Space也是通過建立一個類似的COM物體來實現的,但是我並不對它很認可,首先構建一個類似COM的類廠非常複雜,開銷有點大,其次COM的一個優點是可以對程式實現向下相容,這也是DX使用它的重要原因,而一個遊戲引擎並不需要。OGRE中也實現了一個類廠結構,這是一個比較通用的類廠,但是使用起來還是需要寫一段程式碼。我比較欣賞VALVE的做法,它通過使用一個巨集就解決了這個問題,非常高效,使用起來也非常方便。這個做法很簡單,它把每個
模組中需要對外暴露的介面都連線到一個內部維護的連結串列上,每一個介面都和一個介面名相連,這樣外部模組可以通過傳入一個介面名給CreateInterface函式就可以獲得這個介面的指標了,非常簡單。下面看看它的具體實現。它內部儲存的連結串列結構如下:

class InterfaceReg
{
public:
    InterfaceReg( InstantiateInterfaceFn fn , const char *pName );

public:
InstantiateInterfaceFn m_CreateFn;
const char *m_pName;

InterfaceReg *m_pNext;
static InterfaceReg *s_pInterfaceRegs;
};

並定義了兩個函式指標和一個函式

#define CREATEINTERFACE_PROCNAME "CreateInterface"
typedef void *(CreateInterfaceFn)( const char *pName , int *pReturnCode );

typedef void *(InstantiateInterfaceFn)( void );
DLL_EXPORT void *CreateInterface( const char *pName , int *pReturnCode );

下面看看它如何通過巨集來建立連結串列

#define EXPOSE_INTERFACE( className , interfaceName , versionName ) \
static void *__Create##className##_Interface() { return (interfaceName*) new className; } \
static InterfaceReg __g_Create##interfaceName##_Reg( __Create_##className##_Interface , versionName );

如果你有一個類CPlayer它想對外暴露介面IPlayer,那麼很簡單,可以這麼做

#define PLAYER_VERSION_NAME "IPlayer001"
EXPOSE_INTERFACE( CPlayer , IPlayer , PALYER_VERSION_NAME );

如果在其他模組內你需要獲得這個介面,可以這麼做

CreateInterfaceFn factory = reinterpret_cast<CreateInterfaceFn> (GetProcAddress( hDLL , CREATEINTERFACE_PROCNAME ));
IPlayer player = factory( PLAYER_VERSION_NAME , 0 );

其中hDLL為模組的控制代碼。這裡函式指標factory實際指向模組內部的CreateInterface函式,這個函式通過比較傳入的介面名從連結串列找到指定類指標。

  解決了類廠問題,下面讓我們看看如何建立模組對外的介面,在Game Programming Gems3的《一個基於物件組合的遊戲架構》一文提出了一種架構,Half Life2引擎中對這種架構進行了有效的擴充套件,你可以讓所有的對外暴露的介面都使用這個架構,前提是模組只有一個介面對外暴露。

class IAppSystem
{
public:
// Here's where the app systems get to learn about each other
virtual bool Connect( CreateInterfaceFn factory ) = 0;
virtual void Disconnect() = 0;

// Here's where systems can access other interfaces implemented by this object
// Returns NULL if it doesn't implement the requested interface
virtual void *QueryInterface( const char *pInterfaceName ) = 0;

// Init, shutdown
virtual InitReturnVal_t Init() = 0;
virtual void Shutdown() = 0;
};

  通過Connect方法你可以將兩個模組建立一個連線關係,通過QueryInterface方法你可以檢索到其他需要暴露介面,這種方法很好的為所有的模組建立一個標準的對外介面,極大的減輕了程式設計的複雜性,遺憾的是在HL2引擎中只有部分模組使用了這個方法,可能是這個介面引入時間太晚的緣故。

相關推薦

遊戲引擎程式設計

     如何組織一個引擎的架構。這是引擎最重要的部分,為什麼重要呢?如果我們把引擎看作一間房子的話,那麼架構可以看作是房子的框架,當你完成這個框架後就可以向框架內添磚加瓦蓋房子了。下面讓我們來看看如何構建這個框架,通常一個大型的軟體工程是按照模組化的方式來構建的,程式設計之前要進行必要的需求分析,將軟體工程

Unity3D 遊戲引擎之C#使用Socket與HTTP連接server數據傳輸包

tco 類型 oba connect asp bre amp 客戶 star 近期比較忙。有段時間沒寫博客拉。近期項目中須要使用HTTP與Socket。雨松MOMO把自己這段時間學習的資料整理一下。有關Socket與HTTP的基礎知識MOMO就不贅述拉,不懂得朋友自己

《黑馬程序猿》 cocos2d遊戲引擎復習筆記一

art cocos2d 程序猿 旋轉 ctrl 次數 進行 是什麽 時間 /** ----------------------------遊戲場景的搭建-------------------------------- 1首先創建一個surfaceview ,它能夠在

Geomystery(幾何迷城)的遊戲引擎設計與實現

isp sum output body ide 信息 orm hid 的人 在這裏介紹Geomystery(幾何迷城)的遊戲引擎設計與實現。 業務邏輯:引擎采用模塊化的MVC(Model模型,View視圖,Controller控制)設計方式,這樣有助於運用多種設計模式

javascript飛機大戰-----002遊戲引擎

pan sco htm gin () ear 效果 time margin 基本html布局 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

Java動畫 重力彈球 如鵬遊戲引擎 精靈 設計一個小球加速落地又減速彈起並反復直到停止的Java程序

ble ack pause ani ring pen nts game 遊戲 package com.swift; import com.rupeng.game.GameCore; public class BouncingBall implements Runnab

Kbengine遊戲引擎-【4】demo-kbengine_unity3d_demo 在容器docker上安裝測試

目錄文件 關於 linux cnblogs 關註 容器 註意 中文 nbsp git地址:https://github.com/kbengine/kbengine_unity3d_demo Demo中文地址:https://github.com/kbengine/kbeng

開發H5牛牛大廳遊戲引擎的選擇:Egret或Laya?

cti visual 回復 pre 開發經驗 中一 程序 進行 社區 Q1446595067官網:h5.haozibbs.com一、H5遊戲開發的引擎介紹 開發H5遊戲的引擎有很多,比如egret、laya、cocos-js等等。這裏主要是分析的是egret和laya,因為

遊戲引擎架構】入門(一)

I/O phy 分析 自定義 ctx 驅動 定義數據 中間 分配 遊戲引擎的組成:運行時組件+工具套件。 運行時組件: 硬件、驅動、操作系統、 第三方軟件開發包(SDK)和中間件:數據結構及算法(STL、STLport、Boost、Loki)、圖形(OpenGL、Dire

cocos2d-x_下載遊戲引擎並創建第一個項目

rom 代碼 setting col file load setup 桌面 目錄 我是一名小白。 下載並創建遊戲項目 第一步:去官網下載cocos2d-x http://www.cocos.com/download 第二步:將安裝包裏邊的 setup.

Xenko C#開源遊戲引擎入門

on() actor scale con 為什麽 pro and 三維 str 最近使有和 Three.js 開發三維頁面,覺得很有趣。以前在做WP應用的時候使用過MonoGame做過一點東西,後來Windows 10上來,MonoGame好像不怎麽支持了,也沒

遊戲引擎架構.pdf高清版免費下載

圖形學 效果 攝像 高速 nbsp 渲染引擎 周期性 純粹 src 下載地址:網盤下載 備用地址:網盤下載 內容簡介編輯[1] 《遊戲引擎架構》同時涵蓋遊戲引擎軟件開發的理論及實踐,並對多方面的題目進行探討。本書討論到的概念及技巧實際應用於現實中的遊戲

遊戲引擎選擇、Mac下和Windows下UnrealEngine 4體驗對比

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

國外15種手機遊戲引擎和開發工具介紹

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

遊戲引擎架構》讀書筆記-遊戲引擎中的C++

《遊戲引擎架構》在兩年前就買了,而且自己也大體的看過一遍,因為自己想學習引擎的底層知識,所以重新又找出了這本書再讀一遍,並把根據自己的理解寫一些讀書筆記在這裡與大家交流。        閒話少續,開始本篇的內容,這本書的第一部分是基礎篇,第一章概述

遊戲開發】免費開源遊戲引擎

開源即開放原始碼(Open Source),遊戲引擎好比賽車的引擎,是用於控制所有遊戲功能的主程式,從計算碰撞、物理加速系統和物體的相對位置,到接受玩家的輸入,以及按照正確的音量輸出聲音等等。無論是角色扮演遊戲、即時策略遊戲、冒險解謎遊戲或是動作射擊遊戲,哪怕是一個只有1兆的小遊戲,都有這樣一段起控

一個人獨立開發 3D 遊戲引擎可能嗎?

  作者:孫志超 連結:https://www.zhihu.com/question/24733255/answer/42000966 來源:知乎 著作權歸作者所有,轉載請聯絡作者獲得授權。 當然可以,但難道有個引擎,就可以做出真正商業化的遊戲麼?

國外大牛對幾大著名開源圖形/遊戲引擎的點評

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

2018最新遊戲蠻牛Egret遊戲引擎

Egret蠻牛公開課是一套全面講解Egret引擎入門和開發的視訊教程,教程全套一共77集視訊,是學習egret入門很好的學習資料。   圍住神經貓案例視訊講解,基於winphone開發,整體遊戲開發過程是個很好的egret參考,是egret引擎所開發的一款經典遊戲。 白鷺講堂主

LGame-0 3 Android與JavaSE遊戲引擎 正式釋出,新增SRPG製作模組

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!