在游戏中,触摸是最基本的,必不可少的。Cocos2d-x 3.x中定义了一系列事件,同时也定义了负责监听这些事件的监听器,另外,cocos定义了事件分发类,用来将事件派发出去以便可以实现相应的事件。
触摸事件
Event
Cocos2d-x 3.x定义了事件基类Event,基于Event,引擎派生出几种事件:
enum class Type
{
TOUCH, // 触摸事件
KEYBOARD, // 键盘事件
ACCELERATION, // 加速度事件
MOUSE,// 鼠标事件
FOCUS,// 焦点事件
CUSTOM // 自定义事件
};
EventTouch
EventTouch是触摸事件中非常重要的一类事件,它定义了四种touch操作:
enum class EventCode
{
BEGAN,
MOVED,
ENDED,
CANCELLED
};
它还定义了一个 static int值,表示最大的触摸点数为15点:
static const int MAX_TOUCHES = 15;
事件监听器
EventListener
EventListener是事件监听器的基类,派生出的监听器对应各种触摸事件:
enum class Type
{
UNKNOWN,
TOUCH_ONE_BY_ONE,
TOUCH_ALL_AT_ONCE,
KEYBOARD,
MOUSE,
ACCELERATION,
FOCUS,
CUSTOM
};
重要的成员变量:
1.onEvent,是绑定于该Listener的callback function,该func的声明使用了c++11
2.type与Event类似,增加一个Unknown的属性。
3.isRegistered变量非常重要,如果他没有被注册,则他的事件不会触发。
4.优先级代表了响应一个事件时的顺序,该值越低,越先响应。
5.node 代表了与该listener相关的node,用于 scene graph类的事件响应,具体的在Dispatcher里面有进行介绍。
6.ListenerID,这是该类型事件的标识符。除了EventCustomListener的ListerID是与name相关的,其余的ListenerID都是固定的,用于标识该类EventListener。
另外:
1.一个Listener想接收事件必须是enabled true 并且 paused false。
2.值得注意的是,pause的变量专门是为了scenGraph类的事件存在的(后续有说明),而且一个Node的onEnter和onExit 事件会影响到与Node相关的该类事件的pause状态。
EventListenerTouchOneByOne
单点触摸方式,实现它时需要重写父类的四种触摸方式的函数:
/// Overrides
virtual EventListenerTouchOneByOne* clone() override;
virtual bool checkAvailable() override;
//
public:
std::function<bool(Touch*, Event*)> onTouchBegan;
std::function<void(Touch*, Event*)> onTouchMoved;
std::function<void(Touch*, Event*)> onTouchEnded;
std::function<void(Touch*, Event*)> onTouchCancelled;
另外, 单点触摸当onTouchBegan函数不是nullptr时,它就是可用的:
bool EventListenerTouchOneByOne::checkAvailable()
{
// EventDispatcher will use the return value of 'onTouchBegan' to determine whether to pass following 'move', 'end'
// message to 'EventListenerTouchOneByOne' or not. So 'onTouchBegan' needs to be set.
if (onTouchBegan == nullptr)
{
CCASSERT(false, "Invalid EventListenerTouchOneByOne!");
return false;
}
return true;
}
还有,EventListenerTouchOneByOne可以设置吞噬。
EventListenerAllAtOnce
多点触摸,当四种触摸方式函数都不为nullptr时,EventListenerAllAtOnce时可用的:
bool EventListenerTouchAllAtOnce::checkAvailable()
{
if (onTouchesBe