cocos2dx触摸摇杆

最近想做格斗游戏,那么就要有摇杆控件,不想去看别人的代码就自己写了个摇杆控件,实现起来很简单。


话不多说,看代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
};
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();
};
#endif
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#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 ;
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
{
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,_touchDot->getPosition()+touch->getDelta());
;
}
;
_touchDot->setPosition(0,0);
resetState();
}
Joystick::onTouchEnded(Touch*touch,Event*event)
{
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,0);
;
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();
}
}
Joystick::setVisibleJoystick( visible)
{
_chassis->setVisible(visible);
_touchDot->setVisible(visible);
}

当然,如果有用到的朋友可以自己修改。这只是最简单的实现。

下面有效果图,不过加载比较慢

普通模式:

5
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(); //启动

存在死亡半径模式:(超出死亡半径将触点重置初始位置,移动失效)

6
//设置初始位置
joystick->setDieRadius(60); //设置死亡半径(外圈)
//角度变化更新(onDirection(JoystickEnumenums))

设置失效半径:(在失效半径内将不会触发角度改变事件)

7
joystick->setFailRadius(30); //设置失效半径(內圈)
//角度变化更新(onDirection(JoystickEnumenums))
设置自由变换位置:以鼠标按下的坐标为初始位置

joystick->setAutoposition(//是否自由改变坐标
//角度变化更新

设置隐藏摇杆:(不显示摇杆底盘和触点,一般会设置成自由改变位置)

joystick->setVisibleJoystick(//是否显示
//角度变化更新

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...