[轉貼]游戲設計工具---游戲引擎 |
|
axsoft
版主 發表:681 回覆:1056 積分:969 註冊:2002-03-13 發送簡訊給我 |
游戲設計工具---游戲引擎作者:小謝 資料來源: 雲風工作室 早想寫一點游戲設計的文章與大家交流,一是經驗的問題,二是公司正在緊張的游戲制作期,實 在抽不出多少時間,一直沒有動手,今天忽然頭腦發熱,寫了一段,以后准備陸續寫一些游戲創意,策 劃,制作,流程管理,和制作工具等方面的文章供大家參考. 我們的游戲設計經驗主要是冒險游戲和角色扮演游戲,但我們設計游戲工具時盡量適應其余題 材,不過是否可行未經檢驗. 寫這篇文章的意圖一是想為游戲界做點事,拋磚引玉吧,另外是公司正在尋找志同道合的戰友, 我寫一點文章交一交朋友,許多東西僅僅是我們的經驗,不一定很好.參考而已吧 游戲設計工具包括游戲編輯工具和游戲引擎兩塊; 編輯工具:交互編輯游戲數據,生成游戲引擎所需的數據文件,包括以下幾個功能塊: 圖像編輯,場景編輯,物品編輯,動畫編輯,人物編輯,事件編輯等,具體介紹在以后的 文章介紹. 先從游戲引擎說起. 語言:VC5.0 操作系統:WIN95 圖像引擎:DIRECT X 5.0 支持游戲風格:各種類型和視角以及多層次的冒險游戲和角色扮演游戲 整個游戲引擎包括以下功能塊: * 資源管理:圖像庫CIMGLIB,聲音庫CSOUNDLIB,通過編輯工具形成的資源文件來定義,每種資源 包括定義管理和一些操作接口.圖像庫圖"像包括多種格式(BMP,GIF.AVI,FLC等)以及他形成的內存 格式定義,子圖定義(每一張圖片包括許多小圖,需定義它的小圖位置,當然可以自動生成),游戲需 要的特殊定義,比如行走,身體性質,中心定位點,觸發區,可以根據自己的要求擴充各種性質定義. 圖像最好允許圖像組合定義.聲音庫包括WAV和 MID的定義和再現. 資源由IMGLIB.DAT和 SOUNGIMG.DAT定義,調試版本中最好不要將資源打包,而是指向正常的 文件名,發行版本中再打包,這樣修改和不同工作人員協調容易一些,否則最好有一個自己的資源 管理器.我們在調試版本中數據文件採用文本描述格式.許多數據可以手工編寫而不需要專門的 編輯工具. 資源管理對象還包括內存管理,比如設置時間閥釋放長期不用的資源. * 聲音管理:CSOUND,包括Creat(),Sound(char *fileName...),SetPos(),等,DirectSound有一 些函數,我們要做的是封裝簡化,減少對外的接口. * 窗口系統:接管標准窗口系統,一個完善的游戲引擎最好有一個自己的界面系統,至于簡單還是 複雜根據自己情況具體分析,一個具備基本功能的界面系統1000行程序就可以對付下來,需要窗口 系統的原因是一般的圖像引擎不支持標准窗口,二是可以便于移植到別的操作系統.在我們的游戲 引擎中,游戲只是窗口系統的一種特殊控件(CWINGMCTR),因此可以實現多窗口游戲等特殊要求. CWINGMCTR是一種特殊控件,通過他來控制游戲.包括控制和顯示. * 圖像引擎:所使用的圖像引擎的管理,我們使用的是DirectX,包括Creat(),CreatSurface(), OutToScr(),Bilt()等對外接口;他不是游戲的重點,我們盡量將圖像引擎細節封裝起來. * 圖像管理:這是處理圖像的中心,一般處理游戲顯示喜歡以某種圖像引擎為中心來設計,我覺得 最好設計自己的對象來封裝別人的圖像引擎,這樣不會因某引擎而受限制,移植也比較容易,我們雖 然使用的DIRECT X ,但實際上對外的接口是一種CPICPAGE的界面,他不但包括DIRECT X 的surface, 也包括標准的位圖,AVI界面,GIF動畫界面,以及自定義的格式,他將各種類型的圖像統一起來,對外 使用統一操作,比如DRAWTEXT,BILT,LINE等標准圖形圖像操作,以及擴充的ALPHA通道,透明度等操 作.為了減少內存的需求,特別是16M高彩,不要將全部圖像使用DIRECT X的表面,對一些刷新不多的 圖像,比如背景,可以使用標准256色位圖,甚至一種GIF表面,需要時再解壓,我們還使用一種單色位 圖用來從背景中摳圖,比如一所場景中一棵巨大的樹,只要不是動畫,我們可以用單色摳圖的形式從 背景中扣除來作為另外一層,這樣我們可以大大降低圖像的內存需求.因此採用全部手繪(或3D場景), 而不是小圖拼貼的場景成為可能.通過各種手段可以節約60%的內存需求. CPICPAGE可以通過TimeTrace()以及多線程來改寫內容,比如AVI的改變. * 游戲控制:這部分包括顯示和控制,由CGAME->CGAMEPAGE->CGMOBJ對象組成,CGAME是總控對象, 包括許多CGAMEPAGE游戲頁,CGAMEPAGE是一個具有連續場景的游戲片斷,有點類似于游戲的一關, CGAMEPAGE由一系列CGMOBJ組成,CGMOBJ是游戲的基本對象,由他繼承出地圖,物體,物品,人物,武器, 動畫,觸發器,多媒體按鈕等特殊游戲對象,這是一個根據游戲要求不斷豐富和改寫的部分,對外的 接口是:SendDraw(),Draw(),TimeTrace(),AcceptMsg(),SendNetMsg(),AcceptNetMsg()等,他是通 過CWINGMCTR來調用,每種對象有許多控制參數,對象之間允許通訊,以及有自己的生長死亡發展的 控制,盡量做到對象與外界減少直接接口,通過消息實現交流. * 對象分為兩類:景色對象和活動對象, o 景色對象定義了組成場景的元素,包括背景和前景兩層,可以是由整個圖片組成或由RPG常用的 圖片拼貼法的組成,它的特點只作為背景或前景,活動物是在他們的之間活動,一般定義后不做改變, 也不做控制,由于支持圖像界面多格式,所以我們可以方便地使用AVI或 GIF動畫作為背景來增加場 景的效果和真實性.景色還包括了行走性質定義,我們採用的是8x8為一單元,每個單元定義了一種 性質,比如平地,草地,障礙物等. o 活動對象是在背景和前景之間活動,他們之間有相互的位置關系,前后關系隨著位置改變會不斷 改變,因此他在所屬的CGAMEPAGE中次序是動態的.對象的關系一般是由Y軸定義,由于要支持斜視角和 複雜的地形結構,光靠Y軸是不夠的,我們引入了地基線的概念,通過在地基線之上還是之下來判斷前 后關系,地基線的定義在圖像定義中描述.活動對象有複雜的參數,可以接受外界消息,可以有自己的 各種反應.我們在引擎中使用了一種描述語言來描述他們的反應,比如對鼠標擊打,人物經過等產生 參數改變,發聲,對話等的回應.描述語言將作為專門的一章來介紹. 游戲顯示過程是這樣的, 在每次刷新期時窗口的游戲控件調用他所屬的游戲頁 CGAMEPAGE->SendDraw(); 游戲頁將要顯示的對象按前后次序送往窗口,同時注明此對象是否改變,窗口分析改寫的區 域,調用每個對象的Draw()接口來刷新活動的區域,為了增加速度,並不是顯示所有的區域,而是只改 寫活動區域,因此我們設計了一個CCLIP的對象來管理刷新定義,它的原理是將表面分為16*16的單元, 最終顯示時計算出優化后的多個剪切區域.整個窗口系統和每個游戲控件擁有自己的CCLIP對象.另 外一項增加速度的方案是游戲控件擁有一個比顯示窗大兩倍的顯示頁,這樣場景滾動時只要將顯示 位置改變即可,不用刷新所有區域. 游戲控制的過程是這樣的:AcceptMsg()來接受各種消息調用腳本來改變自己參數和狀態並影響 別的對象,另外每次時鐘來時,調用每個對象的TimeTrace()來改變狀態,比如動畫改變,運動軌跡改變, 觀察周圍的對象做出反應等. * 系統控制模塊:對系統的參數做出反應.不同的題材控制不一樣,比如即時戰略等.只要改寫這部 分以及擴充游戲對象,引擎便能支持不同的題材.至于人工智能,智能行走,只是對象的方法,比較簡 單,只是需要時間. 游戲控制部分比較複雜,每一種游戲對象都有許多控制的細節,在這篇文章里不做具體描述,以后 再說吧. * 最后一個是網絡模塊:我們正在開發的是國內第一個圖形化MUD游戲,網絡是它的核心部分,介紹 網絡的內容很多,需專門文章.我們使用的不是DirectPlay,使用的是WinSoct,考慮的是UNIX作為服務 器的需求.網絡要解決的難點是安全,同步和數據壓縮,這里要用到許多技巧. 游戲是通過數據文件來定義: 數據文件格式:數據文件包括資源定義文件和游戲定義,界面定義文件,文件的數據格式我們採用 的是文本形式,類似于WEB的文本,這樣的好處一是版本升級容易處理,二是可以減少前期對編輯工具的 功能要求,因為我們可以用文字編輯器處理大部分數據,然后有時間再設計一個強大的工具比較現實, 當然,最終提供給用戶的是處理后的數據文件.他中間有一個轉換模塊. 游戲的運行流程描述(不是真正的過程,按DOS格式描述): CreatGameWindow();//初始化window窗口 CreatDraw(hWnd); //初始化圖像引擎 CreatSound();//初始化聲音引擎 CreatAvi()//初始化AVI引擎 CreatNet();//初始化網絡引擎 LoadGameData();//讀取游戲定義數據,包括資源定義文件和游戲定義,界面定義 While(1) { WINTraceMsg();//處理系統消息,比如鼠標,鍵盤等 GameTimeTarce();//處理活動的游戲頁的時間反應 WinPaint();//刷新游戲顯示 OutToScr(); } 我們這里介紹的是單線程結構,許多部分可以用多線來加快游戲速度,但結構是一樣的,就不多介 紹了. 游戲引擎的系統分析是游戲設計技術方面的成功關鍵,是最容易走彎路的部分,希望我們的文 章能給大家一點啟發,由于今天的游戲趨向于多類型綜合,設計引擎時一定不要拘泥于某一單項題材, 我們在策劃這套引擎時要求他支持的游戲非常廣,甚至支持多媒體設計,這套引擎只要擴充或改寫參 數管理以及游戲對象,便能支持各種風格的2D類游戲.將來我們要做的是一套可以交互設計各種游戲 的開發平台,當然不是<<游戲工廠>>似的玩具. 今天就寫到這里,這只是對引擎結構的大概介紹,其中每一點將來都有詳細的描述,歡迎同志商討. 我們盡量回答朋友們的意見,歡迎加入我們的隊伍. 目前win95下比較常用的圖像引擎是DirectX,國內資料比較少,我給大家推薦過《高性能 WINDOWS圖形設計》這本書,大家不妨找一下. 在我們的游戲引擎中,目前使用的也是DirectX,網上見到有關DirectX的簡化接口的對象 庫,沒有使用過,不知如何,最好是自己做這些對象,靈活些. 圖像引擎在游戲中的作用是這樣的,設置顯示模式,管理操作一種特殊圖像表面,顯示到屏幕. 圖像引擎對象:class DirectDrawWin { HWND hWnd; BOOL IsUse; int winWidth,winHeight; LPDIRECTDRAW2 ddraw2; LPDIRECTDRAWSURFACE primsurf; LPDIRECTDRAWPALETTE palette; CDirectPAGE bakDirectPAGE;//背景表面,是CPICPAGE的繼承對象CDirectPAGE的實例 LPDIRECTDRAWCLIPPER clipper; RECT displayrect; int displaydepth; WORD loREDbit, numREDbits; WORD loGREENbit, numGREENbits; WORD loBLUEbit, numBLUEbits; public: DirectDrawWin(); ~DirectDrawWin(); BOOL IsWorking(void); int OnCreate(HWND _hWnd,BOOL IsFullWin=FALSE,int colors=16,int width=640,int height=480); void DrawScene(); BOOL ClearSurface( LPDIRECTDRAWSURFACE surf, DWORD clr, RECT* rect=0 ); BOOL ClearSurface( LPDIRECTDRAWSURFACE surf, DWORD r, DWORD g, DWORD b, RECT* rect=0 ); BOOL BltSurface(LPDIRECTDRAWSURFACE destsurf,LPDIRECTDRAWSURFACE srcsurf, int srcInX, int srcInY,DWORD flap, RECT *DecView=NULL,RECT *souRectBlt=NULL,//源圖片目標區 RECT *lpFillRect=NULL); CPICPAGE *GetDecDrawPage(void); LPDIRECTDRAWSURFACE CreateSurface( DWORD w, DWORD h ); HRESULT SetColorKey(IDirectDrawSurface *pdds, COLORREF rgb); //====================================================================== private: void SetHWnd(HWND _hWnd); HWND GetSafeHwnd(){return hWnd;}; BOOL CreateFlippingSurfaces(); void OnDestroy(); DWORD RGBtoPixel(DWORD r, DWORD g, DWORD b); void GetSurfaceRect(LPDIRECTDRAWSURFACE surf,RECT *lpRc); DWORD ColorMatch(IDirectDrawSurface *pdds, COLORREF rgb); BOOL GetSurfaceRect( LPDIRECTDRAWSURFACE surf, RECT& rect); ////////////////////////////////////////////////////////////////////// WORD LowBitPos( DWORD dword ); WORD HighBitPos( DWORD dword ); BOOL StorePixelFormatData(); BOOL DetectDisplayMode(); };大家可以看到,對外的接口有限,主要是初始設置OnCreate,輸出到屏幕DrawScene, 然后是表面的生成CreateSurface和圖像操作ClearSurface,BltSurface; 初始設置OnCreate():初始DrectX,設置顯示模式,申請前表面,背景表面.對于即時 滾屏的游戲,為了加快速度,可以將背景表面設置得比顯示區大,這樣滾動時只要局部更 改活動區,設置DrawScene時的起始位置即可.但我們沒有使用這項技巧,我們的系統設 計原則之一是:盡量少用技巧,靠系統設計提高速度,而不是局部技巧,原因是技巧的適應 範圍一般有限.系統盡量要求通用. 表面的生成和圖像操作被一個叫CPICPAGE的通用圖像頁調用,CPICPAGE是一個包括各 種位圖格式的統一管理對象,游戲在進行圖像操作時,不直接與DirectX圖像表面打交道, CPICPAGE擴展了DirectX圖像操作功能,比如帶alpha通道的BLT,以及帶亮度的BLT,直接對 表面的Line,DrawTxt等.BltSurface()是一個包括許多剪裁定位輸求的函數. 對于窗口模式下的DrawScene,為了避免屏幕產生圖像撕裂現象,可以利用垂直同步刷 新同步地更新屏幕,為了減少此過程的等待時間,可以使用多線程技術. 為了加快游戲顯示速度,在使用DirectX中有許多可以挖掘的技巧. 有關DirectX的部分我不作詳細介紹,網上有一部分資料,另外可參閱《高性能 WINDOWS圖形設計》一書,我們的這個對象就是在其書的基礎上簡化而來,需要這部分源代 碼的朋友可來信與我們聯系. 圖像頁CPICPAGE介紹 圖像頁指的是內存中保存圖像數據的各種表面,屏幕緩存,各種圖片數據,窗口界面的 界面數據等,不要只依靠DirectX的表面,最好單獨用一個對象來管理這些內容,避免直接與 DirectX打交道,這樣改變引擎和移植到別的操作系統的工作量會小得多. 在我們的引擎設計中,CPICPAGE是一個功能強大而且擴充性極好的對象,比如我們不想 使用DirectX表面,而想自己設計一種表面結構,游戲的其余部分不須任何改變,只要從CPICPAGE 發展出CSELFPAGE的對象即可.象我知道的"騰圖"公司的余雪松和吳冬黎(兩個非常優秀的程 序師,我從他們那里收益非淺,他們也是國內比較早的"xx"游戲站點的主人)就有一套自己的 功能強大的圖像表面.游戲對圖像的操作一般不是直接對具體類型的表面操作,而是調用他們的根對象CPICPAGE. 在我們的游戲引擎中,圖像頁的結構是這樣的 CPICPAGE CBitmapPage//標准windows的位圖,如果使用16M色模式,對于一些不常更新的圖像,使用 //16M色的DirectXDraw是種巨大的浪費,比如背景,我們可以保存一塊比視 //口大的DirectXDraw表面作為背景區,只在一定條件下才將256色原圖 //CBitmapPage寫入背景區(使用任意調色版可保証非常高的圖像質量,特別 //是使用Potoshop 5.0或Animatorfor Window 作為真彩轉換256色工具,顏 //色失真極小),平時游戲讀的是高速的DirectXDraw背景表面 CDirectXDrawPage//標准的DirectXDraw表面, CGifPage//Gif動畫表面,隨著時間自動修改圖像內容,繼承CDirectXDrawPage CAviPage//AVi動畫表面,隨著時間自動修改圖像內容,繼承CDirectXDrawPage,可以帶自己線程 CFlcPage//Flc動畫表面,隨著時間自動修改圖像內容,繼承CDirectXDrawPage 目前我們只設計了這些類型,但可以供據需要隨時擴充. class CPICPAGE { protected: char picStyle;//圖像類型 BOOL CanWrite;//是否可以寫 int picWidth,picHeight;//尺寸 DWORD activeMode;//靜態,可釋放, unsigned short useTimeMark;//使用時間標記,如果長時間未使用,則保存到虛擬文件中 char *programeBuf;//可以用代碼來控制圖像的改變, //我們支持腳本語言對圖像進行特殊控制 char *lpImgBuf;//圖像內存 long imgBufLen;//內存長度 HDC hDC;//標准設備句柄,指對CDirectXDrawPage和它的繼承對象有效 BOOL hasChg;//圖像內容是否已經改變 BOOL UseClip;//是否設定顯示剪裁區 RECT clipRc;//顯示剪裁區 public: CPICPAGE(); ~CPICPAGE(); virtual void Destroy(void); char GetPicStyle(void); BOOL GetSize(int *w,int *h); void GetRect(RECT *lpRc); char *GetImgBuf(void); BOOL Load(char *lpFileName,long startOfs=0);從文件中讀取內容 virtual BOOL LoadFile(FILE *lpFileHandle,long startOfs=0){return FALSE;}; virtual void BeginDraw(){};//如果是標准的DirectXDraw表面,再進行 //Window的標准圖形讀寫時要獲得HDC,如果是連續寫,不要 //馬上釋放,反複申請和釋放HDC會大大降低速度 virtual void EndDraw(){};//終止Window的標准圖形讀寫,釋放HDC virtual HDC GetHDC(void){return NULL;}; virtual void Line(int bx,int by,int ex,int ey,COLORREF rgb); virtual void drawStrgs(char *strg,short bx,short by, char drawBox,short choice); virtual void Draw(RECT *lpRc,COLORREF *lpCr,char drawStyle,DWORD otherMess); virtual void Fill(RECT *rc=NULL,COLORREF colorFill=0); virtual void DrawRect(RECT *rc,COLORREF colorLeft,COLORREF colorRight, COLORREF colorFill,COLORREF colorKey, DWORD drawStyle); virtual BOOL BltInView( CPICPAGE *lpDec, int srcInX, int srcInY,//x,y是souRectBlt相對于整個des表面的位置 DWORD flap=0, RECT *DecView=NULL, RECT *souRectBlt=NULL,//源圖片目標區 RECT *lpFillRect=NULL) {return FALSE;}; virtual BOOL FillRect(CPICPAGE *lpSou,RECT *lpSouRect=NULL,RECT *lpDecRect=NULL){return FALSE;}; virtual BOOL Scroll(int scrollX,int scrollY,RECT *lpRect=NULL){return FALSE;}; virtual BOOL ChgSize(int chgWidth,int chgHeight,int mode=0){return FALSE;};//0 設置尺寸,1 改變尺寸 virtual BOOL HasLost(void){return FALSE;}; //已經丟失圖像數據 virtual BOOL Scroll(int scrollX,int scrollY,COLORREF fillColor=0, RECT *lpScrollRc=NULL){return FALSE;}; virtual void TimeTrace(vodi);//時間跟蹤,動畫可以在此時更改自己的圖像 }; class CDIBPAGE:public CPICPAGE { HDIB hDIB; LPSTR lpDIBHdr; unsigned aLineByte; BYTE biBitCount; char style; char *LpGetIMG(void); public: CDIBPAGE(){picStyle=BMPPIC;}; BOOL Creat(int width,int height,DWORD mode=0); BOOL SetBmp(char *_lpImgBuf); BOOL LoadFile(FILE *lpFileHandle,long startOfs=0); BOOL StretchDIBits(HDC hDC,LPRECT lpDCRect,LPRECT lpDIBRect,DWORD dwRop,BOOL canChg=FALSE); BOOL Blt(HDC hDC,LPRECT lpDCRect,LPRECT lpDIBRect,DWORD dwRop=SRCCOPY); virtual BOOL BltInView( CPICPAGE *lpDec, int srcInX, int srcInY,//x,y是souRectBlt相對于整個des表面的位置 DWORD flap=0, RECT *DecView=NULL, RECT *souRectBlt=NULL,//源圖片目標區 RECT *lpFillRect=NULL); }; class CDirectPAGE:public CPICPAGE { LPDIRECTDRAWSURFACE surf; public: CDirectPAGE(){surf=NULL;picStyle=DIRECTPIC;} ~CDirectPAGE(); void Destroy(void); BOOL Creat(int width,int height,DWORD mode=0); LPDIRECTDRAWSURFACE GetSurface(void) {EndDraw();return surf;} virtual BOOL LoadFile(FILE *lpFileHandle,long startOfs=0); HDC GetHDC(void); void BeginDraw(); void EndDraw(); virtual BOOL BltInView( CPICPAGE *lpDec, int srcInX, int srcInY,//x,y是souRectBlt相對于整個des表面的位置 DWORD flap=0, RECT *DecView=NULL, RECT *souRectBlt=NULL,//源圖片目標區 RECT *lpFillRect=NULL); void Fill(RECT *rc=NULL,COLORREF colorFill=0); BOOL Scroll(int scrollX,int scrollY,COLORREF fillColor=0, RECT *lpScrollRc=NULL); };這里面我只列舉了一些常用的接口,另外還有一些象帶alpha通道的BLT,line, 以及帶亮度的BLT,Line等,可以供據游戲的要求隨時擴充.對標准DirectXDraw表面,我們可以 在開始時使用一些window的庫函數,然后如果時間允許再改為自己的速度更快的函數.系統設 計時一般先完成功能,中后期才作優化,不要一開始馬上陷入過多的技術細節,除非是決定系統 成敗的關鍵的速度要求. 通過二,三章的工作,現在系統便可以顯示一些圖像和動畫了,顯示部分有關的內容基本 就完成,下一章介紹資源管理.聲音部分在最后介紹,因為那部分實現起來比較簡單. 資源管理 這里所說的資源管理不僅僅只是資源打包,它包括了定義和壓縮,打包,以及各種性質定義 和操作接口. 本章只介紹圖像資源管理. 定義文件名:IMGLIB.DAT 在調試版本中我們使用的腳本語言,只有在發行版本中才將其加密和壓縮. 文本舉例 PATH ".\IMGLIB\" //放置圖片的路徑,在調試版本中,圖片是不打包的,發行版本中 //才打包和壓縮在一個文件中 #def id=0,name="1",file//對象類型,有文件型,圖素拼貼型,複合型等,可以擴充自己的類型 #begin include file "man.bmp" //包含"man.bmp"的圖片 include file "manalpha.bmp" //alpha通道圖片 makpicpage directXpage //生成的表面類型,缺省是DirectXDraw表面,參見"第四章" memctroll TRUE //內存自動管理 litImgs 16 //總共有16張小圖 litimg place (0,0,30,30) (30,0,60,30)...//子圖在圖片中的位置,可以自動生成 //litimg place auto //子圖在圖片中的位置,自動生成 defgo 0,0,0,0,0,3,5... //行走性質定義,我們使用的8*8為一單元 touch litimg=0,(10,0,0,1,1,30,30..)//可以定義子圖複雜的觸發區,這在 //冒險游戲和多媒體中有時需要 middle all in top( or all in bottom or seldef 0,0,..) //每張子圖片的中心定位點,這在人物行走時特別重要 //定位有幾種方法:頂點,坐標,.... #end大家可以看出,這是一個很複雜的定義格式.他不像許多游戲直接使用圖片作為資源,而是包含了 一些控制描述的複合定義,當然最簡單的形式也就是一個文件名,其余可以使用缺省控制. 首先說說素材的類型,我們經常看到地圖編輯器的介紹,提來提出無非是什麼拼貼視角等等詞語, 在我們的引擎中,許多界限都被打破,比如地圖的構成,象《仙劍奇俠》許多游戲使用的是一種我們稱 為"圖素拼貼"的技術構成,它的原理是採用8*8(或其他尺寸的單元)距陣紀錄每個單元對用的材質的 序列號,而不是使用實際的點陣數據,這樣可以節約大量的內存,另外一種方法是直接使用整張繪制 的圖像,比如直接由3D設計的一個場景,這在象《命運之手》等游戲中使用過.而在我們的引擎中, 這些游戲類型的定義都打破了,我們統一使用的是大的圖片,但這張圖片可以是只包含索引的拼貼紀 錄,甚至可以是其他已定義資源的合成資源. 隨著硬件內存的增加,使用整張圖片作為連續滾屏(而不是切換)的背景成為可能,但如果不注意 壓縮,16M色的內存需求仍然讓人恐怖,雖然效果是上去了,所以我們一方面提出了一些場景組成方案, 圖像壓縮使用方案,在某些局部兼容原來的"圖素拼貼"的技術有時也是必要的. 這個資源使用的方法很簡單: IMGLIB::Blt(int imgid,int sonImgNo,CPICPAGE *decPage,RECT *decPlace,...); 省略的是其他擴展寫法,比如亮度控制,alpha控制等等.不管資源是什麼類型,接口一致,保証 了系統的擴充性,這就是對象繼承的優勢,在整個系統構架中,我們都注意了這些,比如前面提到的 "三:圖像頁CPICPAGE介紹". * 子圖:每一張圖片可以包含許多小圖片,比如一個人的一套動作包含一張圖片中,這樣容易管理, 子圖數要定義其在圖像中的Rect,我們使用一種色為子圖邊框色,這樣可以自動得到位置,而不是每個 手工測量,也沒有子圖必須使用統一尺寸的要求.當然怎麼做不重要,只要你得到了結果,生成尺寸也 是配套的開發工具必須解決的事情. 每一張圖片可以帶對應的一張圖片作為alpha通道圖片,這是生成一些特技效果的需求,我們會 在另外一張專門介紹當前比較常用的一些特技效果技術比如光影煙霧等和實現辦法以及他對提高游 戲效果的意義. * 行走性質的定義:定義每張圖片的一些性質,比如地面,懸崖,障礙等,對如人物,還有頭,手,心等 詳細定義,這樣可以制作一些格斗游戲. * 觸發區:普通的圖片觸發區要麼是包含它的方框,要麼是實體區,對于一些多媒體,要求在一張圖 片中包含多個非規則的觸發區,比如一個人的圖片,擊打不同的軀體位置顯示不同的動畫,這便用到此 定義,使用:int IMGLIB::GetTouch(int imgId,int sonImgNo,POINT *pt);得到此點在觸發區的序號. 生成表面類型:定義此資源生成的CPICPAGE的類型,這是為了盡量減少內存的需要. 見第三章. * 中心定位點:一般地圖背景使用的做左上角為定位點,而人物通常使用的是圖片的下部中間為定位 點,我們在腳本語言中規定了幾種標准定位方式,但對于一些非規則體,比如中心位置不標准的人物圖 片,允許使用坐標標定. 圖像資源管理使用的是一個CIMGLIB的對象,對象包含了一個資源的列表單. 通過前幾章,我們基本上可以顯示一個地圖和人物動畫了,再加上控制,一個簡單的游戲就可以演示 了. 下面簡單的描述一下過程: hWnd=InitWindow(640,480) DirectXWin.OnCreat(640,480,TRUE); ImgLib.Load("IMGLIB.DAT"); while(1)//按dos寫法 { delay(100); time ; //刷新游戲顯示 { CPIGPAGE *lpPage=DirectXWin.GetBakPage();//得到背景圖像頁 Imglib.Blt(0,1,lpPage,0,10);//將序號為0,子圖號為1的背景圖片顯示在0,10上 Imglib.Blt(2,time,lpPage,100,100);//將序號為2,子圖號不斷改變的人物圖片顯示在背景上 } DirectXWin.OutToScr();//輸出到屏幕 }一個游戲引擎包含了太多的內容,不知這篇文章什麼時候能寫完?! 由于這套引擎本身功 能比較全,要介紹的特別具體我們時間不允許,里面許多地方由于時間關系語言邏輯沒有條理, 甚至不通,大家原諒. 時間就是金錢---[ 發問前請先找找舊文章] |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |