跳到主要內容

發表文章

我的小遊戲

之前提過,我平均每年至少會作個一款小遊戲(不管是新開發或重製),這些小遊戲會開放免費下載。到目前為止已經推出12款了,其中7款Windows遊戲,2款Symbian遊戲,1款J2ME遊戲和1款WindowsMobile遊戲。 開發這些遊戲除了自己好玩外,也是練功的好題目。所以可以發現到,這幾個小遊戲裡面,有好幾款其實只是不同平台的移植(同平台上用不同方式實作練習就不提)。透過這種方式我能接觸並學習到不同平台的開發,同時也能加強跨平台的經驗也訓練小技巧,一舉數得。 會把它開放到 網站 上,只不過是基於獨樂樂不如眾樂樂的簡單想法,有沒有獲得迴響其實也沒所謂。至少每當看著首頁那一堆自己的作品,只有一個爽字能夠形容! (PS:這些遊戲有差不多一半都是WindowsGDI程式...所以效能難免有時不理想,不過那不是重點) ; 25940m (by good) 25940p 實驗中國象棋 (WindowsMobile,240x320) 實驗中國象棋 (Symbian s60, 176x208) 單人撲克101 小香咪咪方塊 小香咪咪方塊 (J2ME1.0) 867 ( upup 原型) 鋤草機 ( 說明 ) 拼吐 ( 說明 ) 傷心掃雷 (Symbian s60, 176x208) Paint by Numbers 2005 ( 說明 )

C++編譯時期靜態多型在遊戲中的應用

上次談到 C++編譯時期靜態多型 的原理,這次要介紹C++編譯期靜態多型要如何應用在遊戲中。雖然這篇文章主要是在談C++編譯期靜態多型的應用,不過其中也牽涉到跨平台的程式設計,所以也順便作點和跨平台程式設計的介紹。 跨平台程式本身不難,困難點在於如何把和平台有關的部份和平台無關的部份切割開,只要作到這點剩下來的就沒什麼難的了。至於要怎樣才能作的好跨平台程式設計並不是在這邊三言二語就能講的清楚。 總之記住儘可能的把平台有關和無關的部份分離,以及儘可能的使用標準的程式庫。例如std::string就是C++標準和平台無關,CreateWindow就是和Windows平台相關的API。 ;;; 如果我們是以C++物件導向來作遊戲程式設計,我們可能會有個上層的CGameApp類別,其它還有遊戲物件如CGameObj等類別。 ; 範例1 class CGameObj { }; class CGameApp { public: CGameMgr<CGameObj> mObjMgr; }; 在範例1中,CGameApp管理所有遊戲物件。這邊我們先不管CGameMgr<>是什麼東西,實際上在本例中我們也不需要去知道。 因為CGameApp是整個遊戲程式的核心,它除了管理所有遊戲物件(CGameObj)外,同時也管理所有其它和遊戲相關的物件或資源或者說狀態(State)。 ; 範例2 class CGameApp { public: CGameDB mGameDB; CGameMgr<CGameObj> mObjMgr; }; 如範例2中的mGameDB,是和遊戲會使用到的資料庫。現在問題來了,如果CGameObj的實體物件需要存取mGameDB怎麼辨。一個簡單的方法就是讓CGameObj內涵一個mGameDB的參考,我們可以在建立一個CGameObj物件時把它傳入CGameObj的constructor。 不過這樣作另一個問題又來了。在CGameApp內不一定只會有一個像mGameDB這樣的東西,通常還會有其它資料是其它物件需要存取的。如果全都傳到物件內,那肯定不是一個好辨法。 有一個更好的解決辨法,那就是把所有資料都集中在一起管理,把它變成一個 singleton ,讓所有物件都能存取到它,也就能存取到所有資料。為了簡單起見,我們讓...

最簡單的單元測試工具 - CppUnitLite

測試驅動開發(Test Driven Development, TDD) 在 敏捷開發流程(Agile Process) 中扮演了一個很重要的角色,不過本文的重點在於TDD,不談Agile,實際上我也不懂,不懂的東西我也不談。 第一次接觸TDD,是在開發 JSR-184 時。在你的JSR(Java Specification Requests)實作和VM整合之前,VM Vendor會要求你的實作至少要通過TCK(Technology Compatibility Kit)。TCK是透過 JCP(Java Community Process) 取得,目的是用來驗證某JSR的實作品是否符合規範。實際上TCK就是一組使用JavaTest harness的測試包,包含了各種用來測試JSR的單元測試(Unit Test)。 以TCK for JSR-184來說,總共包含了161個測試項目,每一個測試項目裡面又再包含了2至10個子測試項目,而每一個子測試項目裡面又有不定數量的更小的測試。JavaTest是個自動化測試的環境,只要載入JSR-184的測試包,設定好環境之後就可以執行自動測試,然後看看結果如何。 JavaTest的測試都是Java寫的,雖然是Java新手,但是當時在發開發的過程中也能感受到TDD的威力。舉個簡單的例子:對於像我這樣不懂3D的人來說,還可以開發3D引擎,你說利不利害。我只需要想盡辨法讓測試能過關就行了,很多細節其實也不懂。這樣說雖然是比較誇張點,但我想要表達的是,TDD果然是神。 ; 話說回來,C/C++是我使用最多的程式語言,所以我如果也要使用TDD的話,就需要找一套支援C/C++的TDD程式工具。因為我沒那麼聰明,所以都只挑簡單易用的,最後終於讓我找到了 CppUnitLite 這個工具。實際上是在閱讀< 修改代碼的藝術 >這本書時,從中學到的,CppUnitLite是作者設計實作的一套短小精幹的UnitTest工具,簡單易用。 這本書的內容我全部忘光光了,但我學會了使用CppUnitLite就算是值回票價了。現在底下內容要作個簡單的介紹,看看如何撰寫單元測試。 ; 下載 後解開檔案,我們只需要將om/CppUnitLite裡的檔案加到我們自己的專案就可以了,om/CppUnitLite裡的Cpp和CppUnitLite資料夾不用管它。 ...

手工打造算式計算機

前面已經對 (E)BNF表示式 作過一個簡介,現在要來看看怎麼樣實作一個可以處理簡單的整數四則運算的Parser。因為我們的重點將放在Parser的語法器(syntax analyser)上,所以忽略字彙剖析器(lexical scanner)不談,雖然一個Parser是由這二部份構成。 ; 許多Parser或Compiler相關的書籍資料上,都會拿簡單的算式計算機作為範例,可以找的到算式計算機的EBNF表示式,底下我們直接引用: expression = term ('+' term | '-' term)* term = factor ('*' factor | '/' factor)* factor = integer | group group = '(' expression ')' 上面的語法可以使用來解析如下的算式: 1+2-3*4 5*(6-(7+8)/9) ; 那麼要如何實作出能夠解析符合我們定義好的規則語法的資料的剖析器呢? 一個剖析器的轉換工作主要分成二個部份:將讀入的資料串流分解為有意義的小單位 token,及處理這些token間的關係。將資料串流分解成小單位 token的工作我們不多作說明。我們現在直接假設我們已經能夠得到分解完畢的 token了,接下來的工作就是分析這些 token之間的關係,檢查它們是否符合我們定義的規則語法。 作法相當的直接。首先,我們從資料串流中獲取一個token,接著檢查這個token是否符合我們正在檢查的語法的第一個符號,如果比對結果是符合的話,那麼我們就把當前的 token 給丟棄並再讀入下一個token,接著再繼續拿這個token和規則的下一個符號作比對。在比對規則時,如果中間遇到了非終端符號,則這個非終端符號會再展開。一直重複這個動作直到讀完所有資料為止,比對的程序才結束。 拿我們定義的group規則來作說明,以下為虛擬碼。 // 檢查當前的token是否是我們所期望匹配的符號 void match(token) {   if (current_token == token)     current_token = get_next_token(); // 如果匹配成功則再讀入下一個符號   else   ...

WTL簡介

good Game Editor的視窗編輯器是以WTL作為框架實作的,因為WTL的資料非常稀少,本文就針對WTL作個簡單的入門介紹。 歷史背景 ATL(Active Template Library,或者ActiveX Template Library ) ,它本來的目的是為了要讓COM元件以及ActiveX元件的撰寫變得更容易。因為ATL是拿來寫COM元件的,所以它只有幾個非常基本的GUI類別,相當於MFC的CWnd和CDialog。 很幸運的是,這幾個 GUI類別有很足夠的彈性可以讓像WTL這樣的東西架構在它之上。 WTL實際上是ATL的一組擴充,它也和ATL一樣都是以C++ Template寫成。它擁有許多像MFC的強大GUI類別所提供的能力,同時還能編譯出更小的執行檔。如果你學習過 MFC的程式設計,那麼你會很習慣於像MFC那樣的元件包裝還有很彈性訊息處理機制,也就是說你會比較容易進入WTL的世界。 WTL有二個主要的修訂版本,版本3及7。版本的號碼對應到ATL的版本號碼,這也是為什麼不叫作版本1及2。一直到版本7.1之後微軟將WTL變成一個開源碼的專案,寄駐在Sourceforge上,而目前最新的版本已到8.1。 安裝 你可以在底下的位址下載到最新版本( http://sourceforge.net/projects/wtl/ ),目前最新的版本是8.1版,而good是使用8.0版本製作。在網站上提供了exe版的自解壓縮檔和zip格式的檔案。下載下來後,解壓縮到電腦上任意的位置。 解壓縮後,AppWiz、AppWizCE 和 AppWizMobile 三個資料夾,提供了以 Java Script撰寫成的針對不同版本Visual Studio的安裝程式。根據自己電腦上安裝的 VS.NET 版本,選擇對應的安裝程式來自動安裝 WTL 精靈到你的VS.NET資料夾。Samples資料夾裡有一些有趣的教學範例程式,有興趣的話可以自行研究看看。 因為WTL完全是以C++ Template實作,所以只有C++ Header檔,不需要任何Lib檔,所以我們只需要把include資料夾的位置加到自己專案的搜尋路徑裡就完成了安裝。因為 WTL可以是個通用的模組,所以一般來說我會選擇把它加入到全域的搜尋路徑裡,這樣就不必每個專案都新增一次搜尋路徑。 以 Visual Stud...

(E)BNF表示式

BNF(Backus-Naur Form)是由John Backus所開發,可用來表示與上下文無關文法的語言,也就是一種用來描述語言的中繼語言(meta-language)。一個BNF表示式是由一個非終端符號(non-terminal)和它的產生式所組成,產生式可以是一個終端符號(terminal)和非終端符號組成的序列。(終端符號中的標點符號一般使用單引號括起來,而字串則使用雙引號) 底下為一個簡單的範例: sent := subj verb '.' subj := “Birds” verb := “sing” 在上面的例子裡面,如Birds、sing及句點('.')表示終端符號。而sent及verb表示為非終端符號。這條BNF句子定義了一條文法,表示的意思為,一個sent是由subj及verb再以一個句點為結尾所構成。 BNF表示式有以下幾種主要表示形式: (1) S := A B C (2) S := A | B | C (3) S := {A} 第一條表示說,S是由ABC三個符號所定義, 而ABC是以序列的形式依序出現,也就是說A之後一定跟著一個B,而B之後一定跟著一個C。第二條表示說,由S可推導出A或B或C其中之一。第三條表示說,由S可以推導出一個或多個A。 範例: S := x A A := y | z (1) xy (O) (2) xz (O) (3) xx (X) (4) yz (X) 以上4個範例中,只有(1)(2)是符合上面BNF文法定義的句子,因為x之後只能接y或z所以(3)不符合文法,因為S只能以x開頭為句子所以(4)也文法錯誤。 範例: id := alpha {alpha} alpha := a | b | c | d (1) aabbbcdd (O) (2) cabbbda (O) (3) baccab (O) (4) bdax (X) (5) 5acd (X) 在上面的5個範例裡面,其中(1)(2)(3)項是正確符合上面BNF的文法定義。而(4)因為alpha裡不包含x符號所以語法不正確。而(5)因為alpha裡面不包含5所以也不正確。 範例: S := '-' FN | FN FN := DL | DL '.' DL DL ...

特訓99稱號

以前在 網站 上擺過後來移除,現在再把它放在這。這是玩了N次收集到的,純脆是個人收藏,只是不知道還有沒有沒收錄到的...