Cocos2d-x 3.0 事件系统【转】
class Event
{
protected:
Event(const std::string& type);
virtual ~Event();
inline const std::string& getType() const { return _type; };
inline void stopPropagation() { _isStopped = true; };
inline bool isStopped() const { return _isStopped; };
inline Node* getCurrentTarget() { return _currentTarget; };
inline void setCurrentTarget(Node* target) { _currentTarget = target; };std::string _type;
bool _isStopped;
Node* _currentTarget;
class EventListener : public Object
{
protected:
EventListener();
bool init(const std::string& t, std::function<void(Event*)>callback);
virtual ~EventListener();
virtual bool checkAvaiable() = 0;
virtual EventListener* clone() = 0;
std::function<void(Event*)> _onEvent;
bool _isRegistered;friend class EventDispatcher;
friend class Node;
class CollisionEvent:public Event
{
public:
static const char* COLLISION_EVENT_TYPE;
CollisionEvent(Entity* l,Entity* r);
Entity* getLeft(){return _left;}
Entity* getRight(){return _right;}
private:
Entity* _left;
Entity* _right;
class CollisionListener : public EventListener
{
public:
static CollisionListener* create(std::function<void(CollisionEvent*)> callback);
virtual bool checkAvaiable() override;
virtual CollisionListener* clone() override;
protected:
CollisionListener();
bool init(std::function<void(CollisionEvent*)> callback);
std::function<void(CollisionEvent*)> _onCollisionEvent;
void HitSystem::configure()
{
auto listener=CollisionListener::create(
[this](CollisionEvent* event){
this->hit(event);
});
EventDispatcher::getInstance()->addEventListenerWithFixedPriority(listener, 1);
}
void CollisionSystem::update(float dt)
{
CollisionEvent* event=new CollisionEvent(entity,collisionEntity);
EventDispatcher::getInstance()->dispatchEvent(event);
}
- 设置订阅者的优先级,一个类型的事件可能拥有多个订阅者,因此有必要设置处理顺序,例如当碰撞事件完成之后,其中一个订阅者负责处理伤害计算,而另一个订阅者可能做一些UI的操作,例如播放声音或者粒子效果。前者的优先级肯定需要更高,因为后者的处理可能需要依赖于生命值的计算。
- 修改订阅者的优先级。
- 停止事件的继续分发,使后续的订阅者不用再处理该事件。
- 根据屏幕上元素的层级,而不是手动设定的优先级来处理事件分发,这在触摸事件的分发中尤其重要。
void addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node);
struct EventListenerItem
{
int fixedPriority;
Node* node;
EventListener* listener;
~EventListenerItem();
- 分发fixedPriority小于0的订阅者,fixedPriority越小则优先分发。
- 分发所有fixedPriority值为0的订阅者,并且没有与Node相关联的。
- 分发所有与Node相关联的订阅者,其关联Node的eventPriority越高(越处于屏幕最上层)则优先级越高。
- 分发所有fixedPriority大于0的订阅者,同样fixedPriority越小则优先分发。
inline void updateEventPriorityIndex() {
_oldEventPriority = _eventPriority;
_eventPriority = ++_globalEventPriorityIndex;
if (_oldEventPriority != _eventPriority)
{
setDirtyForAllEventListeners();
}
class EventTouch : public Event
{
public:
enum class EventCode{
BEGAN,
MOVED,
ENDED,
CANCELLED
};
EventCode getEventCode() { return _eventCode; };
std::vector<Touch*> getTouches() { return _touches; };
#if TOUCH_PERF_DEBUG
void setEventCode(EventCode eventCode) { _eventCode = eventCode; };
void setTouches(const std::vector<Touch*>& touches) { _touches = touches; };
#endif
};
class CC_DLL Touch : public Object
{
public:
/** 触摸点在OpenGL坐标系中的位置 */
Point getLocation() const;
/** 触摸点在OpenGL坐标系中的上一个位置 */
Point getPreviousLocation() const;
/** 触摸点在OpenGL坐标系的起点位置 */
Point getStartLocation() const;
/** 在OpenGL坐标系中当前位置与上一个位置的差 */
Point getDelta() const;
/** 触摸点在屏幕坐标系中的位置 */
Point getLocationInView() const;
/** 触摸点在屏幕坐标系中的上一个位置 */
Point getPreviousLocationInView() const;
/** 触摸点在屏幕坐标系的起点位置 */
Point getStartLocationInView() const;
int getID() const{ return _id; }
class EventListenerTouch : public EventListener
{
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;
std::function<void(const std::vector<Touch*>&, Event*)> onTouchesBegan;
std::function<void(const std::vector<Touch*>&, Event*)> onTouchesMoved;
std::function<void(const std::vector<Touch*>&, Event*)> onTouchesEnded;
std::function<void(const std::vector<Touch*>&, Event*)> onTouchesCancelled;
void setSwallowTouches(bool needSwallow);
private:
bool _needSwallow;
Touch::DispatchMode _dispatchMode;
bool HelloWorld::init()
{
if ( !CCLayer::init()){
return false;
}
setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
setTouchEnabled(true);
return true;
class HelloWorld : public cocos2d::Layer
{
public:
virtual bool onTouchBegan(Touch *touch, Event *event);
virtual void onTouchMoved(Touch *touch, Event *event);
virtual void onTouchEnded(Touch *touch, Event *event);
bool Menu::onTouchBegan(Touch* touch, Event* event)
{
if (_state != Menu::State::WAITING || ! _visible || !_enabled){
return false;
}
for (Node *c = this->_parent; c != NULL; c = c->getParent()){
if (c->isVisible() == false){
return false;
}
}
_selectedItem = this->itemForTouch(touch);
if (_selectedItem){
_state = Menu::State::TRACKING_TOUCH;
_selectedItem->selected();
return true;
}
return false;
MenuItem* Menu::itemForTouch(Touch *touch)
{
Point touchLocation = touch->getLocation();
if (_children && _children->count() > 0)
{
Object* pObject = NULL;
CCARRAY_FOREACH_REVERSE(_children, pObject)
{
MenuItem* child = dynamic_cast<MenuItem*>(pObject);
if (child && child->isVisible() && child->isEnabled())
{
Point local = child->convertToNodeSpace(touchLocation);
Rect r = child->rect();
r.origin = Point::ZERO;
if (r.containsPoint(local)){
return child;
}
}
}
}
return NULL;
class EventKeyboard : public Event
{
EventKeyboard(KeyCode keyCode, bool isPressed)
: Event(EVENT_TYPE)
, _keyCode(keyCode)
, _isPressed(isPressed)
{};
private:
KeyCode _keyCode;
bool _isPressed;
friend class EventListenerKeyboard;
class EventListenerKeyboard : public EventListener
{
public:
std::function<void(EventKeyboard::KeyCode, Event* event)> onKeyPressed;
std::function<void(EventKeyboard::KeyCode, Event* event)> onKeyReleased;
bool EventListenerKeyboard::init()
{
auto listener = [this](Event* event){
auto keyboardEvent = static_cast<EventKeyboard*>(event);
if (keyboardEvent->_isPressed){
if (onKeyPressed != nullptr)
onKeyPressed(keyboardEvent->_keyCode, event);
}
else {
if (onKeyReleased != nullptr)
onKeyReleased(keyboardEvent->_keyCode, event);
}
};
if (EventListener::init(EventKeyboard::EVENT_TYPE, listener)){
return true;
}
return false;
Cocos2d-x 3.0 事件系统【转】的更多相关文章
- 高屋建瓴 cocos2d-x-3.0架构设计 Cocos2d (v.3.0) rendering pipeline roadmap(原文)
Cocos2d (v.3.0) rendering pipeline roadmap Why (the vision) The way currently Cocos2d does rendering ...
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(八)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 回到Xcode中,新建一个EndLayer类,继承于CCNode ...
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(四)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 现在打开MainScene.m文件,首先设置实例变量: @imp ...
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(一)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 首先说一下为什么要转换,这是为了后面的A*寻路算法做准备.由于在 ...
- 最新版本号cocos2d­2.0­x­2.0.2使用新资源载入策略!不再沿用-hd、-
前段时间cocos2dx更新了最新版本号cocos2d2.0x2.0.2.也从这个版本号開始对于资源载入与管理都改变了策略. 在之前的载入方式都是通过沿用与cocos2d-iphone一样 ...
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(六)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在Xcode中打开MainScene.h文件,在接口中添加2个方 ...
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(五)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 为了暂时不影响原来的cat移动方法,我们在CatSprite.m ...
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(三)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 下面看一下CatSprite中最复杂的moveToward方法, ...
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(二)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 首先在CatMazeV3中新建CatSprite类,继承于Spr ...
随机推荐
- 给windows的VM更换网卡到VMNET3从E1000
1. Login to vCenter via vSphere client. go to the vm 2. create a 1G new disk(SCSI 1:2) for the VM te ...
- jQuery-webcam(.NET)实现WEB摄像头监控
jQuery-webcam是一个非常好用的摄像头监控工具,DEMO可官方下载地址http://www.xarg.org/project/jquery-webcam-plugin/ 1.下载解压后,jq ...
- S3C2440之MMU
转自:http://blog.chinaunix.net/uid-23193900-id-3187782.html 1.MMU简介 MMU(Memory Management Unit),内存管 ...
- Linux客户端、服务器、窗口管理器的关系
嵌入式linux中文站发现很多LINUX初学者在学习linux图形方面的知识时会遇到一些概念,如:X.X11.Xfree86.WM.KDE.GNOME.QT.QT/E.Qtopia.DirectFB. ...
- codeforces 336D. Vasily the Bear and Beautiful Strings 组合数学 dp
题意: 给出n,m,g,求好串的个数 0 <= n,m <= 10^5,n + m >= 1,0 <= g <= 1 好串的定义: 1.只由0,1组成,并且恰好有n个0, ...
- USACO CHAPTER 1 1.1 Ride 水题
水题,主要是学习文件输入输出. /* ID: ijustwa1 LANG: C++ TASK: ride */ #include<cstdio> #include<cstring&g ...
- php之form表单
<!DOCTYPE HTML> <html> <head> <title>form</title> <style type=" ...
- js复习(一)
一.常用数据框1.alert(""):警告对话框,作用是弹出一个警告对话框 2.confirm(""):确定对话框,弹出一个带确定和取消按钮的对话框--确定返回 ...
- C#(二维数组/集合)
一.二维数组int [,] array = new int[5,3];//有五个一维数组,每一个一维数组有3个元素 /打印出来一个“王”这个字string[,] wang = new string[, ...
- mysql 正则
mysql 正则学习 基本字符匹配 select desk from dealer_info where desk regexp "82107777"; . 表示匹配任意一个字符 ...