[HGE]-原始碼分析-2 一個小demo
先來看看HGE是怎麼使用的吧。
先上程式碼
這個是HGE包裡面的第7個樣例,是一群龍貓滿屏飛,看著很溫暖,這是HGE的特點吧,所有樣例開啟都有種很柔和的感覺/* ** Haaf's Game Engine 1.8 ** Copyright (C) 2003-2007, Relish Games ** hge.relishgames.com ** ** hge_tut07 - Thousand of Hares */ // Copy the files "font2.fnt", "font2.png", "bg2.png" // and "zazaka.png" from the folder "precompiled" to // the folder with executable file. Also copy hge.dll // to the same folder. #include "hge.h" #include "hgefont.h" #pragma comment(lib,"hge.lib") #pragma comment(lib,"hgehelp.lib") #define SCREEN_WIDTH 800 #define SCREEN_HEIGHT 600 #define MIN_OBJECTS 100 #define MAX_OBJECTS 2000 struct sprObject { float x,y; float dx,dy; float scale,rot; float dscale,drot; DWORD color; }; sprObject* pObjects; int nObjects; int nBlend; // Pointer to the HGE interface (helper classes require this to work) HGE *hge=0; // Resource handles HTEXTURE tex, bgtex; hgeSprite *spr, *bgspr; hgeFont *fnt; // Set up blending mode for the scene void SetBlend(int blend) { static int sprBlend[5]= { BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE, BLEND_COLORADD | BLEND_ALPHABLEND | BLEND_NOZWRITE, BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE, BLEND_COLORMUL | BLEND_ALPHAADD | BLEND_NOZWRITE, BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE }; static DWORD fntColor[5]= { 0xFFFFFFFF, 0xFF000000, 0xFFFFFFFF, 0xFF000000, 0xFFFFFFFF }; static DWORD sprColors[5][5]= { { 0xFFFFFFFF, 0xFFFFE080, 0xFF80A0FF, 0xFFA0FF80, 0xFFFF80A0 }, { 0xFF000000, 0xFF303000, 0xFF000060, 0xFF006000, 0xFF600000 }, { 0x80FFFFFF, 0x80FFE080, 0x8080A0FF, 0x80A0FF80, 0x80FF80A0 }, { 0x80FFFFFF, 0x80FFE080, 0x8080A0FF, 0x80A0FF80, 0x80FF80A0 }, { 0x40202020, 0x40302010, 0x40102030, 0x40203010, 0x40102030 } }; if(blend>4) blend=0; nBlend=blend; spr->SetBlendMode(sprBlend[blend]); fnt->SetColor(fntColor[blend]); for(int i=0;i<MAX_OBJECTS;i++) pObjects[i].color=sprColors[blend][hge->Random_Int(0,4)]; } bool FrameFunc() { float dt=hge->Timer_GetDelta(); int i; // Process keys switch(hge->Input_GetKey()) { case HGEK_UP: if(nObjects<MAX_OBJECTS) nObjects+=100; break; case HGEK_DOWN: if(nObjects>MIN_OBJECTS) nObjects-=100; break; case HGEK_SPACE: SetBlend(++nBlend); break; case HGEK_ESCAPE: return true; } // Update the scene for(i=0;i<nObjects;i++) { pObjects[i].x+=pObjects[i].dx*dt; if(pObjects[i].x>SCREEN_WIDTH || pObjects[i].x<0) pObjects[i].dx=-pObjects[i].dx; pObjects[i].y+=pObjects[i].dy*dt; if(pObjects[i].y>SCREEN_HEIGHT || pObjects[i].y<0) pObjects[i].dy=-pObjects[i].dy; pObjects[i].scale+=pObjects[i].dscale*dt; if(pObjects[i].scale>2 || pObjects[i].scale<0.5) pObjects[i].dscale=-pObjects[i].dscale; pObjects[i].rot+=pObjects[i].drot*dt; } return false; } bool RenderFunc() { int i; // Render the scene hge->Gfx_BeginScene(); bgspr->Render(0,0); for(i=0;i<nObjects;i++) { spr->SetColor(pObjects[i].color); spr->RenderEx(pObjects[i].x, pObjects[i].y, pObjects[i].rot, pObjects[i].scale); } fnt->printf(7, 7, HGETEXT_LEFT, "UP and DOWN to adjust number of hares: %d\nSPACE to change blending mode: %d\nFPS: %d", nObjects, nBlend, hge->Timer_GetFPS()); hge->Gfx_EndScene(); return false; } int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { int i; hge = hgeCreate(HGE_VERSION); // Set desired system states and initialize HGE hge->System_SetState(HGE_LOGFILE, "hge_tut07.log"); hge->System_SetState(HGE_FRAMEFUNC, FrameFunc); hge->System_SetState(HGE_RENDERFUNC, RenderFunc); hge->System_SetState(HGE_TITLE, "HGE Tutorial 07 - Thousand of Hares"); hge->System_SetState(HGE_USESOUND, false); hge->System_SetState(HGE_WINDOWED, true); hge->System_SetState(HGE_SCREENWIDTH, SCREEN_WIDTH); hge->System_SetState(HGE_SCREENHEIGHT, SCREEN_HEIGHT); hge->System_SetState(HGE_SCREENBPP, 32); if(hge->System_Initiate()) { // Load textures bgtex=hge->Texture_Load("bg2.png"); tex=hge->Texture_Load("zazaka.png"); if(!bgtex || !tex) { // If one of the data files is not found, // display an error message and shutdown MessageBox(NULL, "Can't load BG2.PNG or ZAZAKA.PNG", "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL); hge->System_Shutdown(); hge->Release(); return 0; } // Load font, create sprites fnt=new hgeFont("font2.fnt"); spr=new hgeSprite(tex,0,0,64,64); spr->SetHotSpot(32,32); bgspr=new hgeSprite(bgtex,0,0,800,600); bgspr->SetBlendMode(BLEND_COLORADD | BLEND_ALPHABLEND | BLEND_NOZWRITE); bgspr->SetColor(0xFF000000,0); bgspr->SetColor(0xFF000000,1); bgspr->SetColor(0xFF000040,2); bgspr->SetColor(0xFF000040,3); // Initialize objects list pObjects=new sprObject[MAX_OBJECTS]; nObjects=1000; for(i=0;i<MAX_OBJECTS;i++) { pObjects[i].x=hge->Random_Float(0,SCREEN_WIDTH); pObjects[i].y=hge->Random_Float(0,SCREEN_HEIGHT); pObjects[i].dx=hge->Random_Float(-200,200); pObjects[i].dy=hge->Random_Float(-200,200); pObjects[i].scale=hge->Random_Float(0.5f,2.0f); pObjects[i].dscale=hge->Random_Float(-1.0f,1.0f); pObjects[i].rot=hge->Random_Float(0,M_PI*2); pObjects[i].drot=hge->Random_Float(-1.0f,1.0f); } SetBlend(0); // Let's rock now! hge->System_Start(); // Delete created objects and free loaded resources delete[] pObjects; delete fnt; delete spr; delete bgspr; hge->Texture_Free(tex); hge->Texture_Free(bgtex); } // Clean up and shutdown hge->System_Shutdown(); hge->Release(); return 0; }
程式碼已經被引擎封裝的相當好用了,這是HGE的特點之一,灰常好用。
包含必要的標頭檔案,hge.h是必須的,此外用到什麼輔助類就包含哪個,例如這裡用到了字型就包含hgefont.h
執行的時候在可執行檔案位置放hge.dll,HGE的聲音用了bass庫,所以在程式需要播放聲音的時候也需要添入bass.dll
由於編譯器原因編譯時可能會報LIBC.lib庫打不開,把它遮蔽了就行
ok說說程式碼吧
其中Winmain是最熟悉的,不過裡面的很多都被HGE自己封裝過了,視窗的設定方式都變成了類似hge->System_SetState(),有點像DX的SetRanderState。
這裡不光會傳遞進去一些常規的引數比如視窗大小,標題什麼的,而且會傳進去進入主迴圈的函式,稍後說。
設定完之後,就是喜聞樂見的初始化操作,初始化時會載入資源,初始化一些物件的引數,比如精靈(管理點陣圖的渲染,座標,一直不明白為什麼會叫精靈)。
在之後是初始化我們的點陣圖物件,就程式碼最開始那個sprobject,裡面有位置,速度,旋轉方向,旋轉速度,縮放,縮放速度
這裡結束以後,就是下面3句,設定混合顏色,然後Let's rock,看來作者也喜歡搖滾嘻嘻。
SetBlend(0);
// Let's rock now!
hge->System_Start();
系統啟動後就進入主迴圈開始掉兩個主要的函式FrameFunc和RenderFunc
一個生成幀,一個畫出來,好和諧=。=
我們在使用HGE的時候主要寫的程式碼就在這裡。
對於這個樣例,FrameFunc裡面主要是檢測一些鍵盤輸入,然後讓所有小龍貓按照設定的速度做一些變化
RenderFunc就是寫一個迴圈便利所有的小龍貓然後把他們畫出來,所有要用的都是封裝好的,灰常方便。
就這麼簡單就可以完成這個小demo了。
最後在結束時釋放掉資源。