********************************Joystick.h****************************#ifndef__Joystick__#define__Joystick__#include"cocos2d.h"USING_NS_CC;enumJoystickEnum{DEFAULT,D_UP,D_DOWN,D_LEFT,D_RIGHT,D_LEFT_UP,D_LEFT_DOWN,D_RIGHT_UP,D_RIGHT_DOWN};classJoystick:publicLayer{public:/**啟動搖杆器*/voidonRun();/**清除數據*/voidonDisable();/**設置死亡半徑,即超出半徑將摇杆器失效*/voidsetDieRadius(floatradius);/**設置無效區域半徑(如果在無效區域內,將重置)*/voidsetFailRadius(floatradius);/**是否顯示底盤和觸點*/voidsetVisibleJoystick(boolvisible);/**是否自由變換搖杆器的位置,即在屏幕上每一次按下鼠標時的座標將是搖杆器的座標,移動時將不改變搖杆器座標,直到下次按下鼠標*/voidsetAutoPosition(boolvalue);/**回調函數指針*/std::function<void(JoystickEnum)>onDirection;/**靜態創建函數(需要傳入底盤和觸點圖片路徑)*/staticJoystick*create(std::stringchassisPath,std::stringdotPath);/**初始化搖杆器(需要傳入底盤和觸點圖片路徑)*/voidinitWithJoystick(std::stringchassisPath,std::stringdotPath);protected:/**有效區域半徑*/float_radius;/**失效區域半徑*/float_failradius;/**是否移出有效區域*/boolisMoveOut;/**是否存在有效區域半徑*/boolisDieRadius;/**是否自由變換搖杆器座標*/boolisAutoPosition;/**方向*/JoystickEnum_direction;/**底盤*/Sprite*_chassis;/**觸點*/Sprite*_touchDot;//*定义一个监听对象*/EventListenerTouchOneByOne*listener;boolonTouchBegan(Touch*touch,Event*event);voidonTouchMoved(Touch*touch,Event*event);voidonTouchEnded(Touch*touch,Event*event);/**1、設置觸點,并判斷是否在無效區域內(如果在無效區域內,將重置)2、發送角度變化(如果不在無效區域內)*/voidsetTouchDotPosition(Vec2vec1,Vec2vec2);/**1、計算搖杆器八方向2、發送角度變化,回調弧度變化函數*/voidchangeAngle(Vec2position);/**回調註冊的監聽函數*/voidcallDirectionFun();/**重置(當弧度不是DEFAULT時才重置)*/voidresetState();};#endif***********************Joystick.cpp******************************#include"Joystick.h"/**靜態創建函數(需要傳入底盤和觸點圖片路徑)*/Joystick*Joystick::create(std::stringchassisPath,std::stringdotPath){autojoystick=newJoystick();/*创建一个对象*/joystick->initWithJoystick(chassisPath,dotPath);/*调用初始化函数*/returnjoystick;/*返回对象*/}/**初始化搖杆器(需要傳入底盤和觸點圖片路徑)*/voidJoystick::initWithJoystick(std::stringchassisPath,std::stringdotPath){_chassis=Sprite::create(chassisPath);/**底盤*/this->addChild(_chassis,0);_touchDot=Sprite::create(dotPath);/**觸點*/this->addChild(_touchDot,1);isDieRadius=false;/**是否存在有效區域半徑*/isAutoPosition=false;/**是否自由變換搖杆器座標*/isMoveOut=false;/**是否移出有效區域*/_direction=DEFAULT;/*方向默认不动*/}/**啟動搖杆器*/voidJoystick::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);}boolJoystick::onTouchBegan(Touch*touch,Event*event){/*将触摸点转换为本地坐标左下角为原点*/Vec2locationInNode=this->convertToNodeSpace(touch->getLocation());if(isAutoPosition){this->setPosition(touch->getLocation());returntrue;}if(isAutoPosition==false&&isDieRadius){if(locationInNode.getLength()>_radius){returnfalse;}}_touchDot->setPosition(locationInNode);if(locationInNode.getLength()>_failradius){changeAngle(locationInNode);}returntrue;}voidJoystick::onTouchMoved(Touch*touch,Event*event){Vec2locationInNode=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();}voidJoystick::onTouchEnded(Touch*touch,Event*event){_touchDot->setPosition(0,0);isMoveOut=false;resetState();}voidJoystick::setTouchDotPosition(Vec2vec1,Vec2vec2){_touchDot->setPosition(vec2);if(_failradius>0){if(vec1.getLength()<_failradius){resetState();return;}}changeAngle(vec1);}/**設置死亡半徑,即超出半徑將摇杆器失效*/voidJoystick::setDieRadius(floatradius){_radius=radius;isDieRadius=true;}voidJoystick::setAutoPosition(boolvalue){isAutoPosition=value;}/**設置無效區域半徑(如果在無效區域內,將重置)*/voidJoystick::setFailRadius(floatradius){_failradius=radius;}/**清除數據*/voidJoystick::onDisable(){this->_eventDispatcher->removeEventListener(listener);isDieRadius=false;isAutoPosition=false;isMoveOut=false;}voidJoystick::changeAngle(Vec2position){autoangle=CC_RADIANS_TO_DEGREES(position.getAngle());if(angle>-22.5&&angle<22.5){_direction=D_RIGHT;}elseif(angle>22.5&&angle<67.5){_direction=D_RIGHT_UP;}elseif(angle>67.5&&angle<112.5){_direction=D_UP;}elseif(angle>112.5&&angle<157.5){_direction=D_LEFT_UP;}elseif((angle>157.5&&angle<180)||(angle<-157.5&&angle>-180)){_direction=D_LEFT;}elseif(angle<-112.5&&angle>-157.5){_direction=D_LEFT_DOWN;}elseif(angle<-67.5&&angle>-112.5){_direction=D_DOWN;}elseif(angle<-22.5&&angle>-67.5){_direction=D_RIGHT_DOWN;}callDirectionFun();}voidJoystick::callDirectionFun(){if(onDirection){onDirection(_direction);}}voidJoystick::resetState(){if(_direction!=DEFAULT){_direction=DEFAULT;callDirectionFun();}}/**是否顯示底盤和觸點*/voidJoystick::setVisibleJoystick(boolvisible){_chassis->setVisible(visible);_touchDot->setVisible(visible);}在HelloWord.h中加个voidupdate(floatdt);在HelloWord.cpp中voidHelloWorld::update(floatdt){/*D_UP,D_DOWN,D_LEFT,D_RIGHT,D_LEFT_UP,D_LEFT_DOWN,D_RIGHT_UP,D_RIGHT_DOWN*/switch(j->getDirection()){case1:log("D_UP");break;case2:log("D_DOWN");break;case3:log("D_LEFT");break;case4:log("D_RIGHT");break;case5:log("D_LEFT_UP");break;case6:log("D_LEFT_DOWN");break;case7:log("D_RIGHT_UP");break;case8:log("D_RIGHT_DOWN");break;default:log("stop");break;}}之后调用检检摇杆**********************************在HelloWord中调用Joystick*******************************************************************普通模式autojoystick=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(JoystickEnumenums))joystick->onRun();//啟動****************************************************************存在死亡半徑模式:(超出死亡半徑將觸點重置初始位置,移動失效)autojoystick=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(JoystickEnumenums))joystick->onRun();//啟動*******************************************************************設置失效半徑:(在失效半徑內將不會觸發角度改變事件)autojoystick=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(JoystickEnumenums))joystick->onRun();//啟動*-****************************************************************設置自由變換位置:以鼠標按下的座標為初始位置autojoystick=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();//啟動*********************************************************************設置隱藏搖杆:(不顯示搖杆底盤和觸點,一般會設置成自由改變位置)autojoystick=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();//啟動