血条跟随怪物运动,当然非常容易想到的就是通过组合的方式将一个怪物精灵和
以前我们制作的ProgressView放在一起,然后通过就像他头像放在血量条旁边一样,
通过位置的一些计算让怪物们在头顶,顶上一个血量条。
类似的我对Monster的setAnimation,AttackAnimation进行了改写。
Monster.h
//
// Monster.h
// Fight
//
// Created by Cytzrs on 15/2/4.
//
//
#ifndef __Fight__Monster__
#define __Fight__Monster__
#include <iostream>
#include "cocos2d.h"
#include "ProgressView.h"
USING_NS_CC;
class Monster:public cocos2d::Node
{
public:
Monster(void);
~Monster(void);
//根据图片名创建怪物,不带血条
void InitMonsterSprite(char *name);
//带血条的怪物
void InitMonsterSprite(char *name,char *xue_back,char* xue_fore);
//设置动画,num为图片数目,run_directon为精灵脸朝向,false朝右,name_each为name_png中每一小张图片的公共名称部分
void SetAnimation(const char *name_each,const unsigned int num,bool run_directon);
//停止动画
void StopAnimation();
//攻击动画
void AttackAnimation(const char *name_each,const unsigned int num,bool run_directon);
//攻击动画结束
void AttackEnd();
Animation* getAnimation(const char *name_each,const unsigned int num,bool run_directon);
void RunEnd();
//返回英雄
Sprite* GetSprite();
//判断是否在跑动画
bool IsRunning;
//判断是否在攻击动画
bool IsAttack;
//英雄运动的方向
bool MonsterDirecton;
CREATE_FUNC(Monster);
private:
Sprite* m_MonsterSprite;//怪物精灵
char *Monster_name;//用来保存初始状态的精灵图片名称
ProgressView* Monster_xue;//怪物血条
};
#endif /* defined(__Fight__Monster__) */
Monster.cpp
//
// Monster.cpp
// Fight
//
// Created by Cytzrs on 15/2/4.
//
//
#include "Monster.h"
USING_NS_CC;
Monster::Monster(void)
{
IsRunning=false;//没在放动画
MonsterDirecton=true;//向右运动
Monster_name=NULL;
IsAttack=false;
Monster_xue=NULL;
}
Monster::~ Monster(void)
{
}
Sprite* Monster::GetSprite()
{
return m_MonsterSprite;
}
void Monster::InitMonsterSprite(char *name)
{
Monster_name=name;
this->m_MonsterSprite=CCSprite::create(name);
m_MonsterSprite->setFlippedX(MonsterDirecton);
this->addChild(m_MonsterSprite);
}
void Monster::InitMonsterSprite(char *name,char *xue_back,char* xue_fore)
{
InitMonsterSprite(name);
//设置怪物的血条
Monster_xue = new ProgressView();
Monster_xue->setPosition(Vec2(m_MonsterSprite->getPositionX()+25, m_MonsterSprite->getPositionY()+50));//设置在怪物上头
//Monster_xue->setScale(2.2f);
Monster_xue->setBackgroundTexture(xue_back);
Monster_xue->setForegroundTexture(xue_fore);
Monster_xue->setTotalProgress(300.0f);
Monster_xue->setCurrentProgress(300.0f);
this->addChild(Monster_xue);
}
void Monster::AttackEnd()
{
//恢复精灵原来的初始化贴图
// this->removeChild(m_MonsterSprite);//把原来的精灵删除掉
// m_MonsterSprite=Sprite::create(Hero_name);//恢复精灵原来的贴图样子
// m_MonsterSprite->setFlippedX(MonsterDirecton);
// this->addChild(m_MonsterSprite);
IsAttack=false;
}
void Monster::RunEnd()
{
//恢复精灵原来的初始化贴图
// this->removeChild(m_MonsterSprite);//把原来的精灵删除掉
// m_MonsterSprite=Sprite::create(Hero_name);//恢复精灵原来的贴图样子
// m_MonsterSprite->setFlippedX(MonsterDirecton);
// this->addChild(m_MonsterSprite);
IsRunning=false;
}
Animation* Monster::getAnimation(const char *name_each,const unsigned int num,bool run_directon)
{
auto animation = Animation::create();
for(int i = 1; i <= num; i++)
{
animation->addSpriteFrameWithFile(CCString::createWithFormat("%s%d.png", name_each, i)->getCString());
}
/** Sets the delay in seconds of the "delay unit" */
animation->setDelayPerUnit(0.1f);
/** Sets whether to restore the original frame when animation finishes */
animation->setRestoreOriginalFrame(true);
/** Sets the times the animation is going to loop. 0 means animation is not animated. 1, animation is executed one time, ... */
animation->setLoops(1);
return animation;
}
void Monster::SetAnimation(const char *name_each,const unsigned int num,bool run_directon)
{
if(MonsterDirecton!=run_directon)
{ MonsterDirecton=run_directon;
m_MonsterSprite->setFlippedX(run_directon);
}
if(IsRunning)
return;
auto ani = getAnimation(name_each,num,run_directon);
auto action = Animate::create(ani);
auto ccback = CallFunc::create(CC_CALLBACK_0(Monster::RunEnd, this));
auto act = Sequence::create(action, ccback, NULL);
m_MonsterSprite->runAction(act);
IsRunning=true;
}
void Monster::StopAnimation()
{
if(!IsRunning)
return;
m_MonsterSprite->stopAllActions();//当前精灵停止所有动画
// //恢复精灵原来的初始化贴图
// this->removeChild(m_HeroSprite);//把原来的精灵删除掉
// m_HeroSprite=Sprite::create(Hero_name);//恢复精灵原来的贴图样子
// m_HeroSprite->setFlippedX(HeroDirecton);
// this->addChild(m_HeroSprite);
IsRunning=false;
}
void Monster::AttackAnimation(const char *name_each,const unsigned int num,bool run_directon)
{
if(IsAttack)
return;
auto ani = getAnimation(name_each,num,run_directon);
auto action = Animate::create(ani);
// auto ccback = CallFunc::create(this,callfunc_selector(Hero::AttackEnd));
auto ccback = CallFunc::create( CC_CALLBACK_0(Monster::AttackEnd,this));
auto act = Sequence::create(action, ccback, NULL);
// 14 frames * 1sec = 14 seconds
m_MonsterSprite->runAction(act);
IsAttack=true;
}
补充一下,后边
Evankaka大神的资源发生了改变,相应地生成动画的函数也要改变,为了保持统一,
我只是对相关的几个函数进行了简单的重写。
代码如下:
Animation* getAnimation(const char *name_each,const unsigned int num,bool run_directon);
void SetAnimation(const char *name_each,const unsigned int num,bool run_directon);
void AttackAnimation(const char *name_each,const unsigned int num,bool run_directon);
Animation* Hero::getAnimation(const char *name_each,const unsigned int num,bool run_directon)
{
auto animation = Animation::create();
for(int i = 1; i <= num; i++)
{
animation->addSpriteFrameWithFile(CCString::createWithFormat("%s%d.png", name_each, i)->getCString());
}
/** Sets the delay in seconds of the "delay unit" */
animation->setDelayPerUnit(0.1f);
/** Sets whether to restore the original frame when animation finishes */
animation->setRestoreOriginalFrame(true);
/** Sets the times the animation is going to loop. 0 means animation is not animated. 1, animation is executed one time, ... */
animation->setLoops(1);
return animation;
}
void Hero::SetAnimation(const char *name_each,const unsigned int num,bool run_directon)
{
if(HeroDirecton!=run_directon)
{ HeroDirecton=run_directon;
m_HeroSprite->setFlippedX(run_directon);
}
// if(IsRunning)
if(IsRunning || IsAttack)
return;
auto ani = getAnimation(name_each,num,run_directon);
auto action = Animate::create(ani);
auto ccback = CallFunc::create(CC_CALLBACK_0(Hero::RunEnd, this));
auto act = Sequence::create(action, ccback, NULL);
m_HeroSprite->runAction(act);
IsRunning=true;
}
void Hero::AttackAnimation(const char *name_each,const unsigned int num,bool run_directon)
{
if(IsAttack)
return;
auto ani = getAnimation(name_each,num,run_directon);
auto action = Animate::create(ani);
// auto ccback = CallFunc::create(this,callfunc_selector(Hero::AttackEnd));
auto ccback = CallFunc::create( CC_CALLBACK_0(Hero::AttackEnd,this));
auto act = Sequence::create(action, ccback, NULL);
// 14 frames * 1sec = 14 seconds
m_HeroSprite->runAction(act);
IsAttack=true;
}
PS:多写博客,帮助自己,方便他人!