首先非常感谢Evankaka大神的无私奉献,传送门:Evankaka神的博客。
在学习大神开源的《赵云要格斗》demo时,为了方便和我一样的小白菜鸟,将其改写为Cocos2d-x3.3版本(根据我个人的理解
做出了一些改动),现在已经改到Evankaka教程的第三节,工作任务少点以后还会陆续更新。
Hero.h:
基于组合优与集成,以及轻量的理念,此类继承自Node即可。
在Hero类里我对SetAnimation,以及AttackAnimation进行了改写,添加了一个函数getAnimation来获取pList文件得到的动作,将其
返回给SetAnimation,AttackAnimation使用。
添加RunEnd运来对run动作结束进行监听。
//// Hero.h// fight//// Created by Cytzrs on 15/2/2.////#ifndef __fight__Hero__#define __fight__Hero__#include <iostream>#include "cocos-ext.h"using namespace cocos2d;USING_NS_CC_EXT;class Hero:public cocos2d::Node{public: Hero(voID); ~Hero(voID); //根据图片名创建英雄 voID InitHeroSprite(char *hero_name); //设置动画,num为图片数目,run_directon为精灵脸朝向,false朝右,name_each为name_png中每一小张图片的公共名称部分 voID SetAnimation(const char *name_pList,const char *name_png,const char *name_each,const unsigned int num,bool run_directon); //停止动画 voID StopAnimation(); //判断是否在跑动画 bool IsRunning; bool IsAttack; //英雄运动的方向 bool HeroDirecton; CREATE_FUNC(Hero); //判断英雄是否运动到了窗口的中间位置,visibleSize为当前窗口的大小 bool JudgePositona(Size visibleSize); voID AttackAnimation(const char *name_pList,bool run_directon); Animation* getAnimation(const char *name_pList,bool run_directon); voID RunEnd(); voID AttackEnd();private: Sprite* m_HeroSprite;//精灵 char *Hero_name;//用来保存初始状态的精灵图片名称};#endif /* defined(__fight__Hero__) */
Hero.cpp
//// Hero.cpp// fight//// Created by Cytzrs on 15/2/2.////#include "Hero.h"#include <String.h>USING_NS_CC;USING_NS_CC_EXT;Hero::Hero(voID){ IsRunning=false;//没在放动画 IsAttack = false; HeroDirecton=false;//向右运动 Hero_name=NulL;}Hero::~Hero(voID){ }voID Hero::InitHeroSprite(char *hero_name){ Hero_name=hero_name; this->m_HeroSprite=Sprite::create(hero_name); this->addChild(m_HeroSprite);}//动画播放,可以是跑、攻击、死亡、受伤等voID Hero::SetAnimation(const char *name_pList,unsigned int num,bool run_directon){ if(HeroDirecton!=run_directon) { HeroDirecton=run_directon; m_HeroSprite->setFlippedX(run_directon); } if(IsRunning) return; auto ani = getAnimation(name_pList,name_png,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::RunEnd(){ IsRunning=false;}Animation* Hero::getAnimation(const char *name_pList,bool run_directon){ auto cache = SpriteFrameCache::getInstance(); cache->addSpriteFramesWithfile(name_pList,name_png); // auto sprite = Sprite::createWithSpriteFramename(String::createWithFormat("%s1.png",name_each)->getCString()); m_HeroSprite->setTexture(CCString::createWithFormat("%s1.png",name_each)->getCString()); auto spriteBatch = SpriteBatchNode::create(name_png); // spriteBatch->addChild(sprite); addChild(spriteBatch); Vector<SpriteFrame*> animFrames(num); for(int i = 1; i < num; i++) { // Obtain frames by alias name auto frame = cache->getSpriteFrameByname(String::createWithFormat("%s%d.png",i)->getCString()); animFrames.pushBack(frame); } auto animation = Animation::createWithSpriteFrames(animFrames,0.3f); return animation;}voID Hero::StopAnimation(){ if(!IsRunning) return; m_HeroSprite->stopAllActions();//当前精灵停止所有动画 // //恢复精灵原来的初始化贴图// this->removeChild(m_HeroSprite);//把原来的精灵删除掉// m_HeroSprite=Sprite::create(Hero_name);//恢复精灵原来的贴图样子// m_HeroSprite->setFlippedX(HeroDirecton);// this->addChild(m_HeroSprite); IsRunning=false;}bool Hero::JudgePositona (Size visibleSize){ if(this->getpositionX()!=visibleSize.wIDth/2)//精灵到达左边 return false; else return true;//到达中间位置}voID Hero::AttackAnimation(const char *name_pList,bool run_directon){ if(IsAttack) return; auto ani = getAnimation(name_pList,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,NulL); // 14 frames * 1sec = 14 seconds m_HeroSprite->runAction(act); IsAttack=true; }voID Hero::AttackEnd(){ //恢复精灵原来的初始化贴图// this->removeChild(m_HeroSprite);//把原来的精灵删除掉// m_HeroSprite=Sprite::create(Hero_name);//恢复精灵原来的贴图样子// m_HeroSprite->setFlippedX(HeroDirecton);// this->addChild(m_HeroSprite); IsAttack=false;}摇杆类HRocker.h
//// HRocker.h// fight//// Created by Cytzrs on 15/2/2.////#ifndef __fight__HRocker__#define __fight__HRocker__#include <iostream>#include "cocos2d.h"using namespace cocos2d;//用于标识摇杆与摇杆的背景typedef enum{ tag_rocker,tag_rockerBG,}tagForHRocker;//用于标识摇杆方向typedef enum{ rocker_stay,rocker_right,rocker_up,rocker_left,rocker_down,}tagDirecton;class HRocker:public Layer{public: HRocker(voID); ~HRocker(voID); //创建摇杆(摇杆的 *** 作题图片资源名,摇杆背景图片资源名,起始坐标) static HRocker* createHRocker(const char *rockerImagename,const char *rockerBGImagename,Point position); //启动摇杆(显示摇杆、监听摇杆触屏事件) voID startRocker(bool _isstopOther); //停止摇杆(隐藏摇杆,取消摇杆的触屏监听) voID stopRocker(); //判断控制杆方向,用来判断精灵上、下、左、右运动 int rocketDirection; //当前人物行走方向,用来判断精灵的朝向,精灵脸朝右还是朝左 bool rocketRun; CREATE_FUNC(HRocker); voID update(float dt);private: //自定义初始化函数 voID rockerInit(const char* rockerImagename,const char* rockerBGImagename,Point position); //是否可 *** 作摇杆 bool isCanMove; //获取当前摇杆与用户触屏点的角度 float geTrad(Point pos1,Point pos2); //摇杆背景的坐标 Point rockerBGposition; //摇杆背景的半径 float rockerBGR; //触屏事件 virtual bool ontouchBegan(touch *ptouch,Event *pEvent); virtual voID ontouchmoved(touch *ptouch,Event *pEvent); virtual voID ontouchended(touch *ptouch,Event *pEvent); };#endif /* defined(__fight__HRocker__) */HRocker.cpp
//// HRocker.cpp// fight//// Created by Cytzrs on 15/2/2.////#include "HRocker.h"const double PI=3.1415;HRocker::HRocker(voID){ rocketRun=false;}HRocker::~HRocker(voID){}//创建摇杆(摇杆的 *** 作题图片资源名,摇杆背景图片资源名,起始坐标)HRocker* HRocker::createHRocker(const char *rockerImagename,Point position){ HRocker *layer = HRocker::create(); if (layer) { layer->rockerInit(rockerImagename,rockerBGImagename,position); return layer; } CC_SAFE_DELETE(layer); return NulL;}//自定义初始化函数voID HRocker::rockerInit(const char* rockerImagename,Point position){ Sprite *spRockerBG = Sprite::create(rockerBGImagename); spRockerBG->setposition(position); spRockerBG->setVisible(false); addChild(spRockerBG,tag_rockerBG); Sprite *spRocker = Sprite::create(rockerImagename); spRocker->setposition(position); spRocker->setVisible(false); addChild(spRocker,1,tag_rocker); rockerBGposition = position; rockerBGR = spRockerBG->getContentSize().wIDth*0.5;// rocketDirection=-1;//表示摇杆方向不变}//启动摇杆(显示摇杆、监听摇杆触屏事件)voID HRocker::startRocker(bool _isstopOther){ Sprite *rocker = (Sprite*)this->getChildByTag(tag_rocker); rocker->setVisible(true); Sprite *rockerBG = (Sprite *)this->getChildByTag(tag_rockerBG); rockerBG->setVisible(true); auto Listener = EventListenertouchOneByOne::create(); Listener->ontouchBegan = CC_CALLBACK_2(HRocker::ontouchBegan,this); Listener->ontouchmoved = CC_CALLBACK_2(HRocker::ontouchmoved,this); Listener->ontouchended = CC_CALLBACK_2(HRocker::ontouchended,this); Director::getInstance()->getEventdispatcher()->addEventListenerWithSceneGraPHPriority(Listener,this);}//停止摇杆(隐藏摇杆,取消摇杆的触屏监听)voID HRocker::stopRocker(){ Sprite *rocker = (Sprite *)this->getChildByTag(tag_rocker); rocker->setVisible(false); Sprite * rockerBG = (Sprite *)this->getChildByTag(tag_rockerBG); rockerBG->setVisible(false); Director::getInstance()->getEventdispatcher()->removeAllEventListeners();}//获取当前摇杆与用户触屏点的角度float HRocker::geTrad(Point pos1,Point pos2){ float px1 = pos1.x; float py1 = pos1.y; float px2 = pos2.x; float py2 = pos2.y; //得到两点x的距离 float x = px2 - px1; //得到两点y的距离 float y = py1 - py2; //算出斜边长度 float xIE = sqrt(pow(x,2) + pow(y,2)); //得到这个角度的余弦值(通过三角函数中的店里:角度余弦值=斜边/斜边) float cosAngle = x / xIE; //通过反余弦定理获取到期角度的弧度 float rad = acos(cosAngle); //注意:当触屏的位置Y坐标<摇杆的Y坐标,我们要去反值-0~-180 if (py2 < py1) { rad = -rad; } return rad;}Vec2 getAngeleposition(float r,float angle){ return Vec2(r*cos(angle),r*sin(angle));}//抬起事件bool HRocker::ontouchBegan(touch *ptouch,Event *pEvent){ Point point = ptouch->getLocation(); Sprite *rocker = (Sprite *)this->getChildByTag(tag_rocker); if (rocker->boundingBox().containsPoint(point)) { isCanMove = true; log("begin"); } return true;}//移动事件voID HRocker::ontouchmoved(touch *ptouch,Event *pEvent){ if (!isCanMove) { return; } Point point = ptouch->getLocation(); Sprite *rocker = (Sprite *)this->getChildByTag(tag_rocker); //得到摇杆与触屏点所形成的角度 float angle = geTrad(rockerBGposition,point); //判断两个圆的圆心距是否大于摇杆背景的半径 if (sqrt(pow((rockerBGposition.x - point.x),2) + pow((rockerBGposition.y - point.y),2)) >= rockerBGR) { //保证内部小圆运动的长度限制 rocker->setposition(getAngeleposition(rockerBGR,angle) + Vec2(rockerBGposition.x,rockerBGposition.y)); // log("touch"); } else { //当没有超过,让摇杆跟随用户触屏点移动即可 rocker->setposition(point); //log("touch"); } //判断方向 if(angle>=-PI/4&&angle<PI/4) { rocketDirection=rocker_right; rocketRun=false; log("%d",rocketDirection); } else if(angle>=PI/4&&angle<3*PI/4) { rocketDirection=rocker_up; log("%d",rocketDirection); } else if((angle>=3*PI/4&&angle<=PI)||(angle>=-PI&&angle<-3*PI/4)) { rocketDirection=rocker_left; rocketRun=true; log("%d",rocketDirection); } else if(angle>=-3*PI/4&&angle<-PI/4) { rocketDirection=rocker_down; log("%d",rocketDirection); }}//离开事件voID HRocker::ontouchended(touch *ptouch,Event *pEvent){ if (!isCanMove) { return; } Sprite *rockerBG = (Sprite*)this->getChildByTag(tag_rockerBG); Sprite *rocker = (Sprite*)this->getChildByTag(tag_rocker); rocker->stopAllActions(); rocker->runAction(CCMoveto::create(0.08f,rockerBG->getposition())); isCanMove = false; rocketDirection=rocker_stay; log("%d",rocketDirection); log("end");}voID HRocker::update(float dt){ if(isCanMove) { }}
最后一步在Scene中添加update函数:
voID HelloWorld::update(float delta){ switch(rocker->rocketDirection) { case 1: hero->SetAnimation("run_animation.pList","run_animation.png",8,rocker->rocketRun); hero->setposition(Vec2(hero->getposition().x+1,hero->getposition().y)); break; case 2: hero->SetAnimation("run_animation.pList",rocker->rocketRun); hero->setposition(Vec2(hero->getposition().x,hero->getposition().y+1)); break; case 3: hero->SetAnimation("run_animation.pList",rocker->rocketRun); hero->setposition(Vec2(hero->getposition().x-1,hero->getposition().y)); break; case 4: hero->SetAnimation("run_animation.pList",hero->getposition().y-1)); break; default: hero->StopAnimation(); break; }}
PS:多写博客,帮助自己,方便他人!
总结以上是内存溢出为你收集整理的Cocos2d-X 3.4版-虚拟摇杆控制精灵上下左右《赵云要格斗》全部内容,希望文章能够帮你解决Cocos2d-X 3.4版-虚拟摇杆控制精灵上下左右《赵云要格斗》所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)