跳到主要內容

發表文章

目前顯示的是有「Boost」標籤的文章

以Boost.Spirit實作算式計算機

Spirit 是開源碼C++程式庫 Boost 裡的一個項目,大量使用了C++ Template Meta-Programming實作技術。它提供了一個用來實作語言剖析器的框架,就好像lex/yacc一樣是專門用來製作語言剖析器的工具。但是Spirit因為應用了C++ Template Meta-Programming的技術,使得我們可以在C++程式碼中寫出相當於 EBNF 的描述且可直接編譯並執行,也因為如此Spirit是一套既神奇又威力強大的工具程式庫。 按照慣例,前面我們已經以 手工的方法 ,以及 lex/yacc的方式 實作了算式計算機,這次我們要使用Spirit來作個簡單的算式計算機。 EBNF表示式 雖然前面我們已經提到過Spirit的神奇的能力,也就是可以直接把EBNF式直接以程式碼的形式寫在C++程式碼內,但是因為受限於C++程式語言的語言,有些表式法需要作些調動,這裡面主要有幾個地方的語法需要注意。 A B 上面是原EBNF表示式的寫法,用來表示一個序列,A之後會有個B。而在Spirit裡需改寫成如下的形式。 A >> B 看起來沒有什麼太大的不同,也可以很容易的理解這是表示在A之後跟著B的序列。再來是*號的用法。 A* 在EBNF內,在符號A之後加個*號,表示A的數量是可重複的,可以是0個以上的A所構成的序列。而在Spirit中需改寫成如下形式。 *A 正好相反,需要把*號擺到符號的前面,因為在C++裡面並沒有任何後序式的*號運算元。不過就算改成前置式也不會影響到原來所代表的意義,並不會造成什麼衝突,容易理解。 A? 這是表示符號A是可有可無,也就是A的數量可以是0個或一個。以下改成以Spirit的寫法。 !A 如你所見到的,問號變成驚嘆號,同時也提到前面變成前置式。那麼一個以上的表示式呢?一樣使用加號,也一樣改成前置式即可,如下所示。 +A 現在來看一個簡單的範例,如下所示是EBNF式,用來表示以逗號分隔的數字的EBNF表示式。 S := INTEGER (',' INTEGER)* 改成Spirit的形式。 S = INTEGER >> *(',' INTEGER); 很直接,也不需要再多作說明。不過上面的式子還不是最終可用的版本,底下還會再陸續交待清楚。 Parser 在上面我們所看...

good spec

程式語言 程式語言:C/C++ 編輯器 系統平台:Windows 視窗框架: WTL 執行時期 系統平台:Windows,MacOS/iPhone 程式庫:smallworld2,stge 第三方程式庫: Lua / SDL / zlib / Boost.Spirit 繪圖(gx) GDI SDL OpenGL 編輯器使用WTL作視窗框架實作,所以主要是以C++ Template實作。而Runtime部份則整個使用C++ Template實作,主要區分成三大模組:good、ed和rt。另外還有個gx模組,簡單定義了圖形介面讓其它模組使用來作圖形繪製。 good模組提供了資源管理的功能,ed模組繼承good模組再擴充編輯功能,而rt模組繼承good模組實作Runtime及提供Script擴充介面。其實正確來說,rt模組並非繼承good模組,而是包含good模組,透過包含及使用good模組作為資源管理。 good模組是個狀態管理器,只能載入資源和讀取內容。ed模組則繼承good模組提供編輯資源內容的功能,可以修改資源並存檔。而rt模組透過good模組載入資源,再經由RunTime及Script將資源和物件關聯起來,並付予物件動作邏輯,最後再透過gx模組將結果呈現在畫面上。

About 25940p

25940p 其實是我自己蠻喜歡的一個小作品,雖然說似乎不怎麼受歡迎的樣子。因為我原來就特別喜歡縱向捲軸射擊遊戲的緣故,才作了相關的研發作了這個作品。話雖說是小品,不過我後來實在退步太多了,自己也很難過關。 線上玩 這個小遊戲花了我大約一個星期的時間製作,主要的時間都花在關卡編輯上。整個遊戲都是用script編輯出來的,所謂的整個,除了彈幕外、敵機什麼時候出來怎麼移動、粒子特效、選單、背景多重星空等等,全都是用script編輯出來的。所以其實說花了一星期製作是假的,我花了更多時間在底層的開發上,為了這個小遊戲我花了幾個月時間,設計開發了專門用來製作射擊遊戲的stge語言和虛擬機器。 本來我作小遊戲花的時間並不多,不過從 鋤草機 開始,我已經開始有那種花很多時間來製作一款可以在很短時間內破關的小遊戲的傾向。比如說鋤草機大概花一個月時間製作,但15分鐘可以過關。25940p也差不多15至20分鐘可以全破,但斷斷續續至少用半年以上時間研發製作。 + + + 為了開發一套專門給射擊遊戲使用的script,我花了很多時間在設計上。完成後,首先是使用C++實作虛擬機器的部份,因為這樣至少可以先進入測試階段。虛擬機器的核心部份以smallworld2的ObjectPool模組為中心管理所有資源,把所有東西都當作粒子作為基本概念,不論是子彈或是敵機等等都用同樣的方式對待。然後所有粒子都能掛上一個可以控制它動作的緒,再加上一些和射擊相關的屬性支援,就可以運作動起來了。 Parser的部份一開始原本是想使用Lex/Yacc來作製作,但後來決定使用 Boost::Spirit ,因為沒碰過可以順便學習新東西,結果還出乎意料外的容易使用,缺點是Complie時間大增。接著再用WTL寫個簡單的工具程式,可以直接在上面編寫script並以視覺化的方式立即檢視執行結果。 最後才是撰寫遊戲程式本身。基本上遊戲本身的主要工作就是畫圖,把所有粒子根據遊戲自己的定義畫出來。子彈粒子就畫成子彈,爆炸碎片粒子就畫成爆炸碎片等等。成像部份使用OpenGL來作,因為也是順便學學OpenGL。 剛好因為成像是用OpenGL的緣故,所以在有支援OpenGL的平台上要作Porting就容易了。這也是為什麼我可以很容易的把25940p移植到PSP和iPhone上。因為除了成像,還有像是IO等和系統比較有...