【cocos2d

阅读: 评论:0

【cocos2d

【cocos2d

  继续上一篇文章继续聊吧,这章内容会比较多,也会附上代码,很多朋友加了群,大家在群里面探讨了很多东西,这让大家都觉得受益匪浅,这便是极好的,废话不多了,精灵是游戏的重要组成部分,那ARPG里面的精灵必然是要做得很细的,因为精灵要能动,能跑,能打,甚至要能做各种交互动作等等。

      大家可以看一下下面的题,是精灵制作的流程思路:

  

 

  上图的人物素材来自于网络流传的梦幻西游,地图还有其他素材是以前公司同事制作的,如果游戏正式上线,会换一套完整的自制的素材。图中大家可以看到一个人物有很多部件组合而成,高端一点的游戏甚至部件多达几十上百种,甚至做出骨骼动画。不过以我现在的做法是按照帧动画方式实现各个人物的动作,人物的body部分细节处理会很多,还有大家看到图中的字体(字体渲染描边,我做的是最简单的了,两个LABEL合成在一起,效果能达到就行),由于人物要有方向,而且我们一次性就做8方向的人物动画,那就需要8个方向的连帧图片:

  首先,要组装起来我们首先要建一个实体角色类,这个类里面不放别的,就统一放角色的部件属性:

  

MainRoledata.h类
#ifndef _MAIN_ROLE_DATA_
#define _MAIN_ROLE_DATA_#include "cocos2d.h"
#include "../Commen_ActionToDo.h"
#include "../Commen_Direction.h"
USING_NS_CC;class MainRoledata
{
public ://人物的TAGint tags;//人物姓名CCString* spiritname;//人物初始坐标
    CCPoint nowpoint;//人物默认像素图CCString* spiritUrl;//人物站立像素图路径CCString* spiritUrl_zhan;//人物跑动像素图路径CCString* spiritUrl_pao;//人物攻击像素图路径CCString* spiritUrl_attack;//人物施法像素图路径/增加人物BUFCCString* spiritUrl_magic;//人物站立最大帧int maxcut_zhan;//人物跑动最大帧int maxcut_pao;//人物战斗最大帧int maxcut_attack;//人物施法最大帧int maxcut_magic;//人物当前动作
    Commen_ActionToDo acttodo;//人物当前朝向
    Commen_Direction dir;//动画时间float actiontime;};#endif

枚举几个方向,和动作的类:

enum Commen_Direction
{up=0,down=1,lefts=2,rigth=3,rigth_up=4,rigth_down=5,left_down=6,left_up=7
};
enum Commen_ActionToDo
{run=1,stand=2,attack=3,death=4,funny=5,magicup=6
};

OK,然后配置精灵数据,建了一个GetNPCData.cpp,GetNPCData.h,主要就是拿来初始化数据,大致的思路是要将上面的Model填充数据,相信大家

能够用很多种方式去实现,填充数据(读取XML配置文件,直接写在代码中配置);

接下来我们正式组装完整的八面玲珑的精灵,建立SpiritsPlayer.cpp,SpiritsPlayer.h;

 文件内容如下:

#ifndef _SPIRIT_PLAYER_
#define _SPIRIT_PLAYER_#include "cocos2d.h"
#include "../Commen_ActionToDo.h"
#include "../Commen_Direction.h"
#include "../GameData/MainRoledata.h"
#include "../Commen/PublicShowUI.h"
#include "../Effects/EffectsCommen.h"USING_NS_CC;class SpiritsPlayer : cocos2d::CCSprite 
{
public: CCSprite* npc;CCSprite* yinzi;CCSprite* sp_liaotianbd;PublicShowUI* p_ui_name;CCArray *stringArray;CCAnimate* playdonghua;CCAnimate* playdonghua2;Commen_Direction move_dir;bool endflag;bool endflag2;bool thiszhujiao_flag;void Spirits_talkabout_hid();SpiritsPlayer(MainRoledata roledata,int zOrder,bool zhujiaoflag);~SpiritsPlayer(void);CCAnimation* getNowAnt(MainRoledata roledata);CCAnimate* updateNowAnt(MainRoledata roledata);void updateNpcPoint(CCPoint newpoint);void moveTomap_dir(CCPoint newpoint);void moveTomap_move(int uestime,CCPoint newpoint,bool npcflag);//人物移动完成的回调void moveoverCallBack(void);//普通NPC移动完成的回调void moveoverCallBackforNpc(void);//根据点击坐标获得人物的朝向
    Commen_Direction getNowPointDir(CCPoint newpoint);// 触摸点是否在精灵上bool isTouchInside(CCPoint thisPos);//移动方式void movemethod(int uestime,CCPoint newpoint);private://角色基本数据
    MainRoledata thisroledata;CCFiniteTimeAction *actall;CCActionInterval* act_moveto_zi;CCActionInterval* act_moveto_npc;CCActionInterval* act_moveto_yinzi;CCActionInterval* act_moveto_eff;CCActionInterval* act_moveto_eff_zhujiao;CCFiniteTimeAction *actbackfun; int flag ;private:CCRect rect();};
#endif//_SPIRIT_PLAYER_


  
#include "../ImagePaths.h"
#include "../GameData/GetNPCData.h"
#include "../Commen/FontChina.h"SpiritsPlayer::SpiritsPlayer(MainRoledata roledata,int zOrder,bool zhujiaoflag)
{//先初始化部分数据thisroledata = roledata;act_moveto_zi =NULL;act_moveto_npc =NULL;act_moveto_yinzi =NULL;actall=NULL;thiszhujiao_flag = zhujiaoflag;p_ui_name = new PublicShowUI();flag = 0;npc = SpiritsPlayer::create(roledata.spiritUrl->getCString());if(npc==NULL){CCLog("图层路径有误,请检查路径");return;}//设置NPC初始位置坐标(该坐标取决于当前画层)npc->wpoint);//NPC动画设置playdonghua = SpiritsPlayer::updateNowAnt(roledata);npc->runAction(playdonghua);/**开始添加角色各部件**///添加角色名称CCLabelTTF* label = CCLabelTTF::create(roledata.spiritname->getCString(), "微软雅黑",12);label->setColor(ccWHITE);label->setDirty(true);label->setPosition(ccp(npc->getContentSize().width/2,npc->getContentSize().height+6));CCLabelTTF* labelback = CCLabelTTF::create(roledata.spiritname->getCString(), "微软雅黑",12);labelback->setColor(ccBLACK);labelback->setDirty(true);labelback->setPosition(ccp(npc->getContentSize().width/2+1,npc->getContentSize().height+6-1));//添加NPC人物脚下阴影yinzi = CCSprite::create(p_yinzi);if(yinzi==NULL){CCLog("图层路径有误,请检查路径");return;}if(zhujiaoflag==true){yinzi->setPosition(ccp(npc->getContentSize().width/2,12));}else{yinzi->setPosition(ccp(npc->getContentSize().width/2,1));}npc->addChild(yinzi,-1,110);npc->addChild(label,2,111);npc->addChild(labelback,1,112);}cocos2d::CCRect SpiritsPlayer::rect()
{//获取精灵区域大小return CCRectMake(npc->getPositionX()- npc->getContentSize().width  * npc->getAnchorPoint().x,npc->getPositionY()-npc->getContentSize().height* npc->getAnchorPoint().y,npc->getContentSize().width, npc->getContentSize().height); }bool SpiritsPlayer::isTouchInside(CCPoint thisPos)
{CCPoint localPos = thisPos;CCRect rc = rect();bool isTouched = rc.containsPoint(localPos);if (isTouched == true) {CCLog(FontChina::G2U("触发点击"));}else{CCLog(FontChina::G2U("未点击"));}return isTouched;
}void SpiritsPlayer::Spirits_talkabout_hid()
{CCLog(FontChina::G2U("************调用了*****************"));
}CCAnimate* SpiritsPlayer::updateNowAnt(MainRoledata roledata)
{//NPC动画CCAnimation* donghua = SpiritsPlayer::getNowAnt(roledata);if(roledata.actiontime>0){donghua->setDelayPerUnit(roledata.actiontime/roledata.maxcut_zhan);}else  {donghua->setDelayPerUnit(2.0f/15.0f);//执行默认时间
    }donghua->setRestoreOriginalFrame(true);donghua->setLoops(-1);CCAnimate* playdonghua = CCAnimate::create(donghua);return playdonghua;
}/*************
* 主角位移移动
*************/
void SpiritsPlayer::moveTomap_move(int uestime, CCPoint newpoint,bool npcflag)
{if(npcflag==true){actbackfun = CCCallFunc::create(this, callfunc_selector(SpiritsPlayer::moveoverCallBackforNpc));}else{actbackfun = CCCallFunc::create(this, callfunc_selector(SpiritsPlayer::moveoverCallBack));}movemethod(uestime,newpoint);
}void SpiritsPlayer::movemethod(int uestime,CCPoint newpoint)
{npc->stopAction(actall);act_moveto_npc = CCMoveTo::create(uestime,ccp(newpoint.x,newpoint.y+20));actall = CCSequence::create(act_moveto_npc,actbackfun,NULL);npc->runAction(actall);
}/*************
* 改变移动方向
*************/
void SpiritsPlayer::moveTomap_dir(CCPoint newpoint)
{GetNPCData npcdata = GetNPCData();npcdata.GetNPCchapter1();move_dir=SpiritsPlayer::getNowPointDir(newpoint);le_player.dir=move_le_player.acttodo = le_player.actiontime=0.5;npc->stopAction(playdonghua);playdonghua = SpiritsPlayer::le_player);npc->runAction(playdonghua);
}/*************
* 根据点击坐标获得人物的朝向
*************/
Commen_Direction SpiritsPlayer::getNowPointDir(CCPoint newpoint)
{Commen_Direction thisdir = rigth_down; //默认为右下//计算移动数据float center_x,center_y,npc_x,npc_y;int move_x,move_y;//更新NPC方向,状态CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();CCSize size = CCDirector::sharedDirector()->getWinSize();center_x = size.width/2;center_y = size.height/2;npc_x = npc->getPositionX();npc_y = npc->getPositionY();move_x =  (int)(npc_x -newpoint.x );move_y =  (int)(npc_y -newpoint.y - 20);if(move_x>=10&&move_y<=-10){//左上thisdir = left_up;}else if(move_x>=10&&move_y>=10){//左下thisdir = left_down;}else if(move_x<=-10&&move_y<=-10){//右上thisdir = rigth_up;}else if(move_x<=-10&&move_y>=10){//右下thisdir =rigth_down;}else if(move_x>-10&&move_x<10&&move_y>0){//下thisdir =down;}else if(move_x>-10&&move_x<10&&move_y<0){//上thisdir =up;}else if(move_x>0&&move_y>-10&&move_y<10){//左thisdir = lefts;}else if(move_x<0&&move_y>-10&&move_y<10){//右thisdir =rigth;}return thisdir;
}/*************
* 移动完成后的回调
*************/
void SpiritsPlayer::moveoverCallBack()
{//移动完成之后恢复站立状态GetNPCData npcdata = GetNPCData();npcdata.GetNPCchapter1();le_player.dir=move_le_player.acttodo = le_player.actiontime=1.1f;npc->stopAction(playdonghua);playdonghua = SpiritsPlayer::le_player);npc->runAction(playdonghua);
}/*************
* 普通NPC移动完成后的回调
*************/
void SpiritsPlayer::moveoverCallBackforNpc()
{}/*************
* 点击瞬移至此
*************/
void SpiritsPlayer::updateNpcPoint(CCPoint newpoint)
{p_ui_name->updataGameText(ccp(newpoint.x,newpoint.y+npc->getContentSize().height/2+10));npc->setPosition(newpoint);yinzi->setPosition(ccp(newpoint.x,newpoint.y-npc->getContentSize().height/2+5));
}/*********************
* 八方向人物动作合成器
*********************/
CCAnimation* SpiritsPlayer::getNowAnt(MainRoledata roledata)
{CCAnimation* thisdonghua = CCAnimation::create();switch (roledata.dir){case up:switch (roledata.acttodo){case run:for(int i = 0; i<=roledata.maxcut_pao ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s06%03d.png",roledata.spiritUrl_pao->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case stand:for(int i = 0; i<=roledata.maxcut_zhan ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s06%03d.png",roledata.spiritUrl_zhan->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case attack:break;case death:break;case funny:break;default:break;}break;case down:switch (roledata.acttodo){case run:for(int i = 0; i<=roledata.maxcut_pao ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s04%03d.png",roledata.spiritUrl_pao->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case stand:for(int i = 0; i<=roledata.maxcut_zhan ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s04%03d.png",roledata.spiritUrl_zhan->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case attack:break;case death:break;case funny:break;default:break;}break;case lefts:switch (roledata.acttodo){case run:for(int i = 0; i<=roledata.maxcut_pao ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s05%03d.png",roledata.spiritUrl_pao->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case stand:for(int i = 0; i<=roledata.maxcut_zhan ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s05%03d.png",roledata.spiritUrl_zhan->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case attack:break;case death:break;case funny:break;default:break;}break;case rigth:switch (roledata.acttodo){case run:for(int i = 0; i<=roledata.maxcut_pao ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s07%03d.png",roledata.spiritUrl_pao->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case stand:for(int i = 0; i<=roledata.maxcut_zhan ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s07%03d.png",roledata.spiritUrl_zhan->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case attack:break;case death:break;case funny:break;default:break;}break;case rigth_up:switch (roledata.acttodo){case run:for(int i = 0; i<=roledata.maxcut_pao ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s03%03d.png",roledata.spiritUrl_pao->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case stand:for(int i = 0; i<=roledata.maxcut_zhan ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s03%03d.png",roledata.spiritUrl_zhan->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case attack:for(int i = 0; i<=roledata.maxcut_attack ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s03%03d.png",roledata.spiritUrl_attack->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case magicup:for(int i = 0; i<=roledata.maxcut_magic ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s03%03d.png",roledata.spiritUrl_magic->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case death:break;case funny:break;default:break;}break;case rigth_down:switch (roledata.acttodo){case run:for(int i = 0; i<=roledata.maxcut_pao ; i++){char donghuaurl[1000] = {0};sprintf(donghuaurl,"%s00%03d.png",roledata.spiritUrl_pao->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case stand:for(int i = 0; i<=roledata.maxcut_zhan ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s00%03d.png",roledata.spiritUrl_zhan->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case attack:for(int i = 0; i<=roledata.maxcut_attack ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s00%03d.png",roledata.spiritUrl_attack->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case magicup:for(int i = 0; i<=roledata.maxcut_magic ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s00%03d.png",roledata.spiritUrl_magic->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case death:break;case funny:break;default:break;}break;case left_down:switch (roledata.acttodo){case run:for(int i = 0; i<=roledata.maxcut_pao ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s01%03d.png",roledata.spiritUrl_pao->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case stand:for(int i = 0; i<=roledata.maxcut_zhan ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s01%03d.png",roledata.spiritUrl_zhan->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case attack:for(int i = 0; i<=roledata.maxcut_attack ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s01%03d.png",roledata.spiritUrl_attack->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case magicup:for(int i = 0; i<=roledata.maxcut_magic ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s01%03d.png",roledata.spiritUrl_magic->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case death:break;case funny:break;default:break;}break;case left_up:switch (roledata.acttodo){case run:for(int i = 0; i<=roledata.maxcut_pao ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s02%03d.png",roledata.spiritUrl_pao->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case stand:for(int i = 0; i<=roledata.maxcut_zhan ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s02%03d.png",roledata.spiritUrl_zhan->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case attack:for(int i = 0; i<=roledata.maxcut_attack ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s02%03d.png",roledata.spiritUrl_attack->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case magicup:for(int i = 0; i<=roledata.maxcut_magic ; i++){char donghuaurl[100] = {0};sprintf(donghuaurl,"%s02%03d.png",roledata.spiritUrl_magic->getCString(),i);thisdonghua->addSpriteFrameWithFileName(donghuaurl);}break;case death:break;case funny:break;default:break;}break;default:break;}return thisdonghua;
}SpiritsPlayer::~SpiritsPlayer(void)
{
}

sprintf(donghuaurl,"%s06%03d.png",roledata.spiritUrl_pao->getCString(),i);

总体思路就是,我们通过了帧连接的拼接来构成动画,通过我们之前写好的model数据来定义我们任务的朝向等问题

比如00000代表右,01000就代表右上,这个也得根据自己素材的模型来写不同的处理逻辑,万变不离其中;

如果我们的图片是在一张大图的集合中,我们可以同过CCRect来处理获取帧图片方式!

CCAnimation* getNowAnt(MainRoledata roledata);
CCAnimate* updateNowAnt(MainRoledata roledata);

通过这两个方法集合,我们就能获取到八面玲珑的朝向,甚至我们连,后续的动画机制也加入了,比如,跑动,打斗,做各种动作等!

Commen_Direction SpiritsPlayer::getNowPointDir(CCPoint newpoint); //获取朝向

void SpiritsPlayer::moveTomap_dir(CCPoint newpoint) //改变朝向方法

以上两个方法,我们是专门处理,之后精灵移动,移动完之后还得恢复到站立状态,移动过程中改变人物朝向问题!所以要考虑的很清楚

很清晰,思路清楚了,才能方便以后的拓展。

OK了,有了以上的精灵类,将其实例化到一个简单的图片地图上,他就会动了;

添加的时候我们直接addchild方法!!

SpiritsPlayer* role_main = new SpiritsPlayer(basedatas->role_player,1,false);

nowmap->addChild(role_main->npc, 999);

nowmap 暂且可以用一张图片CCSprite代替!!!

下一篇博客我会非常详细的将地图制作方法写出来给大家一起分享,由于其实我之前都是C#,JAVA做的很多,很多地方和细节还需要重构

还需要大家多指点一下,这也是我学习的好机会;

 

游戏demo及素材下载地址(demo里面包含了所有的素材资料);

=4012433582&uk=4097703620&third=15

 

ps:广告我建了一个QQ群:和大家一起分享cocos2dx开发经验【41131516】

 

转载于:.html

本文发布于:2024-02-04 12:00:25,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170706701655370.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:cocos2d
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23