cocos2dx 大型ARPG手游研发精灵的八面玲珑.docx
《cocos2dx 大型ARPG手游研发精灵的八面玲珑.docx》由会员分享,可在线阅读,更多相关《cocos2dx 大型ARPG手游研发精灵的八面玲珑.docx(30页珍藏版)》请在冰点文库上搜索。
cocos2dx大型ARPG手游研发精灵的八面玲珑
继续上一篇文章继续聊吧,这章内容会比较多,也会附上代码,很多朋友加了群,大家在群里面探讨了很多东西,这让大家都觉得受益匪浅,这便是极好的,废话不多了,精灵是游戏的重要组成部分,那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;
classMainRoledata
{
public:
//人物的TAG
inttags;
//人物姓名
CCString*spiritname;
//人物初始坐标
CCPointnowpoint;
//人物默认像素图
CCString*spiritUrl;
//人物站立像素图路径
CCString*spiritUrl_zhan;
//人物跑动像素图路径
CCString*spiritUrl_pao;
//人物攻击像素图路径
CCString*spiritUrl_attack;
//人物施法像素图路径/增加人物BUF
CCString*spiritUrl_magic;
//人物站立最大帧
intmaxcut_zhan;
//人物跑动最大帧
intmaxcut_pao;
//人物战斗最大帧
intmaxcut_attack;
//人物施法最大帧
intmaxcut_magic;
//人物当前动作
Commen_ActionToDoacttodo;
//人物当前朝向
Commen_Directiondir;
//动画时间
floatactiontime;
};
#endif
枚举几个方向,和动作的类:
enumCommen_Direction
{
up=0,
down=1,
lefts=2,
rigth=3,
rigth_up=4,
rigth_down=5,
left_down=6,
left_up=7
};
enumCommen_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;
classSpiritsPlayer:
cocos2d:
:
CCSprite
{
public:
CCSprite*npc;
CCSprite*yinzi;
CCSprite*sp_liaotianbd;
PublicShowUI*p_ui_name;
CCArray*stringArray;
CCAnimate*playdonghua;
CCAnimate*playdonghua2;
Commen_Directionmove_dir;
boolendflag;
boolendflag2;
boolthiszhujiao_flag;
voidSpirits_talkabout_hid();
SpiritsPlayer(MainRoledataroledata,intzOrder,boolzhujiaoflag);
~SpiritsPlayer(void);
CCAnimation*getNowAnt(MainRoledataroledata);
CCAnimate*updateNowAnt(MainRoledataroledata);
voidupdateNpcPoint(CCPointnewpoint);
voidmoveTomap_dir(CCPointnewpoint);
voidmoveTomap_move(intuestime,CCPointnewpoint,boolnpcflag);
//人物移动完成的回调
voidmoveoverCallBack(void);
//普通NPC移动完成的回调
voidmoveoverCallBackforNpc(void);
//根据点击坐标获得人物的朝向
Commen_DirectiongetNowPointDir(CCPointnewpoint);
//触摸点是否在精灵上
boolisTouchInside(CCPointthisPos);
//移动方式
voidmovemethod(intuestime,CCPointnewpoint);
private:
//角色基本数据
MainRoledatathisroledata;
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;
intflag;
private:
CCRectrect();
};
#endif//_SPIRIT_PLAYER_
#include"../ImagePaths.h"
#include"../GameData/GetNPCData.h"
#include"../Commen/FontChina.h"
SpiritsPlayer:
:
SpiritsPlayer(MainRoledataroledata,intzOrder,boolzhujiaoflag)
{
//先初始化部分数据
thisroledata=roledata;
act_moveto_zi=NULL;
act_moveto_npc=NULL;
act_moveto_yinzi=NULL;
actall=NULL;
thiszhujiao_flag=zhujiaoflag;
p_ui_name=newPublicShowUI();
flag=0;
npc=SpiritsPlayer:
:
create(roledata.spiritUrl->getCString());
if(npc==NULL)
{
CCLog("图层路径有误,请检查路径");
return;
}
//设置NPC初始位置坐标(该坐标取决于当前画层)
npc->setPosition(roledata.nowpoint);
//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:
:
CCRectSpiritsPlayer:
:
rect()
{
//获取精灵区域大小
returnCCRectMake(npc->getPositionX()-npc->getContentSize().width*npc->getAnchorPoint().x,npc->getPositionY()-npc->getContentSize().height*npc->getAnchorPoint().y,npc->getContentSize().width,npc->getContentSize().height);
}
boolSpiritsPlayer:
:
isTouchInside(CCPointthisPos)
{
CCPointlocalPos=thisPos;
CCRectrc=rect();
boolisTouched=rc.containsPoint(localPos);
if(isTouched==true){
CCLog(FontChina:
:
G2U("触发点击"));
}else
{
CCLog(FontChina:
:
G2U("未点击"));
}
returnisTouched;
}
voidSpiritsPlayer:
:
Spirits_talkabout_hid()
{
CCLog(FontChina:
:
G2U("************调用了*****************"));
}
CCAnimate*SpiritsPlayer:
:
updateNowAnt(MainRoledataroledata)
{
//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);
returnplaydonghua;
}
/*************
*主角位移移动
*************/
voidSpiritsPlayer:
:
moveTomap_move(intuestime,CCPointnewpoint,boolnpcflag)
{
if(npcflag==true)
{
actbackfun=CCCallFunc:
:
create(this,callfunc_selector(SpiritsPlayer:
:
moveoverCallBackforNpc));
}
else
{
actbackfun=CCCallFunc:
:
create(this,callfunc_selector(SpiritsPlayer:
:
moveoverCallBack));
}
movemethod(uestime,newpoint);
}
voidSpiritsPlayer:
:
movemethod(intuestime,CCPointnewpoint)
{
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);
}
/*************
*改变移动方向
*************/
voidSpiritsPlayer:
:
moveTomap_dir(CCPointnewpoint)
{
GetNPCDatanpcdata=GetNPCData();
npcdata.GetNPCchapter1();
move_dir=SpiritsPlayer:
:
getNowPointDir(newpoint);
npcdata.role_player.dir=move_dir;
npcdata.role_player.acttodo=run;
npcdata.role_player.actiontime=0.5;
npc->stopAction(playdonghua);
playdonghua=SpiritsPlayer:
:
updateNowAnt(npcdata.role_player);
npc->runAction(playdonghua);
}
/*************
*根据点击坐标获得人物的朝向
*************/
Commen_DirectionSpiritsPlayer:
:
getNowPointDir(CCPointnewpoint)
{
Commen_Directionthisdir=rigth_down;//默认为右下
//计算移动数据
floatcenter_x,center_y,npc_x,npc_y;
intmove_x,move_y;
//更新NPC方向,状态
CCPointorigin=CCDirector:
:
sharedDirector()->getVisibleOrigin();
CCSizesize=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;
}
elseif(move_x>=10&&move_y>=10)
{
//左下
thisdir=left_down;
}
elseif(move_x<=-10&&move_y<=-10)
{
//右上
thisdir=rigth_up;
}
elseif(move_x<=-10&&move_y>=10)
{
//右下
thisdir=rigth_down;
}
elseif(move_x>-10&&move_x<10&&move_y>0)
{
//下
thisdir=down;
}
elseif(move_x>-10&&move_x<10&&move_y<0)
{
//上
thisdir=up;
}
elseif(move_x>0&&move_y>-10&&move_y<10)
{
//左
thisdir=lefts;
}
elseif(move_x<0&&move_y>-10&&move_y<10)
{
//右
thisdir=rigth;
}
returnthisdir;
}
/*************
*移动完成后的回调
*************/
voidSpiritsPlayer:
:
moveoverCallBack()
{
//移动完成之后恢复站立状态
GetNPCDatanpcdata=GetNPCData();
npcdata.GetNPCchapter1();
npcdata.role_player.dir=move_dir;
npcdata.role_player.acttodo=stand;
npcdata.role_player.actiontime=1.1f;
npc->stopAction(playdonghua);
playdonghua=SpiritsPlayer:
:
updateNowAnt(npcdata.role_player);
npc->runAction(playdonghua);
}
/*************
*普通NPC移动完成后的回调
*************/
voidSpiritsPlayer:
:
moveoverCallBackforNpc()
{
}
/*************
*点击瞬移至此
*************/
voidSpiritsPlayer:
:
updateNpcPoint(CCPointnewpoint)
{
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(MainRoledataroledata)
{
CCAnimation*thisdonghua=CCAnimation:
:
create();
switch(roledata.dir)
{
caseup:
switch(roledata.acttodo)
{
caserun:
for(inti=0;i<=roledata.maxcut_pao;i++)
{
chardonghuaurl[100]={0};
sprintf(donghuaurl,"%s06%03d.png",roledata.spiritUrl_pao->getCString(),i);
thisdonghua->addSpriteFrameWithFileName(donghuaurl);
}
break;
casestand:
for(inti=0;i<=roledata.maxcut_zhan;i++)
{
chardonghuaurl[100]={0};
sprintf(donghuaurl,"%s06%03d.png",roledata.spiritUrl_zhan->getCString(),i);
thisdonghua->addSpriteFrameWithFileName(donghuaurl);
}
break;
caseattack:
break;
case