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 ...
随机推荐
- OC—设计模式-通知的使用
通知 通知(广播) 可以一对多的发送通知(一个发送者 多个观察者) 特别注意:在发送者 发送通知的时候,必须有观察者 发送者,就是注册一个通知中心,以他为中心,发送消息 通过通知的名字,来判断是哪个通 ...
- Nexus手动更新索引
如果有耐心的话,完全可以通过在线更新索引的方式来做,但所消耗的时间较长,下面介绍一种简单.可行的方式来手动更新索引文件. 访问http://repo.maven.apache.org/maven2/. ...
- 25. Reverse Nodes in k-Group
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If ...
- PHPWord生成word实现table合并(colspan和rowspan)
PHPWord(http://phpword.codeplex.com/)是一个很好处理和生成WORD文档的工具,但是生成复杂的word,如colspan和rowspan的实现,还是需要你做些修改. ...
- SQL语句技巧_索引的优化_慢查询日志开启_root密码的破解
1.正则表达式的使用 regexp例:select name,email from t where email regexp '@163[.,]com$'使用like方式查询selct name,em ...
- 限制页面内部链接访问源-HTML注释
不知道大家有没有碰到过这样一个问题:我修改的是别人的网页,他的超连接是指向一个服务器的某个HTML文件,我把超连接地址修改成了我本地机器的跟首页 同一目录下的一个HTML文件,却发现超连接根本 ...
- C#中的 int?是什么意思
http://www.cnblogs.com/firstcsharp/archive/2011/12/11/2283797.html int?:表示可空类型,就是一种特殊的值类型,它的值可以为null ...
- zend studio 9实用快捷键大全 分享ZEND STUDIO 9的常用快捷键,高亮显示相同变量。
=====把鼠标放在调用函数默认是显示函数的参数,而按下ctrl时会显示出函数的原型=====查询调用该函数父函数,这个实在是太有用了:Ctrl+shift+M:模糊搜索方法名 [这块要注意配置,否则 ...
- CXF发布restful WebService的入门例子(服务器端)
研究了两天CXF对restful的支持. 现在,想实现一个以 http://localhost:9999/roomservice 为入口, http://localhost:9999/roomse ...
- Linux大文件传输(转)
我们经常需要在机器之间传输文件.比如备份,复制数据等等.这个是很常见,也是很简单的.用scp或者rsync就能很好的完成任务.但是如果文件很大,需要占用一些传输时间的时候,怎样又快又好地完成任务就很重 ...