最近想做格斗游戏,那么就要有摇杆控件,不想去看别人的代码就自己写了个摇杆控件,实现起来很简单。
话不多说,看代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @H_404_49@ 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | #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 @H_301_240@ }; class Joystick: public Layer { : /**启动搖杆器*/ voID onRun(); /**清除数据*/ ondisable(); /**设置死亡半径,即超出半径將摇杆器失效*/ setDIERadius( float radius); /**设置无效区域半径(如果在无效区域內,將重置)*/ setFailRadius( radius); /**是否显示底盘和触点*/ setVisibleJoystick( bool visible); /**是否自由变换摇杆器的位置,即在屏幕上每一次按下鼠标时的坐标将是摇杆器的坐标,移动时将不改变摇杆器坐标,直到下次按下鼠标*/ setautoposition( value); /**回调函数指针*/ std::function< (JoystickEnum)>onDirection; /**静态创建函数(需要传入底盘和触点图片路径)*/ static Joystick*create(std::stringchassisPath,std::stringdotPath); /**初始化摇杆器(需要传入底盘和触点图片路径)*/ initWithJoystick(std::stringchassisPath,std::stringdotPath); protected : /**有效区域半径*/ _radius; /**失效区域半径*/ _failradius; /**是否移出有效区域*/ isMoveOut; /**是否存在有效区域半径*/ isDIERadius; /**是否自由变换摇杆器坐标*/ isautoposition; /**方向*/ JoystickEnum_direction; /**底盘*/ Sprite*_chassis; /**触点*/ Sprite*_touchDot; EventListenertouchOneByOne*Listener; ontouchBegan(touch*touch,Event*event); ontouchmoved(touch*touch,Event*event); ontouchended(touch*touch,Event*event); /** 1、设置触点,并判断是否在无效区域内(如果在无效区域内,将重置) 2、发送角度变化(如果不在无效区域内)*/ settouchDotposition(Vec2vec1,Vec2vec2); /** 1、计算摇杆器八方向 2、发送角度变化,回调弧度变化函数*/ changeAngle(Vec2position); /**回调注册的监听函数*/ callDirectionFun(); /**重置(当弧度不是DEFAulT时才重置)*/ resetState(); @H_533_502@ }; #endif |
#include"Joystick.h" Joystick*Joystick::create(std::stringchassisPath,std::stringdotPath) { autojoystick= new Joystick(); joystick->initWithJoystick(chassisPath,dotPath); return joystick; } Joystick::initWithJoystick(std::stringchassisPath,std::stringdotPath) { _chassis=Sprite::create(chassisPath); this ->addChild(_chassis,0); _touchDot=Sprite::create(dotPath); ->addChild(_touchDot,1); isDIERadius= false ; @H_301_240@ isautoposition= ; isMoveOut= ; _direction=DEFAulT; } Joystick::onRun() { Listener=EventListenertouchOneByOne::create(); Listener->setSwallowtouches( ); Listener->ontouchBegan=CC_CALLBACK_2(Joystick::ontouchBegan, ); Listener->ontouchmoved=CC_CALLBACK_2(Joystick::ontouchmoved,monospace!important; Font-size:1em!important; min-height:inherit!important">); Listener->ontouchended=CC_CALLBACK_2(Joystick::ontouchended,monospace!important; Font-size:1em!important; min-height:inherit!important">); ->_eventdispatcher->addEventListenerWithSceneGraPHPriority(Listener,monospace!important; Font-size:1em!important; min-height:inherit!important">); } Joystick::ontouchBegan(touch*touch,Event*event) { Vec2locationInNode= ->convertToNodeSpace(touch->getLocation()); if (isautoposition) { ->setposition(touch->getLocation()); return true ; } (isautoposition== &&isDIERadius) { (locationInNode.getLength()>_radius) { ; } } _touchDot->setposition(locationInNode); (locationInNode.getLength()>_failradius) { changeAngle(locationInNode); } ; } Joystick::ontouchmoved(touch*touch,Event*event) { ->convertToNodeSpace(touch->getLocation()); (isDIERadius) { (locationInNode.getLength()<_radius) { (isMoveOut) { _touchDot->setposition(locationInNode); ; } settouchDotposition(locationInNode,_touchDot->getposition()+touch->getDelta()); ; } } else { ; } @H_533_502@ ; _touchDot->setposition(0,0); resetState(); } Joystick::ontouchended(touch*touch,Event*event) { ; resetState(); } Joystick::settouchDotposition(Vec2vec1,Vec2vec2) { _touchDot->setposition(vec2); (_failradius>0) { (vec1.getLength()<_failradius) { resetState(); ; } } changeAngle(vec1); } Joystick::setDIERadius( radius) { _radius=radius; ; } Joystick::setautoposition( value) { isautoposition=value; } Joystick::setFailRadius( radius) { _failradius=radius; } Joystick::ondisable() { ->_eventdispatcher->removeEventListener(Listener); ; ; ; } Joystick::changeAngle(Vec2position) { autoangle=CC_radians_TO_degrees(position.getAngle()); (angle>-22.5&&angle<22.5) { _direction=D_RIGHT; } else (angle>22.5&&angle<67.5) { _direction=D_RIGHT_UP; } (angle>67.5&&angle<112.5) { _direction=D_UP; } (angle>112.5&&angle<157.5) { _direction=D_left_UP; } ((angle>157.5&&angle<180)||(angle<-157.5&&angle>-180)) { _direction=D_left; } (angle<-112.5&&angle>-157.5) { _direction=D_left_DOWN; } (angle<-67.5&&angle>-112.5) { _direction=D_DOWN; } (angle<-22.5&&angle>-67.5) { _direction=D_RIGHT_DOWN; } callDirectionFun(); } Joystick::callDirectionFun() { (onDirection) { onDirection(_direction); } } Joystick::resetState() { (_direction!=DEFAulT) { _direction=DEFAulT; callDirectionFun(); } } @H_301_1463@ Joystick::setVisibleJoystick( visible) { _chassis->setVisible(visible); _touchDot->setVisible(visible); } |
当然,如果有用到的朋友可以自己修改。这只是最简单的实现。
下面有效果图,不过加载比较慢
普通模式:
autojoystick=Joystick::create( "rocker.png" , "rocker_joy.png" ); //通过两张图片初始化控件 ->addChild(joystick); joystick->setposition(VisibleRect::leftBottom()+Vec2(200,200)); //設置初始位置 joystick->onDirection=CC_CALLBACK_1(SceneMain::onDirection,0)!important">//角度变化更新(onDirection(JoystickEnumenums)) joystick->onRun(); //启动 |
存在死亡半径模式:(超出死亡半径将触点重置初始位置,移动失效)
//设置初始位置 joystick->setDIERadius(60); //设置死亡半径(外圈) //角度变化更新(onDirection(JoystickEnumenums)) |
评论列表(0条)