分享到:

研发图
联络我们 | 访客留言 |
 
论 文 专 利 著 作 项 目 ZigBee 与 Uwb动态 技术FAQ
 

<< 返回上页

 

基于 SymbianO的智能手机游戏开发的技术方案

1 SymbianOS简介[1]

    Symbian操作系统是所有Symbian OS电话共享的应用编程接口[6](API)技术的公共核心。这个核心被命名为"通用技术"(generic technology,简称为GT),它被分成不同的版本。GT包括一个多任务核心、通讯、数据管理和图表中间件,低级图形用户界面框架和应用程序引擎。

• Symbian操作系统历史

    Symbian是一个手机巨头联盟的代名词,该公司成立于1987年,是摩托罗拉、西门子、诺基亚等几家大型移动通讯设备商共同出资组建的一个合资公司,专门研发手机操作系统。而Symbian操作系统的前身是EPOC[1](著名的网站http://www.epocn.com的命名我想就来源于此),而EPOC是Electronic Piece of Cheese取第一个字母而来的,其原意为"使用电子产品时可以像吃乳酪一样简单",这就是它在设计时所坚持的理念。

    Symbian的总部设在英国伦敦,办公室遍布美国、欧洲和亚洲。如需更多关于Symbian和其即将召开的年度行业展览Exposium04—智能电话展的信息。

    Symbian操作系统在智能移动终端上拥有强大的应用程序以及通信能力,这都要归功于它有一个非常健全的核心--强大的对象导向系统、企业用标准通信传输协议以及完美的sun java语言。Symbian认为无线通讯装置除了要提供声音沟通的功能外,同时也应具有其它种沟通方式,如触笔、键盘等。在硬件设计上,它可以提供许多不同风格的外型,像使用真实或虚拟的键盘,在软件功能上可以容纳许多功能,包括和他人互相分享信息、浏览网页、传输、接收电子信件、传真以及个人生活行程管理等。此外,Symbian操作系统在扩展性方面为制造商预留了多种接口,而且EPOC操作系统还可以细分成三种类型:Pearl/Quartz/Crystal,分别对应普通手机、智能手机、Hand Held PC场合的应用。

• Symbian操作系统现状

    Symbian操作系统是一种32位占先式多任务操作系统,具有功耗低,内存占用少等特点,非常适合手机等移动设备使用。而与微软产品不同的是,Symbian将移动设备的通用技术,也就是早错系统的内核,与图形用户界面技术分开,这就使得它能很好的适应不同输入方式的平台,这也是我们能见到不同界面的Symbian系统的主要原因。

    由于支持Symbian操作系统的的移动通讯终端设备厂商众多,因此商场上有相对较多的支持该系统的不同品牌和型号的终端产品,从而使得这个操作系统能够被迅速的推向市场,进而被消费者所接受和认可,而消费者本身也拥有了更多的产品选择。同时,由于这个系统为第三方应用程序开发商提供了一个开放、标准的开发平台,因此,这些开发商一方面可以很容易的开发、设计相关的应用程序,另一方面也拥有了较多可以使用的终端产品。不过支持Symbian操作系统的移动通讯终端设备厂商都是各家自己独立开发设计用户接口程序的,因此往往互不兼容,在设计理念上差距往往会很大。另外,由于各移动通讯终端设备厂商并非专业的应用软件开发公司,因此在应用软件的开发上要面临很多的困难,尤其是在办公软件、媒体录播软件等方面,这样很可能会导致Symbian操作系统没有足够多的应用软件可以选用,不利于发挥Symbian操作系统的强大支持功能。

2 对SymbianOS作为游戏开发平台的系统分析

    对于智能电话这样的小型手持设备,通常是资源非常紧张的设备。这种设备的尺寸和制造费用限制了可用的存储器,处理速度和电池寿命。尽管以上这些资源缺乏,但是这些设备还是需要能够稳定运行相当长的一段时间,甚至数个月。一旦出现资源溢出的错误,对于系统来说重要的事情就是返回到前一个稳定的状态,而不失去任何重要的数据。这使得完全地捕捉和处理每个运行错误对于系统和应用程序来说是非常重要的。Symbian开发他们自己的异常处理程序的另一个原因是开发SymbianOS的时候,try-catch-throw机制还不是C++标准的一部分。trap-harness的概念是使用一个TRAP宏把可能引发异常的函数封装起来。这个宏可用于捕获多个函数,并且这些函数可以嵌套。万一出现一个异常,导致异常的函数的执行就会通过User::Leave函数终止,相当于标准的C++异常处理中的throw。这被称为一个leave(离开),它将返回程序执行到结束的TRAP宏,在那里相应的恢复动作可以被执行。

    Symbian OS提供一个用于在单一线程之内非抢先式多任务处理技术的系统。这个包括活动对象和活动调度程序的系统的设计目标是降低运行时间成本和解决与优先计划线程冲突的同步问题。Symbian OS中的每个应用程序由一个活动调度程序和一个或多个活动对象组成。这个调度程序封装一个需要异步的服务和依照它们的优先权安排活动对象的等待循环。活动对象封装实际的异步服务。

2.1 资源需求

    与许多其它用于游戏的设备不同,智能电话需要在游戏中或者任何其他的应用程序运行的时候能够通知用户各种系统事件。应用程序需要考虑到可能的中断,例如因为打进来的电话或者消息,并且它们需要根据情况进行处理。应用程序还应该不消耗设备资源,例如过度的使用内存或者电量。

    通知用户的大多数系统消息使用系统自己的对话框,称为全局通知。这个对话框具有比任何应用程序都要高的窗口优先权,因此它们出现在应用程序的前端。在系统事件中,一个异常是打进来的电话造成电话通信应用程序变成最前端的应用程序而把被中断的应用程序留作背景。然而,所有的系统端事件具有一个公共特征,可以被一个应用程序捕捉。当一个系统事件发生时,最前端的应用程序失去焦点。这造成应用程序用户接口类(CAknAppUI)的HandleForegroundEventL方法被调用[5]。通过覆盖这个方法,应用程序可以执行需要的动作,例如暂停正在进行的游戏。

2.2 内存限制

    在内存有限制的设备中,内存管理处于一种非常重要的地位。这关系到运行时间内存使用和最后的编译代码长度。大部分基于Symbian OS的设备只有8MB内存甚至更少。除了内存以外,这种设备只有用于预先安装的软件和用户数据区域的只读存储器,只读存储器用于安装应用程序和系统的可写入数据和持久数据文件。此外,便携式存储卡,例如小型闪存(CF)卡或者多媒体卡(MMC)[5]。

    内存使用最重要的规则是所有分配的存储器都应该在在尽可能的早期释放。Symbian OS仿真程序提供一个宏用于内存检验,默认情况下所有应用程序都有图形用户界面。如果这个宏不能释放内存,这个宏将使应用程序变混乱,这样就会出现内存泄漏。在一个目标硬件中,OS的核心记录每个线程的内存并且在线程退出的时候自动的释放它。这保证所有的内存都在应用程序退出的时候被释放。运行时间一长,应用程序和服务器可能出现一个问题。它们在结束使用它们的时候,如果它们不释放已经不需要的资源,那么就会有很多资源被系统保留起来而不能被应用程序所使用

3 声音和图像处理

3.1 声音处理

    在Symbian OS中,播放和操作声音是由媒体服务器处理的。媒体服务器支持各种声音文件格式,比如wa、au和wve,并且提供一个应用编程接口以便应用程序能够开发补充的文件格式插入式模块。媒体服务器的客户端应用编程接口被分为三个不同的接口:音频示例编辑器,音频音调播放器和音频示例播放器[2]。音频示例编辑器接口提供了高级音频操作方法,可以用来录音、编辑和播放声音。音频音调播放程序接口启动应用程序来创建和播放合成的声音。音频示例播放程序接口可用于播放样本数据文件。媒体服务器接口的使用需要在同一线程中运行一个活动的调度程序。

    对于大多数游戏来说,音频示例播放器接口提供了所有需要的特性来实现要求的音响效果。这个接口由MMdaAudioPlayerCallback和CMdaAudioPlayerUtility类组成。MMdaAudioPlayerCallback是一个mixin类,提供回调方法来通知客户端类样本的初始化或者播放已经完成。这就是为什么这个使用样本播放程序接口的类需要从mixin类中继承而来。CMdaAudioPlayerUtility类提供了加载和播放样本的方法,并且可以设置播放的音量。这个类可以仅仅和单一样本数据关联,这样一个应用程序有多少个不同的样本数据文件,它就需要创建多少CMdaAudioPlayerUtility的实例。下面的代码是使用的CMdaAudioPlayerUtility类的示例。

  ∥ 创建一个帮本播放程序并且从一个文件装入样本
  CMdaAudioPlayerUtility* samplePlayer =
  CMdaAudioPlayerUtility::NewFilePlayerL(
  KSampleFileName, *this );
  ∥ 播放样本
  samplePlayer->Play();

3.2 图像处理

    Symbian OS可以被理解为一个面向位图的操作系统[2]。Symbian OS中所有的应用程序都可以使用位图,尤其是游戏程序。虽然使用基本绘图方法(例如DrawLine和DrawEllipse)能够画出更加小型的图形,但是位图能够更有效地画屏,而且输出的图形更加细腻。

    Symbian OS有自己的位图文件格式MBM,这是一种多位图文件。窗口位图使用一个位图转化工具bmconv来创建MBM。由于一个MBM文件可能包含多个位图,所以bmconv还产生一个位图头文件MBG,这个头文件提供了一个访问位图的ID。当从MBM文件加载一张位图的时候,应该包括相应的头文件,同时应当使用恰当的标识符作为加载位图的方法的参数。位图可以在项目文件中定义:

  START BITMAP [target-file]
  HEADER
  TARGETPATH [targetpath]
  SOURCEPATH [sourcepath]
  SOURCE [colour-depth] [source-bitmap]
  END

3.2.1 子图形

    子图形是一个经过蒙板化(Mask)的位图,可以在应用程序不重画底层窗口的情况下移动。如果游戏不需要经常更新背景,那么使用子图形就再好不过了。例如类似于PacMan这样的游戏,在这种游戏中动画在一个不能卷轴并且固定的背景上移动。重画是靠窗口服务器来执行的,替代一个较高优先性的任务。这种游戏要考虑的是平滑的动画和子图形的运动。Symbian OS提供两种不同的子图形:指针和动画位图。图1说明子图形类的层次。

说明子图形类的层次图

(图1说明子图形类的层次)

    RWsSpriteBase是一个用于子图形的抽象基本类。它拥有一个或多个包含子图形的位图数据的TSpriteMembers。通过指定带有不同的位图的多个成员,子图形就可以活动起来了。TSpriteMember还定义了位图的蒙板,子图形中位图的位置和位图显示的时间间隔。RWsSprite是一个用于子图形的具体的类。除了构造器之外,它只提供一个方法SetPosition,可用于移动子图形。下面的代码说明了使用从MBM文件中装载的位图创建子图形的示例。

  RWsSprite sprite = RWsSprite( iEikonEnv->WsSession() );
  User::LeaveIfError( sprite.Construct( Window(), TPoint(0,0), 0 );
  for ( TInt i=0; i < 8; i += 2 )
  {
   iMember[i/2].iBitmap = new ( ELeave ) CFbsBitmap();
   User::LeaveIfError( member.iBitmap->Load( KBitmapFile, i, EFalse ) );
   iMember[i/2].iBitmap = new ( ELeave ) CFbsBitmap();
   User::LeaveIfError( member.iMaskBitmap->Load( KBitmapFile, i+1, EFalse ) );
   iMember[i/2].iInvertMask = EFalse;
   iMember[i/2].iOffset = TPoint(0,0);
   iMember[i/2].iInterval = TTimeIntervalMicrosecond32(100000);
   User::LeaveIfError( sprite.AppendMember( iMember[i/2] ) );
  }

    在子图形成员已经更新并且附加到RWsSprite类之后,子图形可以通过调用RWsSpriteBase::Activate来激活。在此之后,这个子图形显示在屏幕上,并且准备移动。子图形的内容可以使用RWsSpriteBase:UpdateMember方法来变化。因为CFbsBitmaps还可访问窗口服务器,所以只有子图形的位图句柄被发送到窗口服务器。这使子图形的位图的更新相当迅速。当子图形不再需要的时候,窗口服务器需要调用RWsSpriteBase::Close来释放资源。但不释放需要被删除的客户端成员数据。RWsPointerCursor是一个用于应用程序创建光标的类

3.2.2 双缓冲

    如果一个游戏的图形由多个需要被经常更新的运动对象组成,窗口服务器的客户端缓冲可能被充满并且可能会在所有对象都更新的时候溢出。用户可能会发现屏幕出现闪烁。如果一个视图仍然在更新的时候,可能会出现闪烁或者其他不希望的效果。这些问题的解决方案是双缓冲,图形先被画在一个屏外位图上,然后被画到屏幕上作为一个单一窗口服务器操作。

    尤其是对于那种在一秒钟内重画几次屏幕的游戏,使用屏外位图可以改善它们的性能。一个屏外位图可以使用位图化的图形上下文和图形设备类来创建:CFbsBitGc和CFbsBitmapDevice。它们使用其他的上下文和设备类来创建和使用。为了获得额外的性能,位图自己就应该是一个CWsBitmap位图。在屏外位图更新之后,它可以使用正常的窗口服务器的描画方法画在窗口中。

    当一个应用程序在一个窗口画位图时,它转化为和窗口相同的显示模式。这是一个很消耗时间的操作,实质上可能降低描画的速度。因此把位图用于动画的游戏应该在动画开始之前就完成转化。转化可以通过使用一个屏外位图来执行,如下面的示例方法演示:

  CFbsBitmap* CExampleControl::LoadAndConvertBitmapL(
  Const TDesC& aFileName, TInt aBitmapId )
  {
  // Load the bitmap
   CFbsBitmap* originalBitmap = new ( ELeave ) CFbsBitmap();
   CleanupStack::PushL( originalBitmap );
   User::LeaveIfError( originalBitmap->Load( aFileName, aBitmapId, EFalse ) );
   // Create a new bitmap, graphics device and context
   CFbsBitmap* newBitmap = new ( ELeave ) CFbsBitmap();
   CleanupStack::PushL( newBitmap );
   newBitmap->Create( originalBitmap->SizeInPixels(), Window()->DisplayMode() );
   CFbsBitmapDevice* graphicsDevice = CFbsBitmapDevice::NewL(bitmapConverted );
   CleanupStack::PushL( graphicsDevice );
   CFbsBitGc* graphicsContext;
   User::LeaveIfError( graphicsDevice->CreateContext( graphicsContext ) );
   TPoint zero(0,0);
  // Blit the loaded bitmap to the new bitmap
   bitmapContext->BitBlt( zero, originalBitmap );
  CleanupStack::Pop(3);
   delete bitmapContext;
   delete bitmapDevice;
   delete originalBitmap;
   return newBitmap;
  }

4 通讯体系结构

    智能电话的移动特性和通讯技术的飞跃发展决定了它们对通讯模块的需求。全世界都在使用智能电话,但是每个国家或者地区可用的通讯服务可能会有很大的差异。现有的服务和技术不断地发展,而且新的技术层出不穷。这些事实就要求智能电话通讯模块具有灵活性和扩展性,因此Symbian OS的通讯体系结构是基于这些思想来设计的。它由几个小的模块组成,并且支持可以在运行期间装载的可插入式模块。而且通讯设置可以在系统不重新启动的情况下就进行更改。

    Symbian OS的通讯体系结构基于三个通讯服务器:ETEL、C32和ESOCK[4]。服务器提供的通讯服务是异步操作,因此它们需要被封装到活动对象里。一个客户应用程序一般产生三个不同的活动对象:一个用于传送数据、一个用于接收数据还有一个用于应用程序端通讯引擎。通讯模块的关系如图2所示。
Symbian OS的通讯组件图

(图2Symbian OS的通讯组件)

    ETEL是一个电话通讯服务器,用于应用程序访问各种电话硬件和服务,例如GSM手机、模拟调制解调器和传真通讯服务。这个服务器使用可动态装载的插入式模块--电话通讯服务器模块(TSYs),把硬件特定的信息转化为应用程序可理解的格式。这个服务器的客户端应用编程接口定义在etel.h头文件中,它主要由RTelServer、RPhone、RLine和RCall类组成。

4.1 串行通讯服务器

    串行通讯服务器(C32)为它的客户端提供一个串行端口应用编程接口。这个服务器使用通讯服务器插入式模块(CSYs)处理实际的通讯协议[4]。SymbianOS提供多个CSY模块,例如处理RS232和红外线串行通讯。应用程序开发者还可以使用串行协议模块应用编程接口来开发自定义CSY模块,自定义CSY模块定义在cs_port.h头文件中。串行通讯服务器使用方法都是很相似的,不管是否使用了CSY模块。首先在初始化阶段,客户端加载所需要的驱动程序,打开服务器并且装载CSY模块。在实际的设备已经打开并且配置之后,服务器准备发送并接收数据。最后,需要释放所有的资源。串行通讯服务器的客户端应用编程接口定义在c32comm.h头文件中,主要由RComm和RCommServ类组成。下面的代码是一个红外线串行通讯初始化阶段的示例。

  // Load device drivers
  TInt err = User::LoadPhysicalDevice( _L("EUART1") );

  if ( err != KErrNone && err != KErrAlreadyExists )
   User::Leave( err );
   err = User::LoadLogicalDevice( _L("ECOMM") );
  if ( err != KErrNone && err != KErrAlreadyExists )
  User::Leave(err);
  // Start serial communications server of type RCommServ
  User::LeaveIfError( iServer.Connect() );
  // Load CSY module for IrComm
  User::LeaveIfError( iServer.LoadCommModule( _L("IRCOMM") ) );
  // Open port of type RComm
  User::LeaveIfError( iPort.Open( iServer, _L(""IRCOMM::0""),ECommExclusive ) );

    上面的示例代码可以通过加载ECUART CSY模块来从IRCOMM模式切换到RS232,同时使用COMM:0端口代替IRCOMM:0。RComm::Open中的ECommExclusive枚举防止其他的RComm客户端使用这个端口。

4.2 套接字服务器[2]

    套接字服务器(ESOCK)提供一个使用套接字的通讯协议的接口。对于所有的协议和指定协议行为,客户端应用编程接口都是相同的。套接字服务器使用TCP/IP、IrDA和蓝牙这些协议模块,它们可在运行期间动态装载。一个协议模块可能包含多个协议。例如IrDA模块可能包含原始的IrMUX、IrTinyTP、IrLAP、IrLMP和IrObex协议。对应于TSY和CSY模块的公共协议模块可以由应用程序开发者开发。

    套接字服务器的客户端应用编程接口的主要的类是RSocketServ和RSocket。可以看到它们与RCommServ和Rcomm很相像。RSocketServ处理一个服务器的会话,提供可用的协议的信息,但是不提供任何数据传送服务--它们由套接字类RSocket提供。因为客户端应用编程接口对于所有协议都是相同的,某种单一协议的属性和语义与TProtocolDesc结构是有区别的。RSocketServer::GetProtocolInfo方法可用于读取当前装载的协议的信息。套接字服务器至少需要两个不同的套接字。一个用于监听进入连接请求,另一个用于建立一个连接和传送数据。套接字服务器的客户端应用编程接口定义在es_sock.h头文件中。

4.2.1 蓝牙技术[3]

    最吸引游戏开发者眼球的套接字服务器协议是蓝牙技术。它提供了一个相对快速的、近程的解决方案,并且是免费使用的,因此很适合用于开发游戏。与红外线通讯相比,蓝牙的优势是它有更大的活动半径以及在终端之间不需要任何可见的连接

    如图3所示蓝牙由一个协议组组成。Symbian OS提供给应用程序完全访问RFCOMM、L2CAP和SDP协议的权限。RFCOMM协议模拟串行通讯,因此简化了从原有应用程序的转化为使用蓝牙技术的过程。应用程序的通常选择是使用逻辑链路控制和适应协议(L2CAP),提供给应用程序更加强大的函数来控制蓝牙连接。服务发现协议(SDP)允许应用程序查询服务和服务提供商。通常当创建一个新的连接的时候,SDP搜索要求的终端并且建立连接设置。Symbian OS还提供一个完整的用户界面组件来搜索可用的蓝牙终端。它使用Symbian OS的通知框架,在应用程序窗口上产生一个对话类型组件并且把可用的终端作为一个列表。

蓝牙堆栈图

(图3 蓝牙堆栈)

   本公司为您提供详尽解决方案的同时,根据您的实际需要,高效率为您量身定制最适合您的产品及服务,包括:蓝牙核心模块(模组)、各类半成品和成品等。联系我们

<< 返回上页

 

>>更多行业应用