初识cocos2dx动作和动画

动作和动画

  • 关于动作
  • 关于动画
    • 动画缓存
    • 骨骼动画详解-Spine

关于动作

动作类(Action)
动作类(Action)是所有动作的基类,它创建的一个对象代表一个动作。动作作用于Node,因此每个动作都需要由Node对象执行。动作类(Action)作为基类,实际上是一个接口,动作类的大多数实现类都派生于有限时间动作类(FiniteTimeAction)。

在实际开发中我们通常用到两类动作-即时动作和持续动作,它们均继承于有限时间动作类。

即时动作类
	auto placeAction = Place::create(Point(10, 10));
	Place:该动作用于将节点放置到某个指定位置,其作用与修改节点的position属性相同。

	auto flipxAction = FlipX::create(true);
	auto flipyAction = FlipY::create(true);
	FlipX和FlipY:这两个动作分别用于将精灵沿X轴和Y轴反向显示,其作用与设置精灵的FlipX和FlipY属性相同,将其包装成动作是为了便于与其他动作进行组合。

	auto hideAction = Hide::create();
	auto showAction = Show::create();
	Show和Hide:这两个动作分别用于显示和隐藏节点,其作用与设置节点的visible属性作用一样。

	auto actionMoveDone = CallFuncN::create([&](Ref* sender){
        log("Clear memory");
    });
    auto moveTo = MoveTo::create(0.4f, Point(0, 0));
    auto action = Sequence::create(moveTo, actionMoveDone, NULL);
	CallFunc系列动作包括CallFunc、CallFuncN两个动作,用来在动作中进行方法调用。在游戏中为了节约内存资源,我们可以在动作完成后调用相应函数清理内存。

持续动作类
    MoveTo::create(float duration, const Point& position);
    MoveBy::create(float duration, const Point& position);
	MoveTo和MoveBy:用于使节点做直线运动,设置了动作时间和终点位置,在规定时间内会移动到终点。

    JumpTo::create(float duration, const Point& position, float height, int jumps);
    JumpBy::create(float duration, const Point& position, float height, int jumps);
	JumpTo和JumpBy:使节点以一定的轨迹跳跃到指定位置。

    ccBezierConfig bezier;
    bezier.controlPoint_1 = Point(0, 0);
    bezier.controlPoint_2 = Point(100, 100);
    bezier.endPosition = Point(50, 100);
    auto bezierAction = BezierTo::create(0.5f, bezier);
    BezierTo和BezierBy:使节点进行曲线运动,运动的轨迹由贝塞尔曲线描述。每条贝塞尔曲线都包含一个起点和一个终点。在一条曲线中,起点和终点各自包含一个控制点,而控制点到端点的连线称作控制线。控制点决定了曲线的形状,包含角度和长度两个参数
    使用时,我们要先创建ccBezierConfig结构体,设置好终点endPosition以及两个控制点controlPoint_1和controlPoint_2后,再把结构体传入BezierTo或BezierBy的初始化方法中。

    ScaleTo::create(float duration, float s);
    ScaleBy::create(float duration, float s);
	ScaleTo和ScaleBy:产生缩放效果,使节点的缩放系数随时间线性变化。

    RotateTo::create(float duration, float deltaAngle);
    RotateBy::create(float duration, float deltaAngle);
	RotateTo和RotateBy:产生旋转效果。

    FadeIn::create(float d);    淡入
    FadeOut::create(float d);    淡出 
    FadeTo::create(float duration, GLubyte opacity); 一定时间内透明度变化
	FadeIn, FadeOut和FateTo:产生淡入淡出效果,和透明变化效果。

    TintTo::create(float duration, GLubyte red, GLubyte green, GLubyte blue);
    TintBy::create(float duration, GLubyte red, GLubyte green, GLubyte blue);
	TintTo和TintBy:设置色调变化,这个动作较少使用。red, green, blue的取值范围为0~255。

 	Blink::create(float duration, int blinks);
	Blink:使节点闪烁,其中blinks为闪烁次数。


复合动作类
	DelayTime::create(float d);
	DelayTime:延时动作其实什么都不做,提供一段空白期,d表示需要延时的时间。

    Repeat::create(FiniteTimeAction *action, unsigned int times);
    RepeatForever::create(ActionInterval *action);
	Repeat/RepeatForever:反复执行某个动作。

    Spawn::create(FiniteTimeAction *action1, ...);
    Spawn::create(const Vector<FiniteTimeAction*>& arrayOfActions);
	Spawn:使一批动作同时执行。

    Sequence::create(FiniteTimeAction *action1, ...);
    Sequence::create(const Vector<FiniteTimeAction*>& arrayOfActions);
	Sequence:让各种动作有序执行。

变速动作类
    auto repeat = RepeatForever::create(animation);
    auto speed = Speed::create(repeat, 0.5f);
    sprite->runAction(speed);
	Speed:用于线性的改变某个动作的速度,为了改变一个动作的速度,首先需要将目标动作包装到Speed动作中,第二个参数为变速比例,设置为0.5f则速度为原来一半。

    auto sineIn = EaseSineIn::create(action);
    sprite->runAction(sineIn);
	ActionEase:Speed虽然能改变动作的速度,但是只能按比例改变速度,ActionEase可以实现动作的速度又快到慢、速度随时间改变的匀速运动。该类包含5类运动,指数缓冲、Sine缓冲、弹性缓冲、跳跃缓冲和回震缓冲。每类运动都包含3个不同时期的变换:In、Out和InOut。

关于动画

序列帧动画(Animation)
Cocos2d-x中,动画的具体内容是依靠精灵显示出来的,为了显示动态图片,我们需要不停切换精灵显示的内容,通过把静态的精灵变为动画播放器从而实现动画效果。动画由帧组成,每一帧都是一个纹理,我们可以使用一个纹理序列来创建动画。

我们使用Animation类描述一个动画,而精灵显示动画的动作则是一个Animate对象。动画动作Animate是精灵显示动画的动作,它由一个动画对象创建,并由精灵执行。

上面描述有点乱,我是这么理解的,真真的动画动作,其实是Animate继承了Action的子类,而Animation只是构成动画动作的资源对象。相当于剧本和道具并非实质性的演出。

Animation的创建方法

手动添加的方法需要将每一帧要显示的精灵有序添加到Animation类中,并设置每帧的播放时间,让动画能够匀速播放。另外,还要通过setRestoreOriginalFrame来设置是否在动画播放结束后恢复到第一帧。创建好Animation实例后,需要创建一个Animate实例来播放序列帧动画。

	int graphics = 9;
	// 假设一共9张图片
	char birdframe[20];
	Vector<SpriteFrame*> spriteFrems;
	// 创建一个精灵帧数组

	for (int i = 1; i <= graphics; i++) {
		// 在for循环里使用sprintf拼凑出每一帧图片的文件名
		sprintf(birdframe, "bird%d.png", i);
		// 通过图片文件名创建精灵
		auto birdSprite = Sprite::create(birdframe);
		// 通过getSpriteFrame()函数把精灵转换为精灵帧,在加入到精灵帧数组里
		spriteFrems.pushBack(birdSprite->getSpriteFrame());
	}
	// 根据精灵帧数组创建动画,第一个参数时精灵帧数组,第二个参数是执行每一帧花费的时间,假设这个动画0.6秒执行完,那么这个参数每帧执行的时间就是0.6/9
	auto animaltion = Animation::createWithSpriteFrames(spriteFrems, 0.6/graphics);

	// 根据动画创建动画动作
	auto animate = Animate::create(animaltion);

	// 用这个动画动作创建一个用久循环的动作
	auto repeatAct = RepeatForever::create(animate);
	
	// 让需要执行这个动作的对象调用runAction()函数执行这个动画动作
	bird->runAction(repeatAct);

动画缓存

动画缓存(AnimationCache)
当需要加载大量动画时,可以把动画加入到动画缓存里

	// 用精灵帧数组创建动画
	auto animaltion = Animation::createWithSpriteFrames(spriteFrames, 0.1);
	//把动画加入到动画缓存里第一个参数是需要加入缓存的动画,第二个参数是动画名,之后是根据这个动画名取出对应的动画
	AnimationCache::getInstance()->addAnimation(animaltion, animationName);
	
	// 获得动画缓存对象 
	auto cache = AnimationCache::getInstance();

	// 从动画缓存中获得指定的动画,参数是加入缓存时addAnimation(animaltion, animationName)函数第二个参数--动画名
	auto animation = cache->getAnimation(animationName);

	// 接下来就和使用普通动画一样,根据动画来创建一个动画动作(Animate)
	auto animate = Animate::create(animation);

	// 创建一个永久循环的动作
	auto repeatAct = RepeatForever::create(animate);

	// 执行这个动画动作
	hero->runAction(repeatAct);
	
	// 常用接口
	static AnimationCache* getInstance(),全局共享的单例
	void addAnimation(Animation *animation, const std::string& name),添加一个动画到缓存
	void addAnimationsWithFile(const std::string& plist),添加动画文件到缓存,plist文件
	void removeAnimation(const std::string& name),移除一个指定的动画
	Animation* getAnimation(const std::string& name),从缓存中获取动画对象
	建议:在内存警告时我们应该加入如下的清理缓存操作:

	void releaseCaches()

	{
    AnimationCache::destroyInstance();

    SpriteFrameCache::getInstance()->removeUnusedSpriteFrames();

    TextureCache::getInstance()->removeUnuserdTextures();
	}
	
	值得注意的是清理的顺序,我们推荐先清理动画缓存,然后清理精灵帧缓存,最后是纹理缓存。按照引用层级由高到低,以保证释放引用有效。

骨骼动画详解-Spine

游戏中人物的走动,跑动,攻击等动作是必不可少,实现它们的方法一般采用帧动画或者骨骼动画。帧动画的每一帧都是角色特定姿势的一个快照(完整的照片),骨骼动画则是主要将对象拆分成个各个小件(小部位),通过在每一帧中按动画要求组合这些小件。从而达到类似帧动画的快照效果,两者的区别帧动画应该每一帧都是完整的图片,所以占用内存和体积会偏大,而骨骼动画小件资源可以重复利用,每一帧之需要记录小件组合的规则,所以相对图片资源体积小,占有内存小。

你可能感兴趣的:(cocos2dx入坑记)