大內高手專欄:

Windows Mobile 遊戲開發經驗談

作者:蔡學鏞

2004 年 11 月

微軟在 PC 平台上具有無可撼動的地位、在伺服器平台上也佔有相當版圖、在 PDA 平台上更是節節逼進龍頭 Palm,而現在,微軟也開始進入智慧型手機平台了。從 2004 年開始,市場推出多款微軟 Smartphone 手機,包括了 ASUS、Mio、Motorola、Dopod… 等廠牌的手機。通常我們將 Pocket PC 和 Smartphone 統稱為 Windows Mobile平台。

除了 Pocket PC 和 Smartphone 之外,微軟還有一個名為 SPOT 的 Mobile 技術。SPOT 是 Smart Personal Objects Technology 的縮寫。微軟已經和許多手錶大廠(包括 Swatch)利用 SPOT 技術推出了 Smart Watch(智慧手錶),另一篇文章〈近在咫尺的行動技術〉一文會介紹到 SPOT 的應用,本文章將焦點集中在 Pocket PC 和 Smartphone 的程式開發上。

.NET Compact Framework

由於 Windows Smartphone 手機和 Pocket PC PDA 已經預先整合了 .NET Compact Framework(後面簡稱為 .NET CF),而且 .NET CF 程式其實就是一般的 .NET 程式,不像 J2ME 程式還有一些特殊的規定要遵守(例如,必須遵守 MIDP Application Model),所以使用 .NET 技術來開發 Windows Mobile 程式是最方便的選擇。任何一個 .NET Framework 程式員都可以很快地寫出第一個 .NET CF 的程式。利用 .NET CF 所寫出來的程式,因為完全符合 Managed PE 檔案格式,而且所用到的程式庫也是 .NET Framework 完整版的子集合,所以可以在 PC 上執行。圖一的例子,一個利用 .NET CF 開發出來的 Smartphone 遊戲,也可以直接在 PC 上執行。(請注意,.NET CF 程式相容於 .NET Framework 1.1,但不一定相容於 .NET Framework 1.0)。目前 .NET CF 最新版是 1.0 SP2。

對 1
圖 1

如果你已經習慣用 J2S E開發 Java 程式,然後才開始用 J2ME 開發程式,你一定會覺得受到許多限制而感到痛苦不已;如果你已經習慣用 .NET Framework 開發 .NET 程式,然後才開始用 .NET CF 開發程式,你一定會因為沒有受到太多限制而感到驚訝不已。大致上來說,.NET CF 只比完整版的 .NET Framework 少了 ASP.NET(包含 Web Services Server 以及 Web Forms,但是 .NET CF 支援 Web Services Client)。.NET CF 不支援 ASP.NET 是很合理的,因為只有 Server 才會用到 ASP.NET。.NET CF 甚至也支援 ADO.NET。(如圖二所示)

對 2
圖 2

下面列出 .NET CF 所支援的 namespace,事實上,除了 System.Drawing 與 System.Windows 之外,其他的 namespace 都在 ECMA-335(ISO/IEC 23271)的定義中,我認為以後或許會有微軟以外的廠商根據 ECMA 或 ISO 的標準來實作出 BREW、APOXI、embedded Linux、Symbian 等平台上的 .NET CF。

System.Collections
System.ComponentModel
System.Configuration
System.Data
System.Diagnostics
*System.Drawing (Not in ECMA 335)
System.Globalization
System.IO
System.Net
System.Reflection
System.Resources
System.Runtime
System.Security
System.Text
System.Threading
*System.Windows (Not in ECMA 335)

從這些 namespace 來看,.NET CF 的功能似乎相當完備。但是事實上 .NET CF 只需要 2.5MB 的空間,而完整版的 .NET Framework 需要超過 40MB 的空間,.NET CF 1.0 用了 18 個 Library,而 NET Framework 1.1 用了 86 個 Library。.NET CF 除了比 .NET Framework 少了一些API之外,.NET CLR 更精簡,並刪除了許多不實用、少用、累贅、以及耗費運算能力的 API。.NET CF 1.0 也不支援 COM Interop(但是微軟將會在以後版本的 .NET CF 支援 COM Interop)。下面的表格整理出 .NET CF 與 .NET Framework 在 API 個數的差異。

  Classes  Methods 
Full .NET Framework  18,700  80,000 
.NET Compact Framework  4,700  13,000 

開發工具

為了幫助程式員進行 Smartphone 手機與 Pocket PC 的 .NET 程式開發,微軟提供了 SDK for Windows Mobile 2003-based Smartphones(簡稱 Microsoft Smartphone 2003 SDK)以及 SDK for Windows Mobile 2003-based Pocket PCs(簡稱 Microsoft Pocket PC 2003 SDK),以為開發工具。你可以到微軟的 MSDN 網站免費下載這兩套 SDK 軟體。安裝完後, SDK 會被整合進 Visual Studio .NET(如圖三所示),並具備 Pocket PC與Smartphone Emulator(仿真器)。最近,微軟將 Smartphone和Pocket PC 的 SDK 整合成一套更方便使用的工具,推出了 Windows Mobile Application Development Toolkit 2004。

對 3
圖 3

開發 .NET CF 程式,目前只能使用 C# 和 Visual Basic .NET,微軟尚未發表對其他語言的支援。Borland 公司上個月剛推出的 Delphi 2005 已經支援使用 C# 與 Delphi 兩種語言來開發 .NET Framework 程式,但是尚不支援 .NET CF。Borland 公司宣稱 Delphi 未來會支援 .NET CF。

有了 .NET CF,Smartphone 的軟體開發者,不再需要像早期 Windows CE 的開發者一樣使用 eMbedded Visual C++。對於程式員來說,.NET 的語言和 API,更可以從 Server、PC、PDA、到 Smartphone,「一以貫之」,減少重新學習新技術的精力耗費。這倒也不是說 .NET CF 是萬能的,儘管 .NET 可以在許多地方可以取代 eMbedded Visual C++/Win32 API,但是仍有一些程式需要利用 eMbedded Visual C++ 來開發(微軟另有 eMbedded Visual Basic,但是已經於 2003 年停止支援),這些需要 eMbedded Visual C++/Win32 API 的程式包括了:

  • Device Driver
  • ActiveSync Provider
  • Control Panel Applet

如果開發的 Windows Mobile 遊戲是益智類(例如象棋、俄羅斯方塊),那麼使用 .NET CF 的 GDI+ 應該足夠應付。如果開發的遊戲是射擊類、動作類,那麼就需要執行速度更快的 API 了。關於遊戲的 API,我們直接想到的就是 DirectX。DirectX 的確是有提供 Windows CE 版本,不幸的是,.NET CF 程式無法呼叫 DirectX,因為:

  • Managed DirectX(也就是 .NET 版的 DirectX)尚未移植到 Windows Mobile 平台上。
  • 微軟雖然有提供 Windows CE 平台的 DirectX,但是 DirectX 是 COM的API,且 .NET CF 1.0 不支援 COM,所以 .NET 程式無法呼叫 DirectX。(如果真的要讓 .NET CF 呼叫 COM API,也是可以做到,但是必須用到 3rd Party 廠商的工具)。
  • 最重要的是,DirectX 沒有內建在 Windows Mobile 平台上。

雖然暫時沒有 DirectX 可用,微軟對於 Windows Mobile 遊戲開發者,另外提供了 GAPI(Game API)。GAPI 的檔案是 \Windows\gx.dll(只有 9.4 KB),是一組很簡單的 API,包含少數幾個函式(function),用來控制螢幕和鍵盤,功能遠比不上 DirectX 的完整。我們可以在 .NET CF 程式中利用 P/Invoke 來呼叫 GAPI,雖然麻煩了一些。GAPI 雖然簡單,但是微軟內部已經有人開始利用 GAPI 來包裝出更方便的 API,你可以在 MSDN 雜誌或網站找到相關的文章。

微軟提供了方便且準確的 Emulator,讓測試很方便。在 Emulator 環境上測試,比起利用 ActiveSync 將程式部署到實體裝置上來測試更方便,更快速。Emulator 不是 Simulator,Emulator 比 Simulator 更精確。Simulator 是用模擬 Windows CE 作業系統的方式,但是 Emulator 則是使用真正的 Windows CE 作業系統,底下則是使用 Virtual PC 的 x86 Virtual Machine 模擬硬體(請見圖四)。也因此大部分的程式只要能通過 Emulator 測試,部署到實體機器(手機、PDA)上就不會有問題。通常,.NET CF 程式在開發階段,只要用 Emulator 來測試就可以了。

對 4
圖 4

當開發完畢之後,在實體裝置上測試,仍然有必要。因為,在極少數的狀況下,在Emulator上執行和在實體裝飾上執行會有差異,這包括了:

  • Emulator 是建構在虛擬 x86 CPU,但實體裝置的 CPU 可能是 StrongARM、MIPS。如果你的程式是和 CPU 有關係,執行狀況可能會有所差異。
  • Emulator 的字型和實際裝置的字型可能有出入。特別是,中文字型。
  • Emulator 的硬體配備很可能和實體裝置不同。
  • Emulator 的執行速度和實體裝置可能會有很大的差異。

使用Windows Mobile將遭遇到的挑戰

開發手機遊戲程式時,必須注意到畫面的設計,因為畫面的美觀與否,會立即影響使用者對此遊戲的觀感。當遊戲畫面的資訊量多時,需要利用高度的技巧,才能在這有限的空間中放入足夠的資訊。一般慣常使用捲軸(Scrollbar)來增加空間,但是此技巧只適合呈現靜態資訊,對於 Smartphone 遊戲並不太適合。

為了要在小畫面上呈現許多資訊,可以利用色彩攜帶一些資訊。使用適當的色彩,不但可以增加資訊量,也可以讓畫面更美觀,但是太多的色彩會造成視覺上的負擔,錯誤的色彩組合也會造成畫面醜化,違反直覺的色彩選擇更會造成操作上的錯誤暗示。關於色彩,如果程式員沒有足夠的美感,必須請教美工專家給予建議。

Smartphone 遊戲程式設計時,也必須特別注意 CPU 和記憶體的使用。良好的資料結構和演算法可以加快計算速度,減少記憶體浪費,減少 GC 的負擔。為了提升效率,整個 Windows Mobile 作業系統的 Process 數目限制在 32,而且已經有數個被系統本身用掉,只剩下 20~25 個。我們可以利用 .NET CF 的 Application Domain 來模擬 Process。

使用 .NET CF 將遭遇到的挑戰

在 .NET CF 中,有許多冗贅的 API 被刪除,要達到相同的功能,必須繞道而行。有些時候,甚至連「繞道而行」的機會都沒有。例如:.NET CF 不支援 .NET Remoting、Registry、COM、ClearType,也不提供 NGEN。

在 PC 上的 .NET 程式可以利用 Double Buffering(雙緩衝區)的技巧,來消除畫面閃爍。但是 Double Buffering 會耗費許多記憶體空間,所以 .NET CF 並不支援。為此,必須利用 invalid() 和 update(),來將畫面需要更動的小區域進行重繪,而盡量減少大範圍的重繪。

Smartphone 遊戲程式免不了要用到繪圖的 API,也就是 GDI+。然而,.NET CF 版本的 GDI+ API 不支援許多功能,其中包括了 Anti-alias(消除鋸齒狀),和 Transform,這使得利用 GDI+ 所繪製的圖文看起來不甚美觀。Anti-alias 與 Transform 會耗費CPU的計算能力,所以 .NET CF 不支援,這是我們可以理解的。為了達到 Anti-Alias 的效果,我的作法是:將圖利用 Anti-Alias 繪製好,程式利用貼圖的方式來展現這些圖。這麼做隨之而來的缺點是,程式體積會變大(因為嵌入圖檔的關係),同時也欠缺使用上的彈性。

Pocket PC vs. Smartphone

Pocket PC 和 Smartphone 雖然很類似,但是仍有不少差異。Pocket PC 上可以開發 Windows Application、Class Library、Non-Graphical Application;Smartphone 上可以開發 Windows Application、Class Library,但是不能開發 Non-Graphical Application。請注意,Pocket PC和Smartphone 都不能開發 Console Application(文字模式的程式)。

微軟 Smartphone 的畫面大小為 176x220,如果扣除標題列與選單列則為 176x180;微軟 Pocket PC 的畫面大小為 240x320,如果扣除標題列與選單列則為 240x268,如圖五所示。

如果你使用 Visual Studio 的畫面設計工具(designer),你可能會注意到視窗的大小並非如這裡所敘述的尺寸。以 Smartphone 來說,是 182x235,而非 176x220;以 Pocket PC 來說,是 246x325,而非 240x320。這是因為,Visual Studio 用 PC 版的視窗邊框和標題列來當作 .NET CF 的視窗邊框和標題列,造成計算錯誤。也算是 Visual Studio 的一個小 bug。不管你將視窗大小如何設定,Pocket PC 與 Smartphone 的程式一定是全螢幕的,所以你不應該去更改視窗大小(即使你更改了,執行時也不會有效果的)。甚至,為了避免不小心拉動視窗大小,你應該在一建立新的 .NET CF 專案之後,就立刻將 Form 的 Locked 屬性設定為 true,表示在 design-time 不允許更動視窗大小。

對 5
圖 5

如果想設計一個 .NET CF 遊戲能在同時在 Pocket PC 和 Smartphone 上執行,必須一開始就把畫面處理的原始碼獨立出來,不要和遊戲的主要程式邏輯混雜在一起。

對於 Smartphone 來說,操作介面指的就是手機上的按鍵,其感知的是按鍵事件(key event)。Smartphone 遊戲必須以一隻手能操作為最佳,且必須符合使用慣例。對於 Pocket PC 來說,主要的操作介面是觸控筆(stylus),其感知的是滑鼠事件(mouse event)。如果你在 .NET CF 遊戲程式中同時提供按鍵事件和滑鼠事件的 event handler,可以讓此遊戲程式可以兼顧 Smartphone 與 Pocket PC 的需求。

對於 Menu 的使用,Smartphone 有嚴格的限制。最上層 Menu 只能有兩個 Menu Item,且只有右邊的 Menu Item 可以有 Sub¬-Menu(次選單)。不遵守這些規則,將導致程式執行失敗(但是編譯仍會過關)。

固然 Smartphone 2003 和 Pocket PC 2003 都是使用 .NET CF 1.0,但是兩者的 API 仍有些許差異,Smartphone 版本的 .NET CF 是 Pocket PC 版本的子集合,有一些 API 被去除,例如,Smartphone 版本的 .NET CF 不具備 System.Windows.Forms.Button,因為 Button 只對指標式(pointer)的操作介面(滑鼠、觸控筆)有意義,對於手機這種按鍵式的操作介面來說,Button 根本沒有意義。按鍵的介面適合用選擇的方式設計操作介面。(如圖六所示)

對 6
圖 6

AI

遊戲的 AI(人工智慧)對手不能太聰明,也不能太笨,否則玩此遊戲老是輸或老是贏,就一點都不好玩了。AI 對手的動作必須有適當的停頓,例如,移動棋子時,一格一格地移動,而不是馬上移到定點。關於遊戲的AI程式設計方式,可以參考 O’Reilly 出版的《AI for Game Developers》一書(http://www.oreilly.com/catalog/ai/)。另外,我的朋友 David Weller 等人所著的《.NET Game Programming in C#》一書也值得參考(APress出版)。

設計 AI 時,切忌過於理論。手機遊戲的AI應該是以「堪用」為目標,而不是以「擊敗人腦」為目標。擊敗人腦是深藍(deep blue)超級電腦的事,與我們無關。也因此 Smartphone 遊戲軟體開發步驟,從我的經驗歸納出來的建議是:

  1. 先設計畫面,因為畫面可能會導致遊戲規則與操作介面的小幅度變動。
  2. 再設計遊戲引擎,銜接遊戲畫面,此時必須把遊戲規則以及限制條件都加上去。
  3. 接著設計操作介面,和遊戲引擎進行銜接。這個步驟通常很快。
  4. 接著進行自己和自己對戰,對戰的過程中,可以找出畫面、遊戲引擎、以及操作介面的一些瑕疵,同時也可以歸納出一些「贏的手段」。
  5. 最後設計 AI,這個時候,之前習得的「贏的手段」就可以派上用場,被寫成演算法。

結語

雖然目前 .NET CF 的 Smartphone 才剛開始推出,但是 .NET CF 的前景相當看好。.NET CF 程式設計的門檻很低,Microsoft Smartphone 和 Pocket PC 的螢幕規格統一,Visual Studio .NET 使用上很方便,這些特點對於程式員來說是很大的吸引力。我相信未來 .NET CF 的程式會逐漸變多,回過頭來推動 .NET CF 的成長。而遊戲與多媒體應用類的程式會在 .NET CF 的程式中佔有相當高的比例。

意見與支援

 您有任何問題、意見或建議嗎?您可以透過下列電子郵件與作者連絡:
 xy.cai@msa.hinet.net

更多資訊

想知道大內高手專欄的其他文章嗎?請至此專欄所有列表