Symbian 中基本的[位图,声音,计时器,按键事件]处理

位图

由于游戏的图形特性,位图经常占用大量的内存使用量。 这应用于随机存取存储器和用户数据区域使用量。 有助于减少使用量,而不减少位图的数目的最有效的方法是减少它们的颜色数。 Symbian OS支持16777216种颜色的24位位图,但是实际的最大颜色数受目标硬件限制。 这就是为什么所有的位图都不应该转化为比硬件设置最大颜色数更高。 小型的低细节的不需要许多颜色的位图,应该参考上的规则转化为比最大颜色数要低的颜色数。 例如8位颜色适合于大多数的子图形。 而所有的mask都应该被转化为1位的位图。

 

计时器

  对于大多数游戏来说,计时是必不可少的。 系统端提供的计时服务用于各种目的。 在更复杂的游戏中,游戏的场景经常更新,并且用户的输入在一秒中被读很多次。 在更简单的游戏中,计时被用于处理游戏玩家的回合或者评估一个游戏玩家是否成功的解决一个给定的问题等等。 大多数的游戏都需要来自系统的计时支持。

  在Symbian OS中,最不足的服务之一就是计时服务。 OS不支持低级计时中断,它只提供一个有最大频率为64 Hz的核心端计时器。 相同的时钟频率还被用于线程的循环调度。 仿真程序环境中,最大时钟频率是10 Hz,这会导致游戏的测试出错。 系统的最大时钟频率可以使用UserHal::TickPeriod方法访问,是用一种平台无关性的方法来给出时钟周期。 这个方法在e32hal.h头文件中被引用。 图3.1是Symbian OS计时器类的类图。


图3.1 Symbian OS计时服务的类图

  核心端计时器可以使用RTimer类取得,这是一个到系统端服务器的操作。 它提供一个简单的应用编程接口来请求三个不同的计时事件:一段给定时间之后的事件,给定时间的事件和一个完成一秒钟的给定分段的事件。 这个应用程序编程接口需要TRequestStatus作为一个参数被传送进去,交付给应用程序开发者来使用活动对象作为事件处理程序。 为了简化RTimer的使用,Symbian OS提供一个抽象活动对象CTimer,封装了RTimer的使用。 这可以使用一个简单的封装完成,应用程序开发者需要从CTimer中派生出这个类,然后覆盖当一个请求完成时被调用的RunL方法。 然而,由于在计时服务中使用了活动的对象,真实计时事件处理可能延迟。 当一个计时器请求完成的时候,另一个活动的对象可能已经被执行,并且正在处理这个记时事件的活动的对象直到另一个活动的对象结束它的RunL的时候它才会被列入计划。 这虽然不可避免,但是对于计时精度的影响可以通过让所有的RunL方法尽可能短时间运行来达到最小化。 如果另一个带有更高优先权的活动对象被列在前面的话,这个事件处理可能还是会被延迟。 这可以通过使处理计时事件的活动对象比其它活动对象具有更高的优先权来避免。

  Symbian OS还提供两个CTimer导出类来重复的进行计时事件:CPeriodic和CHeartbeat。这两个类都在一个事件发生时调用一个回调方法。 对于CPeriodic,事件的间隔可以以微秒给出,而对于CHeartbeat来说,事件的间隔仅仅以秒划分,这两个类都是被TTimerLockSpec枚举定义的。 最小的分数是十二分之一。 在CPeriodic中,给定的间隔近似到最接近的系统计时分辨率。 CHeartbeat提供了一个方法来使计时器与系统计时器同步。 如果错过了一个或多个记时事件,那么它的回调方法Synchronize将被调用,并且使用这种方法,它可以提供一个应用程序执行必要的恢复动作的可能性。 上面提到的计时类可以从e32std.h和e32base.h头文件中找到。

 

按键事件处理

  Symbian OS是一个事件驱动系统--所有的应用程序和服务器都可以被看作为事件处理程序。 象按键事件这样的事件都是被活动对象操作的,使事件处理非抢先式计划。 一个用户按下一个键的事件流程的示例如图3.2所示。


图3.2按键事件流程

  当一个用户按下一个按键时,键盘硬件生成一个中断,被键盘驱动程序捕获。 在分解按键事件之后,驱动程序把它发送到一个称为窗口服务器的系统端线程中。 窗口服务器发送事件到窗口群具有焦点的应用程序中。 这是使用一个控制环境( CONE)来实现的,这是一个介于窗口服务器和用户界面库之间的应用编程接口。 CONE和窗口服务器在第四章中做出了解释。

  在应用程序端中,按键事件是在窗口服务器调用的OfferKeyEventL方法处理的。 每按下一个键就会生成三个单独的事件。 第一个事件是EEventKeyDown,这是当一个键被按下的时候生成的。 然后是EEventKey,当键被松开的时候生成了EEventKeyUp事件。 这些事件类型是被TEventCode枚举定义的,被传送到OfferKeyEventL作为第二个参数。 第一个参数是一个结构(struct)TKeyEvent,指定关于事件的更详细的信息。 如果一个键按下的时间长于0.8秒,窗口服务器发送另一个EEventKey事件到应用程序,长时间按键事件。 如果这个键按下的时间比这个还长,那么窗口服务器每隔0.25秒钟发送一次按键重复事件。 这些时间帧对于Series 60来说是缺省值,它们可以被应用程序修改。

  TKeyEvent有一个成员变量iRepeats,用于从按键重复事件中分离出长时间按键事件。 一旦这个变量不为零,应用程序必须知道当最后一次按键事件被接收的时候这个值为多少。 如果最后的事件的iRepeats等于零,那么一个长时间按键事件就被接收,而如果不为零的话,就接收一个按键重复事件。 iRepeats变量是一个32位带符号整数,定义了自从最有一次处理的事件之后定义的事件数。 因为大部分的案件事件在某个地方被处理,所以这个变量不定义自从第一个按键事件之后的实际重复数。 如果它们想知道键到底被按下去多长时间,这就是为什么应用程序需要它们自己计算重复的次数。 TKeyEvent和TEventCode的定义可以在w32std.h头文件中找到。

  经常需要按键事件的游戏应该设置它们自己的按键重复率。 按键重复期间可以使用窗口服务器的带有两个参数的SetKeyboardRepeatRate应用编程接口来更改。 第一个参数在第一次按键重复事件之前指定时间,这相当于一个长时间按键事件,而第二个参数指定后继按键重复事件之间的时间。 设置时间框相等产生了一个线性的重复速度,也就是说第一次按键事件和后续按键事件之间的时间框相等。 因为重复速度是全系统范围的设置,所以它们应该在另一个应用程序进入前台的时候被改回默认值。

  默认情况下,在Series 60中大部分的按键被阻塞;仅有电源键和编辑键是非阻塞按键。 无论如何,按键覆盖对于游戏来说是非常重要的,因为游戏中往往需要用户能同时按下两个键。 这就是为什么Series 60提供能用于禁止按键阻塞的应用编程接口。 应用程序用户界面的基本类CAknAppUi提供SetKeyBlockMode方法,可用于禁止按键阻塞。 这个应用编程接口接受一个TAknKeyBlockMode枚举作为一个参数,这个枚举可以有两个可能的值:EDefaultBlockMode和ENoKeyBlock。 按键覆盖也是一个全系统的设置,应该在游戏不在前台的时候被恢复到缺省值。

 

声音

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

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

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

  在Series 60中,每个应用程序对于每个键都有一个默认的声音。 这个声音还可以取决于这个按键事件是否是短时间、长时间或者重复按键。 Series 60应用程序用户界面类CAknAppUi提供对应用程序在资源文件中指定它们自己的按键声音效果的支持。

RESOURCE AVKON_SKEY_LIST r_example_skey_list
{
list =
{
AVKON_SKEY_INFO { key=EStdKeyLeftArrow;
sid=EAvkonSIDNoSound;},
AVKON_SKEY_INFO { key=EStdKeyLeftArrow;
sid=EAvkonSIDNoSound;
type=ESKeyTypeLong;},
AVKON_SKEY_INFO { key=EStdKeyLeftArrow;
sid=EAvkonSIDNoSound;
type=ESKeyTypeRepeat;}
};

  可用的声音标示符SIDs在avkon.hrh头文件中指定。 在游戏中,如果一个键被长时间按下,重复声音应该通过指定这个按键事件的声音标识符为EAvkonSIDNoSound来禁止。 这是因为每当一个按键重复事件接收的时候播放重复声音会消费大量处理时间。 如果一个游戏需要连续的声音,应该使用音频样本播放器来代替。

你可能感兴趣的:(Symbian 中基本的[位图,声音,计时器,按键事件]处理)