HGE一點東東
無意中發現了HGE中文社區,聽朋友介紹,認識了HGE,然後開始對它進行研究,並使用HGE開始製作遊戲。
因為我所得的資料基本上都是來源於各位高手的無私翻譯,所以,我打算也做一些貢獻出來,在這裏寫一篇HGE的基礎教程,供剛接觸HGE的朋友研究學習。
教程中可能會出現一些錯誤,請大家及時指正。由於我也是初學者,包括C++,也隻是一個初學者,所以寫出的教程可能質量並不高,也請大家諒解。
另外,學習此教程需要C++的基本知識,不需要非常高深,隻需要了解函數調用、結構體、枚舉、常量、變量、類的基本知識、函數指針等基本知識即可。
關於轉載:
本教程可以隨處轉載,我的名字就不用了,不過請著名來源於HGEChina中文論壇:https://www.hgechina.com/,我們將對此表示感謝。
我使用的編譯器:
我使用的編譯器是Microsoft的Visual C++ 2005,但是Visual C++ 6.0或者Visual C++ 2003等VisualStudio的C++編譯器都是可以使用HGE的,另外,BorlandC++也是可以使用HGE的,本教程將使用Visual Studio 2005為大家做講解,如果有一些編譯器問題上的出入,請大家搜索或者提問解決。
HGE基礎教程第一章:初識HGE
C++有一個理念,我記得是在我看C++ Primer學習時看到的,那就是一次代碼編寫,處處使用,所以,就出現了諸如DLL,LIB等便於大家使用的代碼庫。其思想基本就是把寫好的代碼打包,然後隻要在工程中鏈接lib或dll,就可以使用dll或者lib中寫好的代碼,它們的出現,為資源共享創造了空前的便利。那麼,HGE也是貫徹這個思想的一個庫,它把DirectX進行封裝,方便大家使用,由於直接使用DirectX需要直接接觸硬件上的東西,所以不利於入門,HGE的出現,讓高效圖形編程成為了簡單的東西。
關於免費:
HGE是一個完全免費的,並且開源的引擎,所以我們可以隨便使用在自己的商業或非商業項目,在此,我們也向HGE的編寫者致敬。
激動人心的時刻:第一個HGE程序。
創建工程:
我們在Visual C++中新建一個WIN32工程,選擇Win32控製台程序/Win32 console,為你的項目起一個名字。選擇一個目錄保存你的項目,點擊確定-下一步。
選擇Windows應用程序,並選擇“空項目”/“empty Project”。點擊確定,工程創建完畢,項目文件和代碼就保存在剛才你選擇的目錄裏。
工程的設置:
創建好工程後,我們需要進行一些設置,在左邊的解決方案管理器中,看到你的項目名稱,點右鍵,選擇【屬性R】
打開屬性窗口後,點擊C/C++,將右邊的附加包含目錄設置到你存放HGE引擎頭文件的目錄下,一般情況下,下載了hge引擎解壓後,在hge目錄下的include目錄下。
設置完成後,再雙擊左邊的鏈接器,打開子選項後,點【常規】,右邊的附加庫目錄,選到hge目錄下的lib/vc/目錄
再點擊左邊的【輸入】,右邊附加依賴項:hge.lib、hgehelp.lib
如此一來,工程就設置好了。
好了,我們首先創建一個任意名字的.cpp文件。敲入以下代碼:
另:解釋,我就不寫了,程序很簡短,注釋也很清楚。大家編譯即可創建出第一個HGE程序了。怎麼樣,很簡單吧!
代碼: 寫道: |
#include "hge.h"//包含hge頭文件 HGE *hge=0;//創建一個指向hge類的指針。 bool RenderFunc()//繪製函數,程序開始後HGE將不停調用它 { return false;//程序正常時總是返回false,返回true將從System_Start往下執行 } bool FrameFunc()//邏輯函數,程序開始後HGE將不停調用它,一些邏輯判斷或者處理可以寫在這裏。 { return false;//總是返回false } int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)//WinMain函數,程序的入口。 { hge=hgeCreate(HGE_VERSION);//使用hgeCreate函數創建HGE接口,參數必須傳遞正確的HGE_VERSION,它是在hge.h中定義的 hge->System_SetState(HGE_SCREENWIDTH, 800);//將屏幕寬度設置為800 hge->System_SetState(HGE_SCREENHEIGHT,600);//將屏幕高度設置為600 hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);//設置邏輯函數為FrameFunc函數 hge->System_SetState(HGE_RENDERFUNC,RenderFunc);//設置繪製函數為RenderFunc函數 hge->System_SetState(HGE_TITLE, "我的第一個HGE程序");//設置窗口標題為“我的第一個HGE程序” hge->System_SetState(HGE_WINDOWED,true);//設置使用窗口模式 hge->System_SetState(HGE_USESOUND,false);//設置不使用聲音(第一個程序我們先不講解聲音和圖像的知識) if(hge->System_Initiate())//用hge類的System_Initiate()方法,檢測初始化是否有錯誤出現。 { hge->System_Start();//如果沒有問題,則使用System_Start方法,開始程序。 } hge->System_ShutDown();//程序停止 hge->Release();//釋放HGE所占用的內存。 } |
以上代碼應該比較簡單易懂,那麼,我說一點小東西,是大家需要留意一下的。
一:請注意HGE HeadFile和dll的版本匹配,如果兩個東西的版本不匹配的話,程序是會出錯的,舉個例子,比如你用了hge 1.7的頭文件,而使用hge 1.8的dll,那麼就會報錯。
二:如果你發現了程序開始會有hge的LOGO,那麼不用擔心,它並不是需要付費才可以解除的,我們隻需要加入這一句:h->System_SetState(HGE_SHOWSPLASH,false);即可解除掉程序開頭HGE的LOGO。
三:關於FrameFunc和RenderFunc的返回值,RenderFunc需要一直返回false,這貌似是HGE的一個規則,必須這麼寫,但是FrameFunc就不一樣了,如果返回了true,程序就會從hge->System_Start();函數下麵繼續運行,運行到了 shutdown,程序就結束了。所以,有時候返回true是結束程序的好方法,而不是隨地亂扔System_ShutDown和 System_Release函數。
HGE基礎教程第二章:可以看到的東西--圖像顯示
圖像顯示,是所有程序,包括Windows操作係統在內必不可少的部分,代碼編寫者(程序員)將美工繪製好的圖像顯示到程序中,讓使用者更加直觀的看到程序的意圖。廢話就不多說了,這裏我們來講一下在HGE中,怎麼顯示圖像,我相信跟我一樣,大多數朋友在剛剛接觸一個圖像引擎的時候最關心的就是這個部分。OK,我們看下去。
HTEXTURE:
這是HGE中定義的一個數據類型,用來保存我們加載的圖像,Texture的意思是“紋理”,說白了就是圖片,當然,當你的程序越來越複雜的時候,你會很樂意接受這種很規範的命名。我們現在隻需要知道,這是一個數據類型,至於怎麼把圖像加載、釋放、顯示,我們下麵一一道來
屏幕上的精靈--hgeSprite類:
精靈,看起來很有意思的名字,但是很簡單,它就是呈現圖像的一個工具,每一個精靈都有一些屬性,包括它的圖像,關於這個,可以在置頂貼中找到hgeSprite類的全麵資料。並且附加了代碼。
靈魂部分:代碼
說了那麼多,不如一段代碼來的實在,同樣,我將保留以上簡潔明了的代碼風格,讓大家很方便的讀懂它,並且會有詳盡的注釋:
另外,請用具體的參數替代代碼中紅字部分
代碼: 寫道: |
#include "hge.h" #include "hgeSprite.h" HGE *hge=0;//創建HGE指針 hgeSprite *spr;//創建精靈類指針 HTEXTURE tex;//定義一個texture(紋理)對象 bool RenderFunc()//繪製函數,程序開始後HGE將不停調用它 { hge->Gfx_BeginScene();//開始渲染 hge->Gfx_Clear(0xFF000000);//以某顏色清屏,OxFF000000為透明度為0的黑色 spr->Render(顯示位置X,顯示位置Y);//在指定位置顯示精靈 hge->Gfx_EndScene();//結束渲染 return false;//總是返回false } bool FrameFunc()//邏輯函數,程序開始後HGE將不停調用它,一些邏輯判斷或者處理可以寫在這裏。 { return false;//程序正常時總是返回false,返回true將從System_Start往下執行 } int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)//WinMain函數,程序的入口。 { hge=hgeCreate(HGE_VERSION);//使用hgeCreate函數創建HGE接口,參數必須傳遞正確的HGE_VERSION,它是在hge.h中定義的 hge->System_SetState(HGE_SCREENWIDTH, 800);//將屏幕寬度設置為800 hge->System_SetState(HGE_SCREENHEIGHT,600);//將屏幕高度設置為600 hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);//設置邏輯函數為FrameFunc函數 hge->System_SetState(HGE_RENDERFUNC,RenderFunc);//設置繪製函數為RenderFunc函數 hge->System_SetState(HGE_TITLE, "顯示圖像");//設置窗口標題為“顯示圖像” hge->System_SetState(HGE_WINDOWED,true);//設置使用窗口模式 hge->System_SetState(HGE_USESOUND,false);//設置不使用聲音(第二個程序我們先不講解聲音的知識) if(hge->System_Initiate())//用hge類的System_Initiate()方法,檢測初始化是否有錯誤出現。 { tex=hge->Texture_Load("圖片路徑和後綴,這裏是相對目錄,vc++2005是debug目錄");//根據路徑載入圖片 if(tex)//檢測是否圖片成功載入 spr=new hgeSprite(tex,圖片的顯示起始位置X,起始位置Y,圖片寬,圖片高);//初始化精靈spr,並且指定tex為它的紋理 hge->System_Start();//如果沒有問題,則使用System_Start方法,開始程序。 } hge->Texture_Free(tex);//釋放紋理 delete spr;//釋放精靈 hge->System_ShutDown();//程序停止 hge->Release();//釋放HGE所占用的內存。 } |
編譯運行代碼後,是不是看到你指定的圖片被顯示在了屏幕上呢?很簡單吧,遊戲製作的第一步,就這樣輕鬆的被我們邁了出去。
寰子的話:淩晨1:30了,累死我了,我才發現寫教程不是最累的,最累的是排版……
HGE基礎教程第三章:可以聽到的--聲音播放
HEFFECT:
這是HGE中的一個數據類型,就像HTEXTURE一樣,但是它是用來保存載入的聲音的,而HTEXTURE是用來載入保存的紋理(圖像)的。我們根據以上的一章,知道了載入紋理是需要用Texture_Load函數的,那麼,針對HEFFECT數據類型,也有一個函數用來專門載入聲音。
Effect_Load函數
這是一個有返回值的函數,返回的值便是一個HEFFECT數據,於是,我們可以寫:snd=Effect_Load("Source/music.mp3");
Effect_Free函數
這是一個沒有返回值的函數,看函數的名字,Free,也就是釋放了,那麼這個函數不難理解,就是釋放已經載入的聲音數據,作用基本同於delete。
Effect_Play函數
這個函數的返回值是一個陌生數據類型,這個數據類型叫做HCHANNEL,什麼意思呢?就是音軌的意思,我們知道,如果有5個同時播放而互不影響的音樂,那麼,它們處在5個不同的音軌上。那麼,這裏也會返回一個音軌,方便我們來對這個音軌上播放的文件進行操作,諸如:“暫停,播放,繼續,停止” 等。
實例代碼:
以上簡單列舉了一下聲音播放要接觸到的幾個基本函數,當然,我們首先讓程序出聲就可以了,隨後再去考慮變調、變速、或者多軌混合等等這些東西。
代碼: 寫道: |
#include "hge.h" HGE *hge=0;//創建HGE指針 HEFFECT snd;//定義一個Effect(音效)對象 bool RenderFunc()//繪製函數,程序開始後HGE將不停調用它 { return false;//總是返回false } bool FrameFunc()//邏輯函數,程序開始後HGE將不停調用它,一些邏輯判斷或者處理可以寫在這裏。 { if(hge->Input_GetKeyState(HGEK_A))//檢測是否按下了A鍵 hge->Effect_Play(snd);//如果按下了A鍵,則播放音樂snd return false;//程序正常時總是返回false,返回true將從System_Start往下執行 } int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)//WinMain函數,程序的入口。 { hge=hgeCreate(HGE_VERSION);//使用hgeCreate函數創建HGE接口,參數必須傳遞正確的HGE_VERSION,它是在hge.h中定義的 hge->System_SetState(HGE_SCREENWIDTH, 800);//將屏幕寬度設置為800 hge->System_SetState(HGE_SCREENHEIGHT,600);//將屏幕高度設置為600 hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);//設置邏輯函數為FrameFunc函數 hge->System_SetState(HGE_RENDERFUNC,RenderFunc);//設置繪製函數為RenderFunc函數 hge->System_SetState(HGE_TITLE, "播放聲音");//設置窗口標題為“播放聲音” hge->System_SetState(HGE_WINDOWED,true);//設置使用窗口模式 hge->System_SetState(HGE_USESOUND,true);//設置使用聲音 if(hge->System_Initiate())//用hge類的System_Initiate()方法,檢測初始化是否有錯誤出現。 { snd=hge->Effect_Load("聲音路徑和後綴,這裏是相對目錄,vc++2005是debug目錄");//根據路徑載入聲音 if(snd)//檢測聲音是否已經載入成功 hge->System_Start();//如果沒有問題,則使用System_Start方法,開始程序。 } hge->Effect_Free(snd);//釋放聲音資源 hge->System_ShutDown();//程序停止 hge->Release();//釋放HGE所占用的內存。 } |
這基本就是最簡單的聲音播放了,根據以上學過的知識,我再寫出幾個需要注意的東西,第三章就結束了:
1:使用hgeSprite類,HTEXTURE,HEFFECT數據類型時,都不要忘記在不需要的時候或者程序結束的時候進行釋放。
2:一定要在使用資源以前檢測資源是否被載入,否則在使用資源操作函數時程序會出錯退出。(如以上代碼中的if(tex)....)
HGE基礎教程第四章:顯示順序的仲裁者--Z-Buffer
Z-Buffer:
Z-Buffer又被稱為深度緩衝,不要覺得深奧,我一一道破它的秘密。2D空間中,我們習慣了X,Y兩軸的坐標,聰明的朋友可能一眼就知道Z是用來做什麼的,沒錯,既然非要給2D空間安上一個Z坐標軸,那麼它的作用,就是決定2D空間上的對象的前後順序,前麵的擋住後麵的。有人說了:那直接改變繪製順序不就好了,回答是:這樣的程序是在編譯時決定,而Z,是在運行時決定,這就意味著程序的靈活性將又有一個質的飛躍,你覺得哪個好呢?
開啟2D空間中的第三根坐標軸:
不難發現,hgeSprite也好,hgeFont也好,都有一個方法:SetZ(float z);那麼,可能有的朋友也試過,為啥不管用呢?可能你忽略了一步:打開Z-Buffer功能。如何打開呢?很簡單,在開始的時候,使用加上以下一句:
hge->System_SetState(HGE_ZBUFFER,true);
這樣,Z-Buffer的功能就被啟用了。
Z-Buffer的範圍:
Z-Buffer雖然是一個float,但是,它的有效範圍隻在0.0-1.0之間,至於為什麼,我就不知道了,需要去問DirectX了,嗬嗬。在0.0-1.0這個範圍內,Z值越小的對象,將被越靠前繪製,舉個例子:
兩個精靈,SpriteA,SpriteB,他們的Z值分別是0.1,0.2
這樣的話,不管你render的順序是什麼,他們的覆蓋順序都是SpriteA覆蓋SpriteB。
為什麼要使用Z-Buffer:
本來我已經困了,打算明天再寫,不過想了想,這節也沒太多東西,一順兒寫完吧!
好,回歸正題。除了剛才說到的“編譯時決策”和“運行時決策”的問題,使用Z-Buffer又有一個好處,那就是它可以優化速度。拿剛才SpriteA和SpriteB的例子來說,
如果按我們的老思路,如果要A覆蓋B,那麼繪製的順序是:RenderB,RenderA,由遠及近,遠處的先畫,近處的後畫,近處的覆蓋遠處的,就成了一個覆蓋順序正確的圖像。那麼,既然有了Z-Buffer,我麼就要顛覆一下這套理論了,我們要先RenderA,再RenderB,為什麼呢?因為當你 RenderA再RenderB的時候,DirectX會自己判斷,有些地方已經有A的存在了,所以B就不需要在那些地方繪製東西了,直接跳過,小圖不說,如果是兩張滿屏的大圖呢?試想一下要節約多少FPS?這樣的方法被稱為逆向畫家算法,但是,逆向畫家算法也不是隨便用的,必須要有Z-Buffer的支持,而且,最重要的是,Z-Buffer的順序要設置正確,比如,A覆蓋B,那麼A的Z值要比B小,也就是更靠前一些,然後顛倒正常的繪製順序,就達到了我們優化的目的。
說到這裏,一定有人問了,能優化到什麼程度呢?我說一下我的試驗吧,一張800*600的滿屏圖,前麵5000個50*100的動畫小人不停走動,而且是每次都clear屏幕全部重繪的實時刷新,我是Geforce Go 7200的顯卡,FPS達到了30+FPS。拿HGE帶的例子比較,我在我的機器上試了,它的小人比我的小,到2000個的時候,就是30FPS,再往上就卡得要死了,當然,也是沒有經過任何優化,這麼以來,大家比一比,結果就出來了。
以上的東西我已經盡力寫的很明白了,如果還有看不懂的就回帖提問吧!另外,畢竟我也是新手,老手勿笑!
HGE基礎教程第五章:你需要知道的更多一些
hgeSprite的常用方法之--SetHotSpot:
Sprite,翻譯過來是精靈,它是為我們來呈現texture的一個類,開始在圖像顯示的時候我也在代碼裏用到了這個類,這是我們在顯示圖像的時候經常用的東西,可能很多方法大家都不太了解,我現在說幾個常用實用的。首先,我們知道,圖像在屏幕上呈現的位置通常由一個坐標控製,這個坐標相對於屏幕左和上邊緣,那麼,相對於圖像呢?可能有的人習慣認為圖像的坐標相對於圖像就是圖像左上角的位置了,但是又有的人習慣把圖像的中心作為這個決定位置的點,別怕,hgeSprite都會滿足我們的要求,無論多麼苛刻,那就是SetHotSpot方法,使用這個方法,你可以為你的精靈設置一個熱點,這個熱點,不僅僅決定了顯示坐標相對於圖像的位置,同時也決定了旋轉時的中心,可謂是非常實用了。
hgeSprite的常用方法之--SetColor:
看名字就知道,是設置渲染色的,如果你設置一個紅色的渲染色,那麼,圖像呈現出來就是帶著紅色渲染效果的,非常簡單,設置的方法很簡單,是一個 DWORD值,你可以理解為long,是這樣的格式:0xFF00FF00,那麼除去0x,前兩位FF是透明度,這裏是16進製,後麵的6位分別是r, g,b,FF就相當於我們平時的255了。但是這樣看起來可就太不方便了,那我們動用一下係統函數:ARGB(),傳遞給這個函數a,r,g,b,這4個參數,它就會反回一個相應的16進製數,那麼,我們就可以這樣些:SetColor(ARGB(alpha,r,g,b));這樣看起來,是不是簡單多了呢?好了,先說這麼兩個,說說其他。
如果我重新載入了Texture呢?
我們前麵可以看到,hgeSprite是和HTEXTURE配套出現使用的,HTEXTURE是數據,而hgeSprite負責呈現它們,那麼如果重新載入了圖像呢?有的朋友會習慣性的學習new和delete使用時的方式,也就是要換,先調用hge->Texture_Free(tex) 來釋放texture,然後再delete 精靈,其實是不用的,開始我也是這麼寫的,但是經過站長vicky_lh指點,我們這樣寫就可以:第一,在更換texture的時候你隻需要tex= hge->Texture_Load(path)即可,不需要free,其次,精靈更不需要delete,隻有在對象被卸載,或者程序結束的時候,才需要這麼做。
程序可能出錯,但是我想把錯誤寫到我的文件裏去
如果我們設置了logfile,那麼hge會把所有的錯誤記錄都會寫到這個log裏,如果我們有了自己的需要,那麼如何截獲hge發出的錯誤消息呢?使用這個方法:hge->System_GetErrorMessage(),它會返回一個char *,一個c風格字符串,裏麵就是程序到現在為止最後一條發生的錯誤信息。很方便吧?
我知道怎麼播放音樂了,可是我該如何獲取音樂的長度、暫停、繼續等操作呢?
很簡單啦,可能你也注意到了,有Channel_GetLength、Channel_IsPlaying等方法,可是怎麼用呢?有朋友就問過我這個問題,我說一下如何解決,比如我們載入了一個HEFFECT數據,並且播放了它,那麼,在使用hge->Effect_Play()方法的時候,它會反悔一個HCHANNEL數據,這個數據就是音軌數據,它返回了你這個音樂播放的音軌,我們要操縱這段音樂,就要靠音軌來操作,看代碼片段(這是不能直接編譯執行的,隻是代碼片段):
引用: |
HEFFECT snd;//聲音數據 HCHANNEL channel; snd=hge->Effect_Load("音樂路徑");//載入音樂數據 channel=hge->Effect_Play(snd);//播放音樂數據,並用channel將返回的音軌記錄下來 hge->Channel_SetVolume(channel,"聲音大小");//設置channel軌道聲音的大小 //這樣說,看起來就很簡單了吧!嗬嗬,目的達到了! |
收尾:
本章沒有多少東西,就是說了說一些小的大家不常常注意或者容易犯錯誤的地方,又熬夜寫教程了,馬上過年了,諸位新年快樂
最後更新:2017-04-02 06:51:29