展会信息港展会大全

Cocos2d-x 血条跟随怪物运动----之游戏开发《赵云要格斗》(5),怪物弹珠赵云
来源:互联网   发布日期:2015-09-28 14:40:25   浏览:2121次  

导读: Cocos2d-x 血条跟随怪物运动----之游戏开发《赵云要格斗》(5),怪物弹珠赵云 本章在前面的基础上Cocos2d-x 自定义血条及其美化----之游戏开发《赵云要格斗》...

Cocos2d-x 血条跟随怪物运动----之游戏开发《赵云要格斗》(5),怪物弹珠赵云

本章在前面的基础上Cocos2d-x

自定义血条及其美化----之游戏开发《赵云要格斗》(4)

设计一个怪物类,并实现怪物的上方显示血条,血条跟随怪物的运动而运动。用到的血条类在上一讲中,平时我们游戏一般怪物都是头顶一个血条的,这里我们就是要实现这个功能。

重要说明:由于TexturePacker试用期结束了,不能再用,所以接下来的动画都不合成plist和整张的PNG。同时,之前的赵云图像太动画效果不是很好,所以换了个赵云的图片。另外,将整个项目的类都分别归档,这样更加容易看懂些,所以hero.h和hero.cpp有些函数进行了更改,同时调用的地方也改了下。这里一定要注意!

这是本章的一个效果:

(下一章的效果)

一、更改英雄hero类

赵云的图片:以下中是一部分,动画就是通过读一张一张的PNG图片来实现的(没有再合成Plist和整张PNG)

更改后的英雄类Hero.h(类的函数和变量还是不变的,使用方法还是不变的,只不SetAnimation函数参数更改变了)

#ifndef __HERO_H__

#define __HERO_H__

#include "cocos2d.h"

using namespace cocos2d;

class Hero:public cocos2d::CCNode

{

public:

Hero(void);

~Hero(void);

//根据图片名创建英雄

void InitHeroSprite(char *hero_name);

//设置动画,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();

//判断英雄是否运动到了窗口的中间位置,visibleSize为当前窗口的大小

bool JudgePositona(CCSize visibleSize);

//判断是否在跑动画

bool IsRunning;

//判断是否在攻击动画

bool IsAttack;

//英雄运动的方向

bool HeroDirecton;

CREATE_FUNC(Hero);

private:

CCSprite* m_HeroSprite;//精灵

char *Hero_name;//用来保存初始状态的精灵图片名称

};

#endif // __HERO_H__

更改后的英雄类Hero.cpp#include "Hero.h"

USING_NS_CC;

Hero::Hero(void)

{

IsRunning=false;//没在放动画

HeroDirecton=false;//向右运动

Hero_name=NULL;

IsAttack=false;

}

Hero::~Hero(void)

{

}

void Hero::InitHeroSprite(char *hero_name)

{

Hero_name=hero_name;

this->m_HeroSprite=CCSprite::create(hero_name);

this->addChild(m_HeroSprite);

}

void Hero::SetAnimation(const char *name_each,unsigned int num,bool run_directon)

{

if(HeroDirecton!=run_directon)

{HeroDirecton=run_directon;

m_HeroSprite->setFlipX(run_directon);

}

if(IsRunning)

return;

CCAnimation* animation = CCAnimation::create();

for( int i=1;i<=num;i++)

{

char szName[100] = {0};

sprintf(szName,"%s%d.png",name_each,i);

animation->addSpriteFrameWithFileName(szName); //加载动画的帧

}

animation->setDelayPerUnit(0.1f);

animation->setRestoreOriginalFrame(true);

animation->setLoops(-1); //动画循环

if(HeroDirecton!=run_directon)

{HeroDirecton=run_directon;

}

//将动画包装成一个动作

CCAnimate* act=CCAnimate::create(animation);

m_HeroSprite->runAction(act);

IsRunning=true;

}

void Hero::StopAnimation()

{

if(!IsRunning)

return;

m_HeroSprite->stopAllActions();//当前精灵停止所有动画

//恢复精灵原来的初始化贴图

this->removeChild(m_HeroSprite,TRUE);//把原来的精灵删除掉

m_HeroSprite=CCSprite::create(Hero_name);//恢复精灵原来的贴图样子

m_HeroSprite->setFlipX(HeroDirecton);

this->addChild(m_HeroSprite);

IsRunning=false;

}

void Hero::AttackAnimation(const char *name_each,const unsigned int num,bool run_directon)

{

if(IsAttack)

return;

IsAttack=true;

CCAnimation* animation = CCAnimation::create();

for( int i=1;i<=num;i++)

{

char szName[100] = {0};

sprintf(szName,"%s%d.png",name_each,i);

animation->addSpriteFrameWithFileName(szName); //加载动画的帧

}

animation->setDelayPerUnit(0.05f);

animation->setRestoreOriginalFrame(true);

animation->setLoops(1); //动画循环

if(HeroDirecton!=run_directon)

{HeroDirecton=run_directon;

}

//将动画包装成一个动作

CCAnimate* act=CCAnimate::create(animation);

//创建回调动作,攻击结束后调用AttackEnd()

CCCallFunc* callFunc=CCCallFunc::create(this,callfunc_selector(Hero::AttackEnd));

//创建连续动作

CCActionInterval* attackact=CCSequence::create(act,callFunc,NULL);

m_HeroSprite->runAction(attackact);

}

void Hero::AttackEnd()

{

//恢复精灵原来的初始化贴图

this->removeChild(m_HeroSprite,TRUE);//把原来的精灵删除掉

m_HeroSprite=CCSprite::create(Hero_name);//恢复精灵原来的贴图样子

m_HeroSprite->setFlipX(HeroDirecton);

this->addChild(m_HeroSprite);

IsAttack=false;

}

bool Hero::JudgePositona (CCSize visibleSize)

{

if(this->getPositionX()!=visibleSize.width/2)//精灵到达左边

return false;

else

return true;//到达中间位置

}

记得在用的地方要改下SetAnimation,其它地方都不变,只不SetAnimation函数参数更改变了

void HelloWorld::update(float delta)

{

//判断是否按下摇杆及其类型

CCSize visibleSize1 = CCDirector::sharedDirector()->getVisibleSize();//得到窗口大小

switch(rocker->rocketDirection)

{

case1:

hero->SetAnimation("hero_run",8,rocker->rocketRun);

if(hero->getPositionX()<=visibleSize1.width-8)//不让精灵超出右边,8可以改成你喜欢的

{

if(!hero->JudgePositona(visibleSize1)||mymap->JudgeMap(hero,visibleSize1))//精灵没到达窗口中间位置或者地图已经移动到边缘了,精灵才可以移动,否则只播放动画

hero->setPosition(ccp(hero->getPosition().x+1,hero->getPosition().y)); //向右走

//下面是移动地图

mymap->MoveMap(hero,visibleSize1);

}

break;

case2:

hero->SetAnimation("hero_run",8,rocker->rocketRun);

hero->setPosition(ccp(hero->getPosition().x, hero->getPosition().y+1));//向上走

break;

case 3:

hero->SetAnimation("hero_run",8,rocker->rocketRun);

if(hero->getPositionX()>=8)//不让精灵超出左边,8可以改成你喜欢的

hero->setPosition(ccp(hero->getPosition().x-1,hero->getPosition().y));//向左走

break;

case 4:

hero->SetAnimation("hero_run",8,rocker->rocketRun);

hero->setPosition(ccp(hero->getPosition().x,hero->getPosition().y-1));//向下走

break;

case 0:

hero->StopAnimation();//停止所有动画和运动

break;

}

//判断是否出动攻击

if(btn->isTouch)

{

if(hero->IsAttack)//英雄没在攻击

return;

hero->AttackAnimation("hero_attack",20,rocker->rocketRun);

m_pProgressView->setCurrentProgress(m_pProgressView->getCurrentProgress()-10); //更改血量

}

}

效果:和以前相比,赵云的图片更加清楚了些,而且攻击的图片也比较顺了一点(20张图片啊!)

二、自定义带血条的怪物

这里的血条用到了前面的自定义血条,思路就是把上篇自定义的血条类ProgressView应用在Monster中,得到Monster类中怪物的位置,然后根据这个位置来设置血条成员变量的位置(一般在上方),最后把怪物精灵和血条类都addchild()进来就行了

下面这是怪物的资源:(一部分,动画也是通过一张一张的播放的)

Monster.h:

#ifndef __Monster_H__

#define __Monster_H__

#include "cocos2d.h"

#include "ProgressView.h"

USING_NS_CC;

class Monster:public cocos2d::CCNode

{

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();

//返回英雄

CCSprite* GetSprite();

//判断是否在跑动画

bool IsRunning;

//判断是否在攻击动画

bool IsAttack;

//英雄运动的方向

bool MonsterDirecton;

CREATE_FUNC(Monster);

private:

CCSprite* m_MonsterSprite;//怪物精灵

char *Monster_name;//用来保存初始状态的精灵图片名称

ProgressView*Monster_xue;//怪物血条

};

#endif // __HERO_H__

Monster.cpp:

#include "Monster.h"

USING_NS_CC;

Monster::Monster(void)

{

IsRunning=false;//没在放动画

MonsterDirecton=TRUE;//向右运动

Monster_name=NULL;

IsAttack=false;

Monster_xue=NULL;

}

Monster::~ Monster(void)

{

}

CCSprite* Monster::GetSprite()

{

return m_MonsterSprite;

}

voidMonster::InitMonsterSprite(char *name)

{

Monster_name=name;

this->m_MonsterSprite=CCSprite::create(name);

m_MonsterSprite->setFlipX(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(ccp(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);

}

voidMonster::SetAnimation(const char *name_each,unsigned int num,bool run_directon)

{

if(MonsterDirecton!=run_directon)

{MonsterDirecton=run_directon;

m_MonsterSprite->setFlipX(run_directon);

}

if(IsRunning||IsAttack)

return;

CCAnimation* animation = CCAnimation::create();

for( int i=1;i<=num;i++)

{

char szName[100] = {0};

sprintf(szName,"%s%d.png",name_each,i);

animation->addSpriteFrameWithFileName(szName); //加载动画的帧

}

animation->setDelayPerUnit(2.8f / 14.0f);

animation->setRestoreOriginalFrame(true);

animation->setLoops(-1); //动画循环

//将动画包装成一个动作

CCAnimate* act=CCAnimate::create(animation);

m_MonsterSprite->runAction(act);

IsRunning=true;

}

voidMonster::StopAnimation()

{

if(!IsRunning)

return;

m_MonsterSprite->stopAllActions();//当前精灵停止所有动画

//恢复精灵原来的初始化贴图

this->removeChild(m_MonsterSprite,TRUE);//把原来的精灵删除掉

m_MonsterSprite=CCSprite::create(Monster_name);//恢复精灵原来的贴图样子

m_MonsterSprite->setFlipX(MonsterDirecton);

this->addChild(m_MonsterSprite);

IsRunning=false;

}

voidMonster::AttackAnimation(const char *name_each,const unsigned int num,bool run_directon)

{

if(IsAttack||IsRunning)

return;

CCAnimation* animation = CCAnimation::create();

for( int i=1;i<=num;i++)

{

char szName[100] = {0};

sprintf(szName,"%s%d.png",name_each,i);

animation->addSpriteFrameWithFileName(szName); //加载动画的帧

}

animation->setDelayPerUnit(2.8f / 14.0f);

animation->setRestoreOriginalFrame(true);

animation->setLoops(1); //动画循环1次

//将动画包装成一个动作

CCAnimate* act=CCAnimate::create(animation);

//创建回调动作,攻击结束后调用AttackEnd()

CCCallFunc* callFunc=CCCallFunc::create(this,callfunc_selector(Monster::AttackEnd));

//创建连续动作

CCActionInterval* attackact=CCSequence::create(act,callFunc,NULL);

m_MonsterSprite->runAction(attackact);

IsAttack=true;

}

void Monster::AttackEnd()

{

//恢复精灵原来的初始化贴图

this->removeChild(m_MonsterSprite,TRUE);//把原来的精灵删除掉

m_MonsterSprite=CCSprite::create(Monster_name);//恢复精灵原来的贴图样子

m_MonsterSprite->setFlipX(MonsterDirecton);

this->addChild(m_MonsterSprite);

IsAttack=false;

}

使用方法:

HelloWorldScene.h添加头文件 #include "Monster.h"

HelloWorldScene.h添加成员变量: Monster *monster1;//怪物种类1

HelloWorldScene.cpp的Init()函数进行初始化:

这是不带血条的怪物:

//添加怪物

monster1=Monster::create();

monster1->InitMonsterSprite("monster.png");

//monster1->InitMonsterSprite("monster.png","xue_back.png","xue_fore.png");

monster1->setPosition(ccp(visibleSize.width-150,visibleSize.height/2));

this->addChild(monster1,1);

这是带血条的怪物:

//添加怪物

monster1=Monster::create();

//monster1->InitMonsterSprite("monster.png");

monster1->InitMonsterSprite("monster.png","xue_back.png","xue_fore.png");

monster1->setPosition(ccp(visibleSize.width-150,visibleSize.height/2));

this->addChild(monster1,1);

好了,这一篇就结束了,下一篇我们将会来讲讲智能怪物,让怪物动起来并能出动攻击!

下面是血条跟随怪物移动的效果(下一章的效果)

后记:

游戏开发中美工好重要,自己为了找这几个图片,都是从GIF图片中,导入到PS中,然后再导出一张张的PNG,主要是cocos2dx不支持直接播放GIF,要是可以就好了(网上有插件,不过没试过),资源啊资源啊!不容易找也不容易用啊,

http://www.bkjia.com/Androidjc/939135.htmlwww.bkjia.comtruehttp://www.bkjia.com/Androidjc/939135.htmlTechArticleCocos2d-x 血条跟随怪物运动----之游戏开发《赵云要格斗》(5),怪物弹珠赵云 本章在前面的基础上Cocos2d-x 自定义血条及其美化----之游戏开...

赞助本站

人工智能实验室

相关热词: android开发 应用开发

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港