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 ...
随机推荐
- WCF学习心得------(七)消息协定
第七章 消息协定 7.1 消息协定概述 通常情况下,在定义消息的架构时只使用数据协定就足够,但是有时需要精确控制如何将类型映射到通过网络传输的SOAP消息.对于这种情况,通常解决方案是插入自定义的SO ...
- php自动转换pfx到pem和cer(dem格式)到pem
经常做银行的支付接口,私钥一般都是pfx格式(私钥用来加密生成签名发送报文),公钥是cer格式(公钥用来验证返回报文里的签名).但是php里openssl只能用pem格式,每次转换都要用openssl ...
- [转] Neutron FWaaS
OpenStack Neutron FWaaS 学习 ( by quqi99 ) 作者:张华 发表于:2013-06-24 版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息 ...
- LintCode "Longest Increasing Continuous subsequence II" !!
DFS + Memorized Search (DP) class Solution { int dfs(int i, int j, int row, int col, vector<vecto ...
- laravel5-目录结构分析
laravel5-目录结构分析 (2016-01-21 11:24:03) 转载▼ 一.环境配置: $ lsb_release -a No LSB modules are available. ...
- 战胜忧虑<2>——忙碌可以消除忧虑
忙碌可以消除忧虑 当你的脑筋空出来时,也会有东西进去补充,是什么呢?通常都是你的感觉.为什么?因为忧虑.恐惧.憎恨.嫉妒.和羡慕等等情绪,都是由我们的思想所控制的,这种情绪都非常猛烈.会把我们思想中所 ...
- C# 用正则表达式替换字符串中所有特殊字符
descriptionXML = Regex.Replace(ToDBC(descriptionXML.ToUpper().Replace((char)32, ' ').Replace((char)1 ...
- ExtJs4 SpringMvc3 实现Grid 分页
新建一个Maven webapp项目,webxml以及spring配置没什么需要注意的,不再赘述. Maven依赖:(个人习惯,有用没用的都加上...) <project xmlns=" ...
- spark单机模式简单搭建
待安装列表hadoophivescalaspark一.环境变量配置:~/.bash_profilePATH=$PATH:$HOME/bin export PATH JAVA_HOME=/usr/loc ...
- bug_ _ android.view.WindowManager$BadTokenException: Unable to add window -- token
========4 关于android的一个常见错误:Unable to add window --token is not valid android.view.WindowManage ...