这种序列帧动画要求每一帧的宽高必须一一致,否则动画播起来会出问题。
需要的图片类似图1.1会把所有的动作拼接到一张图上,这样做也是为了节省内存和减少DrawCall,切换动作的时候只需要重新计算图片的UV,然后把算出来的UV作为新区域贴在原来的那张纹理面片上即可。
Animate是Animation的一部分,一个Animation可以保存多个Animate,也可以理解成Animate只是一个动画片段,Animation是完整的动画控制器。这个结构其实有点像Unity的AnimateClip和Animator。
不多说,上代码,自己去看代码吧,实现不是很难,不多讲了。
程序1.1
Animate.h完整代码
#pragmaoncenamespaceU2D{enumMovementEvent{START,COMPLETE,};classCAnimate:publicCPicture{friendclassCAnimation;private:charname[50];//动画名UINTframeWidth;//每一帧的宽度UINTframeHeight;//每一帧的高度UINTrows;//总行数UINTcols;//总列数UINTstartIndex;//开始的索引编号UINTendIndex;//结束的索引编号UINTcurIndex;//当前的索引编号boolisPlaying;//是否播放boolisLoop;//是否循环UINTframeSpeed;//每一帧的速度UINTframeTimer;//每一帧的时间animate_selectorlistener_movementEvent;//动画事件监听public:CAnimate(char*fileName,UINTrows,UINTcols);CAnimate(CCTexture*tex,UINTrows,UINTcols);voidsetName(char*name){strcpy(this->name,name);}char*getName{returnthis->name;}voidsetFrameIndex(UINTstartIndex,UINTendIndex){this->startIndex=startIndex;this->endIndex=endIndex;curIndex=startIndex;}Vector2getFrameSize{returnVector2(frameWidth,frameHeight);}UINTgetFrameCount{returnendIndex-startIndex+1;}voidplay{isPlaying=true;}voidstop{isPlaying=false;}voidrepeat(boolisLoop){this->isLoop=isLoop;}voidsetDelayUnit(UINTframeSpeed){this->frameSpeed=frameSpeed;}voidsetMovementEventCallFunc(animate_selectorfun_movementEvent);//设置动画事件的回调函数voiddraw;voidall_Anchor_0_0;voidall_Anchor_05_05;public:CAnimate{}~CAnimate(void){}};}
程序1.2
Animate.cpp完整代码
#include"Engine.h"namespaceU2D{CAnimate::CAnimate(char*fileName,UINTrows,UINTcols):CPicture(fileName){strcmp(this->name,fileName);this->rows=rows;this->cols=cols;isPlaying=true;isLoop=true;frameSpeed=10;frameWidth=pTexture->getWidth/cols;frameHeight=pTexture->getHeight/rows;startIndex=0;endIndex=rows*cols-1;curIndex=startIndex;}CAnimate::CAnimate(CCTexture*tex,UINTrows,UINTcols):CPicture(tex){strcmp(this->name,tex->getName);this->rows=rows;this->cols=cols;isPlaying=true;isLoop=true;frameSpeed=10;frameWidth=tex->getWidth/cols;frameHeight=tex->getHeight/rows;startIndex=0;endIndex=rows*cols-1;curIndex=startIndex;}voidCAnimate::setMovementEventCallFunc(animate_selectorfun_movementEvent){this->listener_movementEvent=fun_movementEvent;}voidCAnimate::draw{if(isPlaying){if(frameTimer++%frameSpeed==0){if(curIndex==startIndex){if(listener_movementEvent){if(parent!=NULL){(parent->*listener_movementEvent)(this,MovementEvent::START);}else(parent->*listener_movementEvent)(this,MovementEvent::START);}}if(curIndex==endIndex+1){if(isLoop){curIndex=startIndex;}else{isPlaying=false;curIndex=endIndex;}if(listener_movementEvent){if(parent!=NULL){if(parent!=NULL){(parent->*listener_movementEvent)(this,MovementEvent::COMPLETE);}else(parent->*listener_movementEvent)(this,MovementEvent::COMPLETE);}}}(&srcRect,curIndex%cols*frameWidth,curIndex/cols*frameHeight,(curIndex%cols+1)*frameWidth,(curIndex/cols+1)*frameHeight);curIndex++;}}CPicture::draw;}voidCAnimate::all_Anchor_0_0{}voidCAnimate::all_Anchor_05_05{}}
程序1.3
Animation.h完整代码
#pragmaoncenamespaceU2D{classCAnimation:publicCElement{friendclassCPlayer;protected:listanimateList;//动画的链表用名字判断,有就返回,没有就new一个CAnimate*animate;//当前播放的动画animation_selectorlistener_movementEvent;//动画集事件监听voidanimateEvent(CAnimate*animate,MovementEventtype);UINTrows;UINTcols;char*fileName;public:CAnimation;CAnimate*addAnimate(char*animName,char*fileName,UINTrows,UINTcols);CAnimate*addAnimate(char*animName,CCTexture*tex,UINTrows,UINTcols);CAnimate*findAnimate(char*animName);voidsetAnimate(char*animName);Vector2getFrameSize{returnanimate->getFrameSize;}UINTgetFrameCount{returnanimate->getFrameCount;}voidplay{animate->play;}voidstop{animate->stop;}voidrepeat(boolisLoop){animate->repeat(isLoop);}voidsetDelayUnit(UINTframeSpeed){animate->setDelayUnit(frameSpeed);}voidsetFrameIndex(UINTstartIndex,UINTendIndex){returnanimate->setFrameIndex(startIndex,endIndex);}voidsetName_FrameIndex(char*name,UINTstartIndex,UINTendIndex);voidsetMovementEventCallFunc(animation_selectorfun_movementEvent);voiddraw;voidsetCurrentAllanchor(floatox,floatoy);RECTgetBoundBox;~CAnimation;};}
程序1.4
Animation.cpp完整代码
#include"Engine.h"namespaceU2D{CAnimation::CAnimation{animate=NULL;listener_movementEvent=NULL;}CAnimate*CAnimation::addAnimate(char*animName,char*fileName,UINTrows,UINTcols){CAnimate*anim=findAnimate(animName);//查找这个动画名字,如果找不到就会返回空if(anim!=NULL)//如果不为空就说明找到了returnanim;this->rows=rows;this->cols=cols;this->fileName=fileName;anim=newCAnimate(fileName,rows,cols);//如果为空就new一个对象压进去。并且把名字设置好anim->setName(animName);//设置动画名字anim->setParent(this);//CAnimation是CNode的子类,子类拥有父类的所有数据,所以压入CAnimation就等同于压入了CNode。anim->setMovementEventCallFunc(animate_selector(&CAnimation::animateEvent));//回调函数animateList.push_back(anim);//压进链表setAnimate(animName);//设置动画returnanimateList.back;//把刚压进去的对象返回出去}CAnimate*CAnimation::addAnimate(char*animName,CCTexture*tex,UINTrows,UINTcols){CAnimate*anim=findAnimate(animName);if(anim!=NULL)returnanim;this->rows=rows;this->cols=cols;anim=newCAnimate(tex,rows,cols);anim->setName(animName);anim->setParent(this);anim->setMovementEventCallFunc(animate_selector(&CAnimation::animateEvent));animateList.push_back(anim);setAnimate(animName);returnanimateList.back;}CAnimate*CAnimation::findAnimate(char*animName){list::iteratoriter;for(iter=animateList.begin;iter!=animateList.end;iter++){if(strcmp((*iter)->name,animName)==0){return*iter;}}returnNULL;}voidCAnimation::setAnimate(char*animName){animate=findAnimate(animName);animate->startIndex=animate->startIndex;//这个写的不对、明天去参考伟哥的写法//animate->curIndex=animate->startIndex;animate->isPlaying=true;animate->frameTimer=0;}voidCAnimation::setName_FrameIndex(char*name,UINTstartIndex,UINTendIndex){CAnimate*anim=findAnimate(name);anim=newCAnimate(fileName,rows,cols);//如果为空就new一个对象压进去。并且把名字设置好anim->setName(name);//设置动画名字anim->setParent(this);//CAnimation是CNode的子类,子类拥有父类的所有数据,所以压入CAnimation就等同于压入了CNode。anim->setFrameIndex(startIndex,endIndex);anim->frameTimer=0;animateList.push_back(anim);//压进链表setAnimate(name);//设置动画}voidCAnimation::draw{Matrix3scaleMatrix;Matrix3rotateMatrix;Matrix3transMatrix;//放缩图片Scale(scaleMatrix,scale.x,scale.y);//水平翻转if(flip==true)scaleMatrix._11*=-1;//旋转图片Rotate(rotateMatrix,angle);//平移图片到我们的指定位置Translate(transMatrix,pos.x,pos.y);local_matrix=scaleMatrix*rotateMatrix*transMatrix;if(parent==NULL){world_color=local_color;world_matrix=local_matrix;}else{sColorcol=parent->getWorldColor;world_color.r=local_color.r*col.r;world_color.g=local_color.g*col.g;world_color.b=local_color.b*col.b;world_color.a=local_color.a*col.a;world_matrix=local_matrix*parent->getWorldMatrix;}if(visible==false)return;animate->draw;}voidCAnimation::setCurrentAllanchor(floatox,floatoy){}voidCAnimation::setMovementEventCallFunc(animation_selectorfun_movementEvent){listener_movementEvent=fun_movementEvent;}voidCAnimation::animateEvent(CAnimate*animate,MovementEventtype){if(listener_movementEvent){if(parent!=NULL)(parent->*listener_movementEvent)(this,type,animate->name);else(this->*listener_movementEvent)(this,type,animate->name);}}RECTCAnimation::getBoundBox{returnanimate->getBoundBox;}CAnimation::~CAnimation{}}
谢谢大家
上一篇:打金传奇端游排行,攻略
下一篇:热血传奇: 石墓入口旁边的那口深井原来和邪恶蜈蚣有关系
哈哈哈 子弹越打越多了
.
《刺客信条: 黑旗 记忆重置》回应DLC比本体贵: DLC非必须
当臭猫扶贫神秘嘉豪号主!
原神: 7.0奥黛塔定位反转! 并非木偶专属, 冰神设计成最大悬念
哪辆车能不被28吨钢卷压成废铁? 哪辆车能不被28吨钢卷压成废铁?
原神: 新超导木偶队顶配配装攻略! 告别刮痧与充能卡顿