Series60游戏设计参考(四)

6.9 Hardware Acceleration
S60平台2.0后(i.e Symbian OS 7.0)提供了基于硬件的2D图形硬件加速API,图形加速已经集成到已存的Graphics API,程序直接用即可。

硬件加速API是一组操作,包括硬件的加速(如一个独立的图形处理器)和软件的加速(对绘制算法的优化)。

除了现存的Graphics APIs,2D硬件加速API还有如下新的内容:
1)Hardware bitmaps(RHardwareBitmap), CFbsBitmap has been extended with CreateHardwareBitmap and HardwareBitmapHandle methods. RHardwareBitmap provides an interface to created hardware bitmap for the framework.

2)Masked, transparent, alpha blended and copy blits. (TGopBitBltMasked, TGopBitBltTransparent, TGopBitBltAlphaBitmap, TGopBitBltAlphaChannel, TgopBitBlt.)

3)Fade effects for a given area. (TGopFadeRect, TgopFadeParams.)

4)Filled polygons with solid color or pattern. (TGopFilledPolygon, TgopFilledPolygonWithPattern.)

5)Filled rectangles with solid color, pattern or bitwise operations. (TGopFilledRect, TGopFilledRectWithPattern, TgopFilledRectUsingDrawMode.)

有两个从抽象类CGraphicsAccelerator中继承的类,提供了如下的操作:
1、CHardwareGraphicsAccelerator: Provides graphics operations with a given RHarwareBitmap. The operations are implemented in hardware, software or a mixture of both ? depending on the device’s capabilities.
2、CSoftwareGraphicsAccelerator: Provides purely software implementations of graphics operations. This might be useful to implement in existing code since it allows operations to a plain non-hardware CFbsBitmap.

下面上个简单操作的例子:
void CMyGameView::MyHwBlitL(CFbsBitmap* iMySourceBitmap)

  CFbsBitmap* iMyBitmap = new (ELeave) CFbsBitmap();
  CleanupStack::PushL(iMyBitmap);
  iMyBitmap->CreateHardwareBitmap(Rect().Size(), EColor64K, KUidMyGameApp); // 16-bit color depth assumed
  // Construct hardware bitmap from the fbsbitmap
  RHardwareBitmap iMyHwBitmap(iMyBitmap->HardwareBitmapHandle());
  // Create accelerator for the hardware bitmap.
  CHardwareGraphicsAccelerator* iMyHwAccel = CHardwareGraphicsAccelerator::NewL(iMyHwBitmap);
  // Create bit blit operation.
  TGopBitBlt myBlitOperation(TPoint(0, 0), // Destination coords
  TAcceleratedBitmapSpec(iMySourceBitmap), // Source
  // Rectangle within the source to be blitted
  TRect(0, 0, 40, 40) );
  // Execute the operation; the defined area from
  // iMySourceBitmap is copied into iMyBitmap
  iMyHwAccel->Operation(myBlitOperation);
  CleanupStack::PopAndDestroy();


7 Sounds
在symbianOS中使用media server来播放和管理声音,这个media server支持各种各样的audio文件格式,如wav, au和wve,还提供给应用程序以API来为该server开发其他的文件格式插件。The media server的客户端API(在2.0中i.e Multi Media Framework)提供给游戏两个重要的特性:
1)、CMdaAudioPalyerUtility:提供了装入和播放的功能,以及设置音量,均衡等。这个类只能和一个单独的示例数据联系在一起,因此需要生成CMdaAudioPlayerUtility的实例,Playback is possible from memory via a descriptor or directly from file.要播放的audio data必须是wav, au 或RAW格式的。在s60 2.0中你可以重复使用那个实例,因为你可以在构建完后再装入一个新的文件。

2)、Audio转换,CMdaAudioConvertUtility:允许audio clips从一个格式转到另一个。

在播放上四,你需要有一个类完成MMdaAudioPlayerCallback的方法以接收回放事件:
1)MMdaAudioPlayerCallback::MapcInitComplete:当sample data已经初始化后由该framework调用,如,装入文件。
2)MMdaAudioPlayerCallback::MapcPalyComplete:当playback已经完成时。

下面的代码演示了一个使用CMdaAudioPlayerUtilty类的事例:

// Called when initialization done; e.g. sample loaded
void CmySamplePlayer::MapcInitComplete(TInt aError, const TtimeIntervalMicroSeconds& aDuration)



// Called when playback completed
void CmySamplePlayer::MapcPlayComplete(TInt aError)



void CmySamplePlayer::PlayMySampleL()

  // Create a sample player and load a sample from a file
  _LIT(KmySampleName,”MyClip.wav”);
  TFileName sampleFileName(KmySampleName);
  CompleteWithAppPath(sampleFileName);
  delete iMySamplePlayer;
  iMySamplePlayer = NULL;
  iMySamplePlayer = CmdaAudioPlayerUtility::NewFilePlayerL( sampleFileName, *this );
  // Play the sample
  iMySamplePlayer->Play();


在series60中,为应用程序的每个键都准备了个缺省的声音。声音会因为按键的长短或重复而不同。series60里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;
    }
   };


这里sound ids,SIDs,要在avkon.hrh头文件中指定,在游戏里,如果一个键可能会长时间按下,那重复的声音可以通过上面的方法来取消,就是指定这个key event's sound ID为EAvkonSIDNoSound.这是因为每次一个key repeat event被接收到后播放重复的声音都会花费一段处理时间。如果游戏中需要一个连贯的声音,那应该使用audio sample player。

8 Networking and Communication
S60为多人game提供了各种连接通讯方法,下面就是建议使用的各种方法:
1)Bluetooth - 当前最具实用性的方法,因为大部分新机器都支持蓝牙
2)TCP/IP sockets - 通过互联网,如GPRS
3)IrDA - 用的比较少,现在一般被蓝牙所替代了,有的新设备根本不提供红外的支持。

连接的速度在game中一般不是那么要求严格的,因为要传输的数据量很小(通常game的状态不会耗费多少空间,如对象的位置),上面所说的几种方法都能提供很好的连接方式。

8.1 Designing Communication Framework
要开完成多人game,你必须设计一个框架,它选择了某种网络方式。For all networking methods ? Bluetooth, TCP/IP and IrDA ? a common, single design pattern can be used by utilizing Active Objects.

联网需要多个active object来提供异步的操作,通常游戏中一个比较简单的、同步的操作是不可能的,or not desired due to blocking of execution.典型的联网结构需要使用3个活动对象:
1)Reader
处理传进来的数据并将它传递到Controller,这时不需要分解数据(only low level protocol parsing, if any)。

2)Writer
处理输出的数据,由Controller将数据传递到网络(only low lever parsing)

3)Controller
在设备之间建立连接,拥有并使用Reader和Writer来传递数据-提供high level protocol implementation,那就是数据怎么样被传输,以及按什么样的格式被传输。

这三个活动对象通常都包括它们自己的状态机制,而Controller可以包括多个状态机制,以用来提供各种不同的连接状态(connecting, connection established, sending data, receiving data)以及传输状态(data block 1 send, ack received, data block 2 sent, expecting reply, response received)。Usually the communication between the devices in games is simple, and does not require a transaction state:
1)、Device 1 sends data to Device 2 in a single block
2)、Device 2 sends data to Device 1 in a single block. (这个可能为前一个消息的回应,Device 1实际上并不是在等待回应,只是在一个消息被收到时的反应。)

game engine using the networking owns the Controller, and communication between the engine and the Controller is done typiclly via callback mechanism. Controller应该提供一个简单的接口,而用户对Controller的内部机制功能并不需要知道太多。

如果是使用Bluetooth/IrDA的话,那么完成一次最简单的联网只要四个方法:
1)CmyController::SeekDevice
寻找Bluetooth/IrDA的设备并通过callback得到可用设备的列表。
2)CmyController::ConnectToDevice
连接到给应的设备上,通过callback来通知连接成功或失败。
3)CmyController::SendMessage
通过连接远程设备来发送message(data)
4)CmyController::Disconnect
和远程设备断开

对TCP/IP来说SeekDevices并不需要,但是其他的都是一样的。

所有上面的方法,除了Disconnect,都是异步的,而Controller会通过callback将结果传递会game engine.
1)MmyController::Event
a general notification of an error(connection failed), success(connected ok) or just informaional(for displaying the progress of the current operation, such as connection attempt). The controller应该从错误中尝试恢复。而这个事件只是用来通知用户和game engine,尽量的要简单直接。game engine对连接的controller应该尽量的所知甚少。

2)MmyController::MessageReceived
一个信息从远程设备中获取(如游戏状态),The message is parsed by the Controller and then passed to game engine with this callback.

Bluetooth, IrDA, TCP/IP都可以通过一般的socket client API(RSocket)来使用:
1)Bluetooth sockets API provides communication over L2CAP and RFCOMM layers, and provides discovery of Bluetooth devices.
2)IrDA sockets API, with IrMUX and IrTinyTP protocol sets. By using IAS, you can create service announcements/queries and even communicate with Windows OS based devices.
3)TCP/IP sockets provide domain name resolutions, Ipv4, and in Series 60 Developer Platform 2.0, Ipv6.

8.2 Game Data Receiving
有时候需要,如在游戏安装后更新和添加新的关卡。这时需要的文件可以通过email,或IrDA甚至MMS来获得。在S60中,我们可以将该文件的类型注册,这样获得的文件就可以自动的进入正确的目录,一边游戏能找到它们。

为了使game支持额外的game data,S60开发平台允许第三方游戏使用Multipurpose Internet Mail Extensions, MIME类型将他们的数据文件格式到系统中,MIME类型被一些连接程序所使用,象WML浏览器和消息应用程序,为了找出一个文件的路径,必须要存储特定的类型,这样的文件可以存放新的关卡,武器或游戏图片。

在S60中游戏的MIMI类型格式为:application/x-NokiaGameData-<APPLICATION-ID>,这里<APPLICATION-ID>是game的symbian OS application UID的最后8位。这个MIME类型可以放在symbian OS应用程序信息文件,aif文件中描述:
RESOURCE AIF_DATA

  app_uid=0x12345678; // Application UID
  datatype_list =
 {
   DATATYPE
   {
     priority = EdataTypePriorityHigh;
     type = “application/x-NokiaGame-Data-12345678”;
    }
  };

这里DATATYPE中的优先级指明了当前应用程序是如何处理数据格式的。EdataTypePriorityHigh should be used for data formats which can not be handled by other applications.

接受到的数据文件的目标路径应该在<APPLICATION-ID>.ini中找到。这个文件需要以unicode格式来存储。它包括SDDataDir=<GAME-PATH>,这里<GAME-PATH>是文件的接收路径。The path is relative to the default game data directory, c:/nokia/games,当游戏安装后,ini文件需要拷贝到/System/ShareData目录下,这个可以通过在pkg文件中指定路径来处理。

这里Series60开发平台指定了一个standard header structure for game data files,它需要加入到MIME类型中才能工作。The Data type field can be used to specify the type of a file that is internal for the game. Name String是一个unicode string,可以使用户在菜单中选择数据的项目。数据的ID和数据的版本都是唯一的数字,可以指定文件数据的类型和版本号。The NGDX字段必须包括ASCII字符

串"NGDX"
(见Figure 8图)


9 安装
9.1 应用程序信息文件
应用程序的图标是任何应用程序在安装后第一个可见的部分,这个icon定义在AIF中,应用程序信息文件为应用程序定义了如下的特性:
1)Application icon
2)程序在系统shell中是否可见
3)程序是否和指定的MIME类型联系在一起
4)应用程序是否可以在system shell中生成新的文档
5)应用程序是内嵌的吗

AIF文件可以定义在工程的mmp文件:
aif MyGame.aif /MyGame/aif MyGameAif.rss c8 Icon1.bmp Icon1Mask.bmp
语法为:
aif <applications aif file> <aif file location> <aif resources> <icon bit depth> <icon 1> <iconmask 1> <icon2> <iconmaks2>

...

一个应用程序可以有多个图标以适应不同的场合,system shell会自动选择合适尺寸的icon进行必要的显示。一般application的icon尺寸为44x44,8-bit color,此外你可以提供其他的icon.

为aif准备的资源文件rss看起来如下:
#include <aiftool.rh>
RESOURCE AIF_DATA

  // application uid
  app_uid=0x1000ABCD;
  // Application caption for each language
  caption_list=
  {
    CAPTION
    {
       code = ElangEnglish;
       caption = “MyGame”;
     }
   };
// Datatypes associated with the application
 datatype_list =
 {
    DATATYPE
    {
      priority = EdataTypePriorityHigh;
      type = “application/x-NokiaGame-Data-12345678”;
    }
   };
  // Number of icons in AIF (does not include masks; each icon must
  // have a mask)
  num_icons=1;
  // Capabilities
  embeddability = KappNotEmbeddable;
  hidden = KappNotHidden;
  newfile = KappDoesNotSupportNewFile;


如果你的程序包括一个aif,那你记得把那个生成的文件放入到sis package中,注意如果AIF的UID和你的应用程序的UID不匹配,那不会显示任何错误,但是安装后生成的应用程序的图标将是不可见的。

9.2 Installation File
pkg file定义了安装文件(sis)的内容,它包括应用程序的UID,一个支持的语言列表,目标产品的UID和打包在sis的一组文件:
; MyGame.pkg
; Specifies an installation file for MyGame
;Languages
&EN
;Header
#,(0x1000ABCD),1,0,0
; Required line for Series 60 devices. Defines the target product
; UID.
(0x101F6F88), 0, 0, 0,
“/epoc32/release/thumb/urel/MyGame.app”-“!:/system/apps/MyGame/MyGame.app”
“/epoc32/release/thumb/urel/MyGame.rsc”-“!:/system/apps/MyGame/MyGame.rsc”
“/epoc32/release/thumb/urel/MyGame.mbm”-“!:/system/apps/MyGame/MyGame.mbm”
“/epoc32/release/thumb/urel/MyGame.aif”-“!:/system/apps/MyGame/MyGame.aif”
“../MyGame/MyGameSample.wav”-“!:/system/apps/MyGame/MyGameSample.wav”

Product UID定义了应用程序的目标环境,大部分的s60版本是向下兼容的。
参见下表:
(Figure 9.1)


如果程序需要依据各不同的平台来进行安装,那就可以使用条件语句块来处理,这时pkg里的语句如下:
;
; Files to install
;
IF MachineUID=0x101fb3dd
; Nokia 6600 specific files
“../MyFiles/FileFor6600.dat”-“!:/system/apps/MyGame/MyData.dat”
ELSEIF MachineUID=0x101f466a
; Nokia 3650 specific files
“../MyFiles/FileFor3650.dat”-“!:/system/apps/MyGame/MyData.dat”
ELSE
; Files for other devices
“../MyFiles/FileForOthers.dat”-“!:/system/apps/MyGame/MyData.dat”
ENDIF

如上的使用你就可以生成一个支持多平台的安装文件,除了机器UID外,还有很多属性,如内存和CPU的标识:

注意,机器UID和Product UID是不同的,见下:
(Figure 9.2)


可以使用如下的代码来找出该设备的机器UID:
#include <hal.h> //and link with hal.lib
TInt machineUid = 0;
HAL::Get(HALData::EmachineUid, machineUid);

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值