bada 2D游戏编程之十——关键帧动画原理

bada 2D游戏编程之十——关键帧动画原理 html

 

前面提到的逐帧动画有一个关键的缺点就是须要为动画中的每一帧都提供一张单独的图片,因为每一帧的图片都须要单独提供,制做起来比较麻烦,图片量也比较大。用关键帧动画能够很好的解决这个问题,下面就给你们进行讲解bada平台的关键帧动画。 编程

 

1, 什么是关键帧动画 api

关键帧动画的原理是只须要提供一张图片(或者对象),而后对这张图片(或者对象)进行处理产生出不一样的效果,例如进行放缩处理产生出大小不一样的效果,还有进行透明度处理产生出透明度不一样的效果等,连续播放处理出来的效果就造成了动画。ide

每每这种处理的效果有限,只能进行一些常规的处理,如改变大小、透明度、位置、角度等,因此关键帧动画不适合表现复杂的变形,例如在逐帧动画中提到的描述一株向日葵从苗芽状态成长到绽开花朵的过程动画就不能用关键帧动画来完成,由于这个动画中的效果不是仅仅经过变形就能实现的,而是须要对图片中内容的改变,这种状况下就只有采用逐帧动画了。函数

下面给你们描述如何用一张图片来实现一个动画。动画

这是提供的一张金鱼的图片,this

 

而后用关键帧动画来实现这条金鱼从小长到大的变化过程,spa

 

 

 

这个动画就是对提供的图片进行大小的改变来实现的,不须要对每一个大小的图片都提供一张图片,中间图片的产生交给系统去处理,节省了不少的工做量。3d

 

2, 相关概念 orm

关键帧动画是对图片(或者对象)的属性值进改变,通常能够改变的属性为大小、透明度、位置坐标和旋转角度等,这样来理解的话,关键帧动画也能够称为属性动画。下面要介绍的这些概念都是和属性值相关的:

开始值:起始帧中的的属性值;

结束值:结束帧中的的属性值;

关键值:在起始帧和结束帧之间产生的属性值,这些值都是按照必定的方式计算出来的;

持续时间:动画持续的时间;

关键帧:开始值和结束值表示的帧都称为关键帧;

过渡帧:关键值表示的帧称为过渡帧;

插值器:能够理解为关键值产生的计算方式;

 

3, 相关类

在关键帧动画中最重要的是如何获得关键值,由于关键值得依靠各类复杂的计算来获得。bada在这方面提供了为开发者提供了很大的帮助,来帮助开发者很方便的获取关键值。

 

3.1 属性动画

下面的这些属性动画都是用于模拟从一个属性值变化到另外一个属性值的变化过程的,都提供了GetAnimatedValue ()或者其它函数来根据时间获取属性值。这样将获得的属性值做为帧属性进行播放就能够造成动画了。

功能说明

IntegerAnimation

用于计算整数型的属性值,如用于计算旋转角度属性值

FloatAnimation

用于计算浮点型的属性值,如用于计算旋转角度属性值。能够获得浮点值,更加精确

PointAnimation

用于计算位置属性

DimensionAnimation

用于计算大小属性

RectangleAnimation

用于同时计算位置和大小属性

RotateAnimation

用于计算旋转角度属性

这些类均可以经过传入开始值、结束值、持续时间和插值器来进行初始化。

 

3.2 插值器

插值器定义了属性值的计算方式,可以让关键值呈必定的规律进行变化。这种变化最终体如今动画的播放速度上,能够产生匀速播放、加速播放和减速播放等各类效果。

其实改变更画的播放速度有两种方式,第一种是在动画中各帧的属性值保持不变的状况下去改变帧的持续时间,如原有每帧的持续时间是40ms,先进将这值改成20ms,这样播放速度就明显加快了;第二种就是在保持原有动画中各帧持续时间不变的状况下去改变各帧的属性值,将属性值变的更大或者更小,这样也能产生加速或者减速的效果。

插值器就能够帮助开发者经过第二种方式来实现各类动画效果。它可以让动画帧的属性值与时间成各类线性关系。

如线型插值器,属性值随时间均匀变化。这样在相同的时间间隔内去取属性值的话,获得的增量都是相同的。因此动画也是表现出匀速播放。

如这种曲线关系,在相同的时间间隔内去取属性值的话,刚开始获得的值之间变化较小,越日后获得的值的变化愈来愈大,则表如今动画的播放速度是从慢到快的。

 

 

 

下面是bada提供的插值器类型:

类型

功能说明

ANIMATION_INTERPOLATOR_LINEAR 

属性值按照线性规律变化,动画播放则表现为匀速播放。

ANIMATION_INTERPOLATOR_DISCRETE 

属性值在最后一帧时才发生变化,表如今动画上则是前段时间不变,最后忽然发送一下变化。能够用于实现那种突隐突现,来回闪烁的效果。

ANIMATION_INTERPOLATOR_EASE_IN 

属性值变化先小后大,动画播放则表现为先慢后快。

ANIMATION_INTERPOLATOR_EASE_OUT 

属性值变化先大后小,动画播放则表现为先快后慢。

ANIMATION_INTERPOLATOR_EASE_IN_OUT 

属性值变化前期是先小后大,后期先大后小,动画播放则是由慢到快,再由快到慢。

ANIMATION_INTERPOLATOR_BEZIER 

这个是按照贝塞尔曲线变化,能够实现进行自定义变化。

 

4, 实例

接下来用代码实现前面的金鱼由小变大的例子。

Step 1,准备动画图片

只须要准备一张图片就能够了。图片的尺寸为134×105像素。

 

 

Step 2,解析图片

将图片解析成系统支持的位图。

AppResource* pAppRes = Application::GetInstance()->GetAppResource();

__pFishBmp =  pAppRes->GetBitmapN("fish.png");

 

Step 3,建立属性动画

建立尺寸属性动画,用于改变长度属性值。动画的初始值为提供的原始图片的1/3,结束值为原始图片的2倍,动画持续的时间为1秒,采用的是线性插值器。

__pFishAni = new DimensionAnimation(Dimension(134/3,105/3),

Dimension(134*2,105*2),1000,ANIMATION_INTERPOLATOR_LINEAR);

 

Step 4,获取属性值

结合咱们前面的文章用到的模块代码,采用“基于时间的固定间隔游戏循环”,只须要在UpdateLogic(int frameInterval) 函数中,根据时间值去获取属性值就能够了。

    __aniDuration = __aniDuration + frameInterval;

    if(__aniDuration <= 1000)

    {

       __pFishAni->GetAnimatedValue(__aniDuration, __aniDimension);

    }

    else

    {

       __aniDuration = 0;

    }

 

Step 5,绘制图片造成动画

FormOnDraw()函数中根据获得的属性值去进行绘制。

    Canvas* pCanvas = this->GetCanvasN();

    pCanvas->SetBackgroundColor(Color::COLOR_WHITE);

    pCanvas->Clear();

    pCanvas->DrawBitmap(Rectangle(100,100,__aniDimension.width,

__aniDimension.height), *__pFishBmp);

 

    delete pCanvas;

 

这样在游戏状态的更加接口Draw()函数中调用RequestRedraw()去请求更新,而后OnDraw()函数不断的被调用来进行从新绘制就造成了动画。