從J2ME學Symbian遊戲開發(一)

gudesheng發表於2008-01-03

        相信在手機遊戲開發這塊是J2ME的天下,一是因為它簡單容易學,二是因為關於它的資料多。

        而J2ME畢竟是執行在Symbian OS的核心之上的,速度慢也是必然的了,更不能忍受的是它把很多與底層的互動封裝了起來,並且不提供介面讓你訪問。

        這對於我這樣喜歡刨根問低的人來說,是實在無法忍受的!

        其實真正瞭解了Symbian OS和相應的Series 60,如果在這個平臺上做遊戲開發的話,Series 60並不比J2ME高深多少。因為它提供了一個AppArc,同樣把一些底層的東西封裝了起來,但是至少我們可以有介面可用來訪問低層的東西。

       下面我就把最近一段時間的學習總結一下:

(一)關於開發工具

       原本是沒有必要寫這個的,不過看到網上五花八門的工具配置、工具安裝的文章,實在覺得有必要出來澄清一下。

      其實,完全沒必要為選擇什麼IDE來煩惱,無論是Moblie Borland C++、VC、VC.NET、CodeWarrior還是Nokia最近力推的Carbide.C++,他們都存在著這樣那樣的問題。沒有一個是完美的開發工具,而且series的SDK還為每一種開發工具提供了不同的版本,真是感覺有點"光了屁股系褲腰帶-----多那麼一道子"。IDE只能用來看原始碼或者寫程式碼,真正有用的還是SDK下的command命令列,不要怕麻煩,這些往往是最重要的。

       命令也就是常用的那麼幾個:

       bldmake bldfiles

      abld build wins udeb

      epoc

      makesis

      devices

(二)關於鍵盤互動

      無論做什麼樣的遊戲,都少不了與使用者的互動,而對於手機裝置來說。與使用者互動的無非是鍵盤,按鍵事件是系統事件的一種,一旦裝置鍵盤上的鍵被按下、按住或釋放的時候即會產生按鍵事件。

     Symbian的Window伺服器通過控制元件棧把按鍵事件傳遞到應用程式。然後通過呼叫控制元件的OfferKeyEventL()方法把按鍵事件通知相應的控制元件。這和我們在J2ME裡通過KeyPressed(int keyCode)把相應的按鍵事件通知相應的Canvas類一樣。

     OK,我們現在有了第一個類比的關係:

    Symbian的OfferKeyEventL()        J2ME的KeyPressed(int keyCode)

    當然,Symbian裡這個方法還有一些需要特別說明的不同之處。

       Symbian裡的控制元件棧是一個結構,負責維護控制元件。當有按鍵事件發生的時候,這個按鍵事件會從控制元件棧的頂部依次傳遞到最底端,直至得到了某個控制元件的處理。預設情況下,控制元件是不在棧中的,所以應該使用相應的函式CAknAppUi::AddToStackL()把控制元件新增到控制元件棧中,使它能夠處理按鍵事件。

      這和我們的J2ME裡不一樣,J2ME裡KeyPressed(int keyCode)是和相應的Canvas裡關聯在一起的。試著想象一下,如果從一個From高階UI切換到Canvas的低階UI,是不是需要用Command命令來控制?

      然後就可以通過呼叫控制元件的OfferKeyEventL()把按鍵事件傳遞給該控制元件。控制元件可以自己決定是否處理某個按鍵事件,如果處理事件,則返回值EKeyWasConsumed,否則返回EKeyWasNotConsumed。按鍵事件會按次序傳遞給控制元件棧中的每個控制元件,直至其中某個控制元件返回EKeyWasConsumed或沒有剩餘控制元件為止。

      OfferKeyEventL()有兩個引數:按鍵事件(const EKeyEvent& aKeyEvent)、按鍵型別(TEventCode aType)。前者表明按鍵是哪一個鍵等資訊,後者則是一個emnu型別,說明按鍵事件的種類。

      和我們在J2ME裡不同的是,J2ME裡用三個方法來分別表示Pressed、Released、Repeated。而Symbian裡用一個emnu型別的引數來說明按鍵事件的種類,分別是:EEventKeyDwon、EEventKey、EEventKeyUp。

      用以下程式碼來做為事例恐怕更能說明問題:

      TKeyReponse CMyControl::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType){

                    if(aType == EEventKeyUp){

                                 switch(aKeyEvent.iCode){

                                                case EKeyUpArrow:

                                                         //producing

                                                        return  EKeyWasConsumed;

                                                 case EKeyDownArrow:

                                                        //producing

                                                       return    EKeyWasConsumed;

                                                  default:

                                                        return   EKeyWasNotConsumed;

                                                   }

                                            }

                                 return    EKeyWasNotConsumed;

                       }



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=818750


相關文章