RPG游戏的遥控杆控制主角
先看代码:(参考赵云要格斗)
#ifndef __HROCKER_H__ #define __HROCKER_H__ #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); 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 *Touch, Event *Event); virtual void onTouchMoved(Touch *Touch, Event *Event); virtual void onTouchEnded(Touch *Touch, Event *Event); }; #endif</span>接下来是 遥控杆.cpp:
#include "HRocker.h" #define PI 3.1415926535898 HRocker::HRocker(void) { rocketRun = false; } HRocker::~HRocker(void) { } //创建摇杆(摇杆的操作题图片资源名,摇杆背景图片资源名,起始坐标) HRocker* HRocker::createHRocker(const char *rockerImageName, const char *rockerBGImageName, 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, const char* rockerBGImageName, Point position) { Sprite *spRockerBG = Sprite::create(rockerBGImageName); spRockerBG->setPosition(position); spRockerBG->setVisible(false); addChild(spRockerBG, 0, 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 touchListener = EventListenerTouchOneByOne::create(); touchListener->setSwallowTouches(true); touchListener->onTouchBegan = CC_CALLBACK_2(HRocker::onTouchBegan, this); touchListener->onTouchMoved = CC_CALLBACK_2(HRocker::onTouchMoved, this); touchListener->onTouchEnded = CC_CALLBACK_2(HRocker::onTouchEnded, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); //this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(mTouchlistener, this); //CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -1, _isStopOther); } //停止摇杆(隐藏摇杆,取消摇杆的触屏监听) void HRocker::stopRocker() { Sprite *rocker = (Sprite *)this->getChildByTag(tag_rocker); rocker->setVisible(false); Sprite * rockerBG = (Sprite *)this->getChildByTag(tag_rockerBG); rockerBG->setVisible(false); //CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); //this->getEventDispatcher()->removeAllEventListeners(); _eventDispatcher->removeEventListenersForTarget(this); } //获取当前摇杆与用户触屏点的角度 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; } Point getAngelePosition(float r, float angle){ return Vec2(r*cos(angle), r*sin(angle)); } //抬起事件 bool HRocker::onTouchBegan(Touch *Touch, Event *Event) { Point point = Touch->getLocation(); Sprite *rocker = (Sprite *)this->getChildByTag(tag_rocker); if (rocker->boundingBox().containsPoint(point)) isCanMove = true; return true; } //移动事件 void HRocker::onTouchMoved(Touch *Touch, Event *Event) { if (!isCanMove) { return; } Point point = Touch->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(ccpAdd(getAngelePosition(rockerBGR, angle), Vec2(rockerBGPosition.x, rockerBGPosition.y))); } else rocker->setPosition(point); //判断方向 if (angle >= -PI / 4 && angle<PI / 4) { rocketDirection = rocker_right; rocketRun = false; } else if (angle >= PI / 4 && angle<3 * PI / 4) { rocketDirection = rocker_up; } else if ((angle >= 3 * PI / 4 && angle <= PI) || (angle >= -PI&&angle<-3 * PI / 4)) { rocketDirection = rocker_left; rocketRun = true; } else if (angle >= -3 * PI / 4 && angle<-PI / 4) { rocketDirection = rocker_down; } } //离开事件 void HRocker::onTouchEnded(Touch *Touch, Event *Event) { if (!isCanMove) { return; } Sprite *rockerBG = (Sprite*)this->getChildByTag(tag_rockerBG); Sprite *rocker = (Sprite*)this->getChildByTag(tag_rocker); rocker->stopAllActions(); rocker->runAction(MoveTo::create(0.08f, rockerBG->getPosition())); isCanMove = false; rocketDirection = rocker_stay; }</span>英雄.h:
#ifndef __HERO_H__ #define __HERO_H__ #include "cocos2d.h" #include"HRocker.h" #include "KnapsackData.h" using namespace std; using namespace cocos2d; class Hero :public Layer { public: Hero(); ~Hero(); //根据图片创建英雄 void InitHeroSprite(char *hero_name); //设置动画,num为图片数目, run_direction为精灵脸朝向, 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_direction); //停止动画 void StopAnimation(); //判断是否在跑动画 bool IsRunning; //英雄运动方向 bool HeroDirection; //英雄是否碰撞 bool isCrash = false; //把精灵返回出去 Sprite* getHero(); //背包道具拥有类 vector<KnapsackData*> knaDataVec; CREATE_FUNC(Hero); private: Size visibleSize = Director::getInstance()->getVisibleSize();//获取舞台高度宽度 //用来保存初始状态的精灵图片名称 char *Hero_name; //精灵 Sprite *m_HeroSprite; }; #endif
英雄.cpp:
#include "Hero.h" USING_NS_CC; Hero::Hero() { IsRunning = false; HeroDirection = false; Hero_name = NULL; } Hero::~Hero() { } void Hero::InitHeroSprite(char *hero_name) { Hero_name = hero_name; this->m_HeroSprite = Sprite::create(Hero_name); this->addChild(m_HeroSprite); this->setPosition(Vec2(visibleSize.width*0.39, visibleSize.height*0.63)); this->setContentSize(Size(40, 43)); } //动画播放,可以是跑、攻击、死亡、受伤等 void Hero::SetAnimation(const char *name_plist, const char *name_png, const char *name_each, const unsigned int num, bool run_direction) { if (HeroDirection != run_direction) { HeroDirection = run_direction; m_HeroSprite->setFlippedX(run_direction); } if (IsRunning) return; //将图片加载到精灵帧缓存池 SpriteFrameCache *m_frameCache = SpriteFrameCache::getInstance(); m_frameCache->addSpriteFramesWithFile(name_plist, name_png); //用一个列表保存所有的CCSpriteFrameCache Vector<SpriteFrame*> frameArray; unsigned int i; for (i = 2; i <= num; i++) { SpriteFrame *frame = m_frameCache->getSpriteFrameByName(__String::createWithFormat("%s%d.png", name_each, i)->getCString()); frameArray.pushBack(frame); } //使用列表创建动画对象 Animation *animation = Animation::createWithSpriteFrames(frameArray); if (HeroDirection != run_direction) { HeroDirection = run_direction; } //表示无限循环播放 animation->setLoops(-1); //每两张图片的时间隔,图片数目越少,间隔最小就越小 animation->setDelayPerUnit(0.1f); //将动画包装成一个动作 Animate *animate = Animate::create(animation); m_HeroSprite->runAction(animate); IsRunning = true; } //自己设定英雄包围盒 /*Rect Hero::getBoundingBoxSp(){ return Rect(m_HeroSprite->getPositionX(), m_HeroSprite->getPositionY(), 80, 83); }*/ Sprite* Hero::getHero() { if (m_HeroSprite) { return m_HeroSprite; } else { m_HeroSprite = Sprite::create("zhoayun.png"); return m_HeroSprite; } } void Hero::StopAnimation() { if (!IsRunning) { return; } m_HeroSprite->stopAllActions(); //恢复精灵原来的初始化贴图 //把原来的精灵删除掉 this->removeChild(m_HeroSprite, true); //恢复精灵原来的贴图样子 m_HeroSprite = CCSprite::create(Hero_name);//恢复精灵原来的贴图样子 m_HeroSprite->setFlippedX(HeroDirection); this->addChild(m_HeroSprite); IsRunning = false; }分别在GameScene中创建层对象后:
帧计时器中加入:
这样,遥控杆的方向就 和 英雄主角绑定了
switch (Hrocker->rocketDirection) { case 1: hero->SetAnimation("run_animation.plist", "run_animation.png", "run_", 8, Hrocker->rocketRun); hero->setPosition(Vec2(hero->getPosition().x + 3, hero->getPosition().y)); //向右走 break; case 2: hero->SetAnimation("run_animation.plist", "run_animation.png", "run_", 8, Hrocker->rocketRun); hero->setPosition(Vec2(hero->getPosition().x, hero->getPosition().y + 3)); //向上走 break; case 3: hero->SetAnimation("run_animation.plist", "run_animation.png", "run_", 8, Hrocker->rocketRun); hero->setPosition(Vec2(hero->getPosition().x - 3, hero->getPosition().y)); //向左走 break; case 4: hero->SetAnimation("run_animation.plist", "run_animation.png", "run_", 8, Hrocker->rocketRun); hero->setPosition(Vec2(hero->getPosition().x, hero->getPosition().y - 3)); //向下走 break; default: hero->StopAnimation();//停止所有动画和运动 break; }
这样,遥控杆的方向就 和 英雄主角绑定了
作者:qq_35576100 发表于2016/10/26 17:33:39 原文链接
阅读:29 评论:0 查看评论