******************************** 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: /** ���u杆器 */ void onRun(); /** 清除��� */ void onDisable(); /** �O置死亡半�剑�即超出半��⒁「似魇�效 */ void setDieRadius(float radius); /** �O置�o效�^域半�剑ㄈ绻�在�o效�^域�龋��⒅刂茫� */ void setFailRadius(float radius); /** 是否�@示底�P和�|�c */ void setVisibleJoystick(bool visible); /** 是否自由��Q�u杆器的位置,即在屏幕上每一次按下鼠��r的座��⑹�u杆器的座�耍�移��r�⒉桓淖��u杆器座�耍�直到下次按下鼠�� */ void setAutoPosition(bool value); /** 回�{函�抵羔� */ std::function<void(JoystickEnum)> onDirection; /** �o�B��建函�担ㄐ枰��魅氲妆P和�|�c�D片路�剑� */ static Joystick* create(std::string chassisPath,std::string dotPath); /** 初始化�u杆器(需要�魅氲妆P和�|�c�D片路�剑� */ void initWithJoystick(std::string chassisPath,std::string dotPath); protected: /** 有效�^域半�� */ float _radius; /** 失效�^域半�� */ float _failradius; /** 是否移出有效�^域 */ bool isMoveOut; /** 是否存在有效�^域半�� */ bool isDieRadius; /** 是否自由��Q�u杆器座�� */ bool isAutoPosition; /** 方向 */ JoystickEnum _direction; /** 底�P */ Sprite* _chassis; /** �|�c */ Sprite* _touchDot; //*定义一个监听对象*/ EventListenerTouchOneByOne* listener; bool onTouchBegan(Touch* touch,Event* event); void onTouchMoved(Touch* touch,Event* event); void onTouchEnded(Touch* touch,Event* event); /** 1、�O置�|�c,并判�嗍欠裨�o效�^域�龋ㄈ绻�在�o效�^域�龋��⒅刂茫� 2、�l送角度�化(如果不在�o效�^域�龋� */ void setTouchDotPosition(Vec2 vec1,Vec2 vec2); /** 1、�算�u杆器八方向 2、�l送角度�化,回�{弧度�化函�� */ void changeAngle( Vec2 position ); /** 回�{�]�缘谋O�函�� */ void callDirectionFun(); /** 重置(��弧度不是 DEFAULT�r才重置) */ void resetState(); }; #endif *********************** Joystick.cpp ****************************** #include "Joystick.h" /** �o�B��建函�担ㄐ枰��魅氲妆P和�|�c�D片路�剑� */ Joystick* Joystick::create(std::string chassisPath,std::string dotPath) { auto joystick = new Joystick();/*创建一个对象*/ joystick->initWithJoystick(chassisPath,dotPath);/*调用初始化函数*/ return joystick;/*返回对象*/ } /** 初始化�u杆器(需要�魅氲妆P和�|�c�D片路�剑� */ void Joystick::initWithJoystick(std::string chassisPath,std::string dotPath) { _chassis = Sprite::create(chassisPath);/** 底�P */ this->addChild(_chassis,0); _touchDot = Sprite::create(dotPath);/** �|�c */ this->addChild(_touchDot,1); isDieRadius = false;/** 是否存在有效�^域半�� */ isAutoPosition = false;/** 是否自由��Q�u杆器座�� */ isMoveOut = false;/** 是否移出有效�^域 */ _direction = DEFAULT;/*方向默认不动*/ } /** ���u杆器 */ 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); } /** �O置死亡半�剑�即超出半��⒁「似魇�效 */ void Joystick::setDieRadius(float radius) { _radius = radius; isDieRadius = true; } void Joystick::setAutoPosition(bool value) { isAutoPosition = value; } /** �O置�o效�^域半�剑ㄈ绻�在�o效�^域�龋��⒅刂茫� */ 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(); } } /** 是否�@示底�P和�|�c */ 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");//通�^����D片初始化控件 this->addChild(joystick); joystick->setPosition(VisibleRect::leftBottom()+Vec2(200,200));//�O置初始位置 joystick->onDirection=CC_CALLBACK_1(SceneMain::onDirection,this);//角度�化更新(onDirection(JoystickEnum enums)) joystick->onRun();//��� **************************************************************** 存在死亡半�侥J剑海ǔ�出死亡半��⒂|�c重置初始位置,移�邮�效) auto joystick = Joystick::create("rocker.png","rocker_joy.png");//通�^����D片初始化控件this->addChild(joystick); joystick->setPosition(VisibleRect::leftBottom()+Vec2(200,200));//�O置初始位置 joystick->setDieRadius(60);//�O置死亡半�剑ㄍ馊Γ� joystick->onDirection=CC_CALLBACK_1(SceneMain::onDirection,this);//角度�化更新(onDirection(JoystickEnum enums)) joystick->onRun();//��� ******************************************************************* �O置失效半�剑海ㄔ谑�效半���⒉���|�l角度改�事件) auto joystick = Joystick::create("rocker.png","rocker_joy.png");//通�^����D片初始化控件 this->addChild(joystick); joystick->setPosition(VisibleRect::leftBottom()+Vec2(200,200));//�O置初始位置 joystick->setDieRadius(60);//�O置死亡半�剑ㄍ馊Γ� joystick->setFailRadius(30);//�O置失效半�剑�热Γ� joystick->onDirection=CC_CALLBACK_1(SceneMain::onDirection,this);//角度�化更新(onDirection(JoystickEnum enums)) joystick->onRun();//��� *-**************************************************************** �O置自由��Q位置:以鼠�税聪碌淖���槌跏嘉恢� auto joystick = Joystick::create("rocker.png","rocker_joy.png");//通�^����D片初始化控件 this->addChild(joystick); joystick->setPosition(VisibleRect::leftBottom()+Vec2(200,200));//�O置初始位置 joystick->setAutoPosition(true);//是否自由改�座�� joystick->onDirection=CC_CALLBACK_1(SceneMain::onDirection,this);//角度�化更新 joystick->onRun();//��� ********************************************************************* �O置�[藏�u杆:(不�@示�u杆底�P和�|�c,一般���O置成自由改�位置) auto joystick = Joystick::create("rocker.png","rocker_joy.png");//通�^����D片初始化控件 this->addChild(joystick); joystick->setPosition(VisibleRect::leftBottom()+Vec2(200,200));//�O置初始位置 joystick->setAutoPosition(true);//是否自由改�座�� joystick->setVisibleJoystick(false);//是否�@示 joystick->onDirection=CC_CALLBACK_1(SceneMain::onDirection,this);//角度�化更新 joystick->onRun();//���