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();//啟動
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章