从J2ME学Symbian游戏开发

ContractedBlock.gif ExpandedBlockStart.gif Code
         相信在手机游戏开发这块是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;

                       }

       讲到了“按键事件”在J2me和Symbian中的类似处理过程,其实这些东西都是一个游戏里必须做的处理,无论是在任何平台。      

        那么在手机游戏里,菜单也是必不可少的。而在Symbian里是不分什么高级UI和低级UI的,只有系统控件和自定义控件之分。

        那么界面交互部分我们一样可以和J2ME做个对比:

       J2ME里的高级UI
+CommandAction()                       Symbian里的系统控件+HandleCommandL()

       J2ME里的低级UI
+KeyPressed()                               Symbian里的自定义控件+OfferKeyEventL()

(三)系统菜单 

      和J2ME里不一样的是,Symbian里的系统控件是通过在资源文件中编辑,在源代码之外独立地指定应用程序的可见控件。在资源中可以定义的系统控件包括菜单、对话框、列表等。

      应用程序框架在应用程序启动时会打开资源文件,并根据在.rsg中创建的资源标识符,根据需要把各个资源加载到C
++代码中。

      这样的架构有一定的好处就是:资源文件和C
++源文件之间可以共享资源文件中定义的数据。

      通常在一个后缀名为.hrh的文件中定义命令菜单中使用的标识符。

      如下实例摘自SDK自带的Graphics实例:

      #ifndef __GRAPHICS_HRH__
      
#define __GRAPHICS_HRH__

      
// Graphics enumerate command codes 
      enum TGraphicsIds
      {
         EGaphicsNoOffScreenDemo 
= 1,
         EGaphicsOffScreenDemo,
         EGaphicsStopDemo
      };

      
#endif // __GRAPHICS_HRH__
      可见资源文件的处理使用的是C的预处理器,以避免多重包含。而.hrh文件也只能包含emnu和预处理语句,其它的C
++语法都会导致资源编辑器编辑失败,这点需要特别注意。

      下面是和这个.hrh文件相对应的.rss文件的内容:

NAME GRAP

#include 
#include 
#include 

#include 
"Graphics.hrh"


// ---------------------------------------------------------
//   
//    Define the resource file signature 
//    This resource should be empty.
//
// ---------------------------------------------------------
//
RESOURCE RSS_SIGNATURE 
 {
 }

// ---------------------------------------------------------
//   
//    Default Document Name
//
// ---------------------------------------------------------
//
RESOURCE TBUF 
 { 
 buf
=""
 }

// ---------------------------------------------------------
//   
//    Define default menu and CBA key.
//
// ---------------------------------------------------------
//
RESOURCE EIK_APP_INFO
    {
    menubar 
= r_graphics_menubar;
 cba 
= R_AVKON_SOFTKEYS_OPTIONS_EXIT;
    }


// ---------------------------------------------------------
//   
//   r_graphics_menubar
//   Menubar for Graphics example
//
// ---------------------------------------------------------
//
RESOURCE MENU_BAR r_graphics_menubar
    {
    titles 
=
        {
        MENU_TITLE 
   {
   menu_pane 
= r_graphics_menu;
   }
        };
    }


// ---------------------------------------------------------
//   
//   r_graphics_menu
//   Menu for "Options"
//
// ---------------------------------------------------------
//
RESOURCE MENU_PANE r_graphics_menu
    {
    items 
= 
        {
        MENU_ITEM 
   {
   command 
= EGaphicsNoOffScreenDemo; 
   txt 
= "No off screen bmp";
   },
        MENU_ITEM 
   {
   command 
= EGaphicsOffScreenDemo; 
   txt 
= "Off screen bmp";
   },
        MENU_ITEM 
   {
   command 
= EGaphicsStopDemo; 
   txt 
= "Stop Animation";
   },
        MENU_ITEM 
   {
   command 
= EAknSoftkeyExit;   
   txt 
= "Exit";
   }
        };
    }
下面对这个文件的内容做一些说明:

RESOURCE RSS_SIGNATURE 
 {
 }

RESOURCE TBUF 
 { 
 buf
=""
 }

这两个一般情况下是不允许做改动的,前者是资源的签名,后者是默认文档名。

===================================================================================

RESOURCE EIK_APP_INFO
    {
    menubar 
= r_graphics_menubar;
    cba 
= R_AVKON_SOFTKEYS_OPTIONS_EXIT;
    }

用来标识菜单和快捷键的ID,就是给菜单和相应的快捷键起个名字而已,以便于程序后面的使用。

===================================================================================

RESOURCE MENU_PANE r_graphics_menu
    {
    items 
= 
        {
        MENU_ITEM 
   {
   command 
= EGaphicsNoOffScreenDemo; 
   txt 
= "No off screen bmp";
   },
        MENU_ITEM 
   {
   command 
= EGaphicsOffScreenDemo; 
   txt 
= "Off screen bmp";
   },
        MENU_ITEM 
   {
   command 
= EGaphicsStopDemo; 
   txt 
= "Stop Animation";
   },
        MENU_ITEM 
   {
   command 
= EAknSoftkeyExit;   
   txt 
= "Exit";
   }
        };
    }
这个才是实际定义的菜单的真正内容,也就是我们能在界面上看得到的Menu_Item的标识和内容。

===================================================================================

       OK了,资源定义已经完成,下面只需要在Ui类的HandleCommandL()方法中针对相应的Command做相应的处理即可。

void CGraphicsAppUi::HandleCommandL(TInt aCommand)
    {
    
switch(aCommand)
        {
        
case EEikCmdExit:
        
case EAknSoftkeyExit:
            Exit();
            
break;

        
case EGaphicsNoOffScreenDemo:
             iAppView
->StartNoOffScreenDemo();
            
break;

        
case EGaphicsOffScreenDemo:
            iAppView
->StartOffScreenDemo();
            
break;

        
case EGaphicsStopDemo:
            iAppView
->StopDemo();
           
break;

        
default:
            User::Panic (_L(
"Graphics"), EGraphicsBasicUi);
            
break;
        }
    }


       现在你也学了和J2ME里的高级UI响应相对应的Symbian里的处理方法,现在和用户交互应该没问题了。无论是按键事件的OfferKeyEventL()方法、还是菜单命令的HandleCommandL()方法。



转载于:https://www.cnblogs.com/bluespot/archive/2008/07/31/1257602.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值