Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3510153
  • 博文数量: 1450
  • 博客积分: 11163
  • 博客等级: 上将
  • 技术积分: 11101
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-25 14:40
文章分类

全部博文(1450)

文章存档

2017年(5)

2014年(2)

2013年(3)

2012年(35)

2011年(39)

2010年(88)

2009年(395)

2008年(382)

2007年(241)

2006年(246)

2005年(14)

分类: C/C++

2009-08-04 14:01:12

Symbian OS关于动画的绘制和处理基本上分为两大类,一类是客户端应用程序动画框架,一类是Window Server的插件动画。在介绍这两种动画前,我们先简单介绍一下精灵(sprite)的概念。

 

精灵(sprite

精灵(sprite)是Window Server的概念范畴,Window Server支持两种类型的精灵,一种是常用的精灵-sprite,一种是用来作为光标(pointer cursor)。精灵是任意形状的位图,其在移动时无需程序对其后面的屏幕进行重画。Window Server之所以提供光标(pointer cursor)的支持,是因为在使用鼠标、手写笔时可以象使用一个指针设备(pointer device)一样有效。

 

Symbian OS中,RWsSpriteBaseRWsSpriteRWsPointerCursor这几个类实现了精灵相关的操作。下图的类图他们之间的关系:

 

 

 

一个精灵有一个或多个精灵成员组成,每个成员包含一个位图图片和一个现实图片的时间间隔。多个成员非别包含不同的图片按顺序已设定的时间间隔显示即可实现动画效果。RWsSpriteBase类实现了添加精灵成员、更新精灵成员等操作,RWsSprite类用来构造精灵sprite对象,RWsPointerCursor类用来构造精灵Pointer cursor对象。

 

应用程序使用精灵通常是以下几步:

l         RWsSprite::Construct来构造一个RWsSprite对象。

l         用位图(CFbsBitmap对象)构造精灵成员(TSpriteMember),并设置播放时间间隔。

l         RWsSpriteBase::AppendMember()一次添加精灵成员。

l         调用RWsSpriteBase::Activate()激活精灵。

 

精灵的显示位置可以在构造是制定,也可以在激活后使用RWsSprite::SetPosition()来设置。还可以通过RWsSpriteBase::UpdateMember来更新成员。Pointer Cursor的使用与sprite的类似。

 

插件动画(CAnim/RAnim

 

这种类型的动画运行在Window Server定义的框架下。要实现这种动画效果需要实现系统定义的多态动态库,这个动态库是Window Server的插件,运行在Window Server的高优先级线程中而不是应用程序的线程中,动画的显示内容及如何显示都在这个插件里实现。同时还需要在Window Server客户端做些工作,来实现对动画插件的加载和动画控制。下面分别介绍如何实现服务端和客户端。

 

服务端实现

 

服务端的实现实际上就是动态库的实现。这个动态库必须定义构造动画的类厂,因为你可以实现窗体动画(window animation),也可以实现精灵动画(sprite animation),你可以通过这个类厂来构造你想要的动画。同时这个动态库必须在其第一个导出函数中实现构造这个类厂。系统提供了一个虚基类CAnimDll,你可以从它派生一个自己的类,实现其CreateInstanceL接口即可。下面的代码显示了如何实现这个类厂:

 

//DLL第一个导出函数,构造类厂

EXPORT_C CAnimDllCreateCAnimDllL()

{

    return new(ELeave) CAnimDllExample;

}

 

class CAnimDllExample : public CAnimDll

{

Public:

    CAnim* CreateInstanceL(Tint aType)

{

CAnim *anim=NULL;

  switch(aType)

  {

  case EKWindowAnim:

     //create window animation;

     anim= new (ELeave) CWindowAnimExample;

     break;

  case EKSpriteAnim:

     //create sprite animation

     anim=new (ELeave) CSpriteAnimExample;

     break;

  case EKFreeTimerWindowAnim:

     //create freetimer animation

     anim=new (ELeave) CFreeTimerWindowAnimExample;

     break;

  }

return anim;

}

};

 

上面例子中的类CWindowAnimExampleCSpriteAnimExample以及CFreeTimerWindowAnimExample,最终都是从CAnim派生而来,但不是直接从它派生。CAnim这个类是一个抽象类,它定义了被Window server调用的接口CommandReplyL  Command。(当客户端调用RAnim::Command  RAnim::CommandReply时,Window Server会自动调用CAnim::CommandCAnim::CommandReply,下面将客户端实现是会讲到这点。)客户端通过向Window Server发送命令来控制动画。下图显示了Symbian OS提供的动画类图:

 

 

 

上面的代码例子中的CWiundowAnimExample就是从CWindowAnim派生,CWindowAnim也是虚基类,所以你必须从其派生自己的类,并实现其定义的接口(重写其定义的纯虚函数)。CSpriteAnimCFreeTimerWindowAnim也都是虚基类,你必须派生并实现自己的类。

 

注意:无论是动画的类型,还是客户端与服务端的控制命令,都是由你自己来定义。

 

客户端实现

 

对于客户端的实现,Symbian OS 提供了RAnim/RAnimDll两个类,RAnimDll类用来加载和卸载你实现的动画插件,RAnim类通过Command/CommandReply方法实现对动画的控制。在使用RAnim类操作动画之前,你必须已经使用RAnimDll成功加载了动画插件。

 

加载动画插件时,使用RAnimDll::Load方法,卸载时调用RAnimDll::Close方法。当Server收到RAnimDll::Load请求时,会加载指定的Dll动画插件,并调用其第一个导出函数创建动画类厂(具体到上面的例子中,即调用CAnimDllCreateCAnimDllL()函数)。

 

当动画插件成功加载后就可以使用RAnim类提供的方法对动画进行操作了。需要说明的一点是RAnim也是一个抽象类,你需要从其派生自己了类,这里我们就用RAnim类来说明。

 

RAnim类在构造对象时,调用RAnim::Construct,这个方法有多个重载,分别用来构造窗体动画和精灵动画。当Server收到RAnim::Construct这个请求时,会调到CAnimDll:: CreateInstanceL(具体到上面例子,会调到CAnimDllExample:: CreateInstanceL,通过你传入的type参数来决定构造那类动画。

 

当你的动画对象也构造好后,动画就可以显示了。在动画显示过程中,你可以向Server发控制命令,如果你使用RAnim::Command,当Server收到这个请求时,会调用CAnim::Command具体到上面例子,会调到CWindowAnimExample::Command);如果你使用RAnim:: CommandReply,当Server收到这个请求时,会调用CAnim::CommandReply(具体到上面例子,会调到CWindowAnimExample::CommandReply)

 

到此为止,你就基本完成了这个动画的实现了,至于你怎么控制动画,实现什么样的动画效果,就看你怎么实现动画插件中的动画了,这完全取决于你自己。

阅读(493) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~