3.2 Joystick 摇杆控件

******************************** Joystick.h ****************************  #ifndef __Joystick__ #define __Joystick__ #include "cocos2d.h" USING_NS_CC; enum JoystickEnum {     DEFAULT,     D_UP,     D_DOWN,     D_LEFT,     D_RIGHT,     D_LEFT_UP,     D_LEFT_DOWN,     D_RIGHT_UP,     D_RIGHT_DOWN }; class Joystick : public Layer { public:     /** 启动摇杆器 */     void onRun();     /** 清除数据 */     void onDisable();     /** 设置死亡半径,即超出半径将摇杆器失效 */     void setDieRadius(float radius);     /** 设置无效区域半径(如果在无效区域内,将重置) */     void setFailRadius(float radius);     /** 是否显示底盘和触点 */     void setVisibleJoystick(bool visible);     /** 是否自由变换摇杆器的位置,即在屏幕上每一次按下鼠标时的座标将是摇杆器的座标,移动时将不改变摇杆器座标,直到下次按下鼠标 */     void setAutoPosition(bool value);     /** 回调函数指针 */     std::function onDirection;     /** 静态创建函数(需要传入底盘和触点图片路径) */     static Joystick* create(std::string chassisPath,std::string dotPath);     /** 初始化摇杆器(需要传入底盘和触点图片路径) */     void initWithJoystick(std::string chassisPath,std::string dotPath); protected:     /** 有效区域半径 */     float _radius;     /** 失效区域半径 */     float _failradius;     /** 是否移出有效区域 */     bool isMoveOut;     /** 是否存在有效区域半径 */     bool isDieRadius;     /** 是否自由变换摇杆器座标 */     bool isAutoPosition;     /** 方向 */     JoystickEnum _direction;     /** 底盘 */     Sprite* _chassis;     /** 触点 */     Sprite* _touchDot;     //*定义一个监听对象*/     EventListenerTouchOneByOne* listener;          bool onTouchBegan(Touch* touch,Event* event);     void onTouchMoved(Touch* touch,Event* event);     void onTouchEnded(Touch* touch,Event* event);     /**      1、设置触点,并判断是否在无效区域内(如果在无效区域内,将重置)     2、发送角度变化(如果不在无效区域内) */     void setTouchDotPosition(Vec2 vec1,Vec2 vec2);     /**      1、计算摇杆器八方向     2、发送角度变化,回调弧度变化函数 */     void changeAngle( Vec2 position );     /** 回调注册的监听函数 */     void callDirectionFun();     /** 重置(当弧度不是 DEFAULT时才重置) */     void resetState();      }; #endif ***********************   Joystick.cpp   ****************************** #include "Joystick.h" /** 静态创建函数(需要传入底盘和触点图片路径) */ Joystick* Joystick::create(std::string chassisPath,std::string dotPath) {     auto joystick = new Joystick();/*创建一个对象*/     joystick->initWithJoystick(chassisPath,dotPath);/*调用初始化函数*/     return joystick;/*返回对象*/ } /** 初始化摇杆器(需要传入底盘和触点图片路径) */ void Joystick::initWithJoystick(std::string chassisPath,std::string dotPath) {     _chassis = Sprite::create(chassisPath);/** 底盘 */     this->addChild(_chassis,0);     _touchDot = Sprite::create(dotPath);/** 触点 */     this->addChild(_touchDot,1);     isDieRadius = false;/** 是否存在有效区域半径 */     isAutoPosition = false;/** 是否自由变换摇杆器座标 */     isMoveOut = false;/** 是否移出有效区域 */     _direction = DEFAULT;/*方向默认不动*/ } /** 启动摇杆器 */ void Joystick::onRun() {     listener = EventListenerTouchOneByOne::create();     listener->setSwallowTouches(false);     listener->onTouchBegan = CC_CALLBACK_2(Joystick::onTouchBegan,this);     listener->onTouchMoved = CC_CALLBACK_2(Joystick::onTouchMoved,this);     listener->onTouchEnded = CC_CALLBACK_2(Joystick::onTouchEnded,this);     this->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this); } bool Joystick::onTouchBegan(Touch* touch,Event* event) {     /*将触摸点转换为本地座标  左下角为原点*/     Vec2 locationInNode = this->convertToNodeSpace(touch->getLocation());     if( isAutoPosition )     {         this->setPosition(touch->getLocation());         return true;     }     if( isAutoPosition==false && isDieRadius )     {         if( locationInNode.getLength() > _radius )         {             return false;         }     }     _touchDot->setPosition(locationInNode);     if( locationInNode.getLength() > _failradius )     {         changeAngle(locationInNode);     }     return true; } void Joystick::onTouchMoved(Touch* touch,Event* event) {     Vec2 locationInNode = this->convertToNodeSpace(touch->getLocation());     if( isDieRadius )     {         if( locationInNode.getLength() < _radius )         {             if( isMoveOut )             {                 _touchDot->setPosition(locationInNode);                 isMoveOut = false;             }             setTouchDotPosition(locationInNode,_touchDot->getPosition() + touch->getDelta());             return;         }     }     else     {         setTouchDotPosition(locationInNode,_touchDot->getPosition() + touch->getDelta());         return;     }          isMoveOut = true;     _touchDot->setPosition(0,0);     resetState(); } void Joystick::onTouchEnded(Touch* touch,Event* event) {     _touchDot->setPosition(0,0);     isMoveOut = false;     resetState(); } void Joystick::setTouchDotPosition(Vec2 vec1,Vec2 vec2) {     _touchDot->setPosition(vec2);     if( _failradius>0 )     {         if( vec1.getLength() < _failradius )         {             resetState();             return;         }     }     changeAngle(vec1); }  /** 设置死亡半径,即超出半径将摇杆器失效 */ void Joystick::setDieRadius(float radius) {     _radius = radius;     isDieRadius = true; } void Joystick::setAutoPosition(bool value) {     isAutoPosition = value; }  /** 设置无效区域半径(如果在无效区域内,将重置) */ void Joystick::setFailRadius(float radius) {     _failradius = radius; } /** 清除数据 */ void Joystick::onDisable() {     this->_eventDispatcher->removeEventListener(listener);     isDieRadius = false;     isAutoPosition = false;     isMoveOut = false; } void Joystick::changeAngle( Vec2 position ) {     auto angle = CC_RADIANS_TO_DEGREES(position.getAngle());     if(angle > -22.5 && angle < 22.5)     {         _direction=D_RIGHT;     }     else if(angle > 22.5 && angle < 67.5)     {         _direction=D_RIGHT_UP;     }     else if(angle > 67.5 && angle < 112.5)     {         _direction=D_UP;     }     else if(angle > 112.5 && angle < 157.5)     {         _direction=D_LEFT_UP;     }     else if((angle > 157.5 && angle < 180)||(angle < -157.5 && angle > -180))     {         _direction=D_LEFT;     }     else if(angle < -112.5 && angle > -157.5)     {         _direction=D_LEFT_DOWN;     }     else if(angle < -67.5 && angle > -112.5)     {         _direction=D_DOWN;     }     else if(angle < -22.5 && angle > -67.5)     {         _direction=D_RIGHT_DOWN;     }     callDirectionFun(); } void Joystick::callDirectionFun() {     if( onDirection )     {         onDirection(_direction);     } } void Joystick::resetState() {     if(_direction != DEFAULT)     {         _direction = DEFAULT;         callDirectionFun();     } } /** 是否显示底盘和触点 */ void Joystick::setVisibleJoystick(bool visible) {     _chassis->setVisible(visible);     _touchDot->setVisible(visible); } 在  HelloWord.h中   加个 void update(float dt); 在  HelloWord.cpp中 void HelloWorld::update(float dt) {/* D_UP,  D_DOWN,  D_LEFT,  D_RIGHT,  D_LEFT_UP,  D_LEFT_DOWN,  D_RIGHT_UP,  D_RIGHT_DOWN*/     switch (j->getDirection())     {     case 1:         log("D_UP");         break;     case 2:         log("D_DOWN");         break;     case 3:         log("D_LEFT");         break;     case 4:         log("D_RIGHT");         break;     case 5:         log("D_LEFT_UP");         break;     case 6:         log("D_LEFT_DOWN");         break;     case 7:         log("D_RIGHT_UP");         break;     case 8:         log("D_RIGHT_DOWN");         break;     default:         log("stop");         break;     } } 之后调用检检摇杆********************************** 在  HelloWord中调用Joystick ******************************************************************* 普通模式 auto joystick = Joystick::create("rocker.png","rocker_joy.png");//通过两张图片初始化控件     this->addChild(joystick);     joystick->setPosition(VisibleRect::leftBottom()+Vec2(200,200));//设置初始位置  joystick->onDirection=CC_CALLBACK_1(SceneMain::onDirection,this);//角度变化更新(onDirection(JoystickEnum enums))     joystick->onRun();//启动 **************************************************************** 存在死亡半径模式:(超出死亡半径将触点重置初始位置,移动失效) auto joystick = Joystick::create("rocker.png","rocker_joy.png");//通过两张图片初始化控件this->addChild(joystick); joystick->setPosition(VisibleRect::leftBottom()+Vec2(200,200));//设置初始位置 joystick->setDieRadius(60);//设置死亡半径(外圈) joystick->onDirection=CC_CALLBACK_1(SceneMain::onDirection,this);//角度变化更新(onDirection(JoystickEnum enums)) joystick->onRun();//启动 ******************************************************************* 设置失效半径:(在失效半径内将不会触发角度改变事件) auto joystick = Joystick::create("rocker.png","rocker_joy.png");//通过两张图片初始化控件 this->addChild(joystick); joystick->setPosition(VisibleRect::leftBottom()+Vec2(200,200));//设置初始位置 joystick->setDieRadius(60);//设置死亡半径(外圈) joystick->setFailRadius(30);//设置失效半径(内圈)  joystick->onDirection=CC_CALLBACK_1(SceneMain::onDirection,this);//角度变化更新(onDirection(JoystickEnum enums)) joystick->onRun();//启动 *-**************************************************************** 设置自由变换位置:以鼠标按下的座标为初始位置 auto joystick = Joystick::create("rocker.png","rocker_joy.png");//通过两张图片初始化控件 this->addChild(joystick); joystick->setPosition(VisibleRect::leftBottom()+Vec2(200,200));//设置初始位置 joystick->setAutoPosition(true);//是否自由改变座标 joystick->onDirection=CC_CALLBACK_1(SceneMain::onDirection,this);//角度变化更新 joystick->onRun();//启动 ********************************************************************* 设置隐藏摇杆:(不显示摇杆底盘和触点,一般会设置成自由改变位置) auto joystick = Joystick::create("rocker.png","rocker_joy.png");//通过两张图片初始化控件 this->addChild(joystick); joystick->setPosition(VisibleRect::leftBottom()+Vec2(200,200));//设置初始位置 joystick->setAutoPosition(true);//是否自由改变座标 joystick->setVisibleJoystick(false);//是否显示 joystick->onDirection=CC_CALLBACK_1(SceneMain::onDirection,this);//角度变化更新 joystick->onRun();//启动
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章