枫叶天空Cocos2d-x3.0系列教程四 事件机制

有关事件机制,官方的文档写的非常完整详实,所以本篇并不打算过多的赘述,这里给出官方文档的地址:http://www.cocos2d-x.org/docs/manual/framework/native/input/event-dispatcher/zh。

下面的内容主要是作为我的学习笔记来发表的,各位可以做一个参考,主要内容如下:

  1. 触摸事件
  2. 键盘事件
  3. 鼠标事件
  4. 自定义事件
  5. 加速事件(缺乏真机环境,未测试)

首先,我还是创建一个EventManager来管理事件测试,头文件如下:

#include "cocos2d.h"

USING_NS_CC;

class EventManager :public cocos2d::Sprite{
public:
	//调用宏CREATE_FUNC,使系统自动的为SimpleGUIManager类创建一个create方法
	CREATE_FUNC(EventManager);
	//测试事件
	void testEvent();

private:
	//测试触摸事件
	void testEventListenerTouch();
	//测试键盘事件
	void testEventListenerKeyboard();
	//测试鼠标事件
	void testEventListenerMouse();
	//测试自定义事件
	void testEventListenerCustom();
	//测试加速事件,需真机
	void testEventListenerAcceleration();

	//触摸开始的回调函数
	bool onTouchBegan(Touch* touch, Event* event);
	//触摸移动的回调函数
	void onTouchMoved(Touch* touch, Event* event);
	//触摸结束的回调函数
	void onTouchEnded(Touch* touch, Event* event);
	//键盘按下
	void onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event);
	//键盘释放回调函数
	void onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event);
	//初始化测试精灵图片
	void initSprite();
	//鼠标按下回调函数
	void onMouseDown(Event *event);
	//鼠标抬起回调函数
	void onMouseUp(Event *event);
	//鼠标移动回调函数
	void onMouseMove(Event *event);
	//鼠标滚动回调函数
	void onMouseScroll(Event *event);
	//自定义事件的回调
	void onCustomEvent(EventCustom* event);
	//分发自定义事件
	void dispatchCustomEvent();

private:
	Sprite *sprite1;
	Sprite *sprite2;
	Sprite *sprite3;
};


触摸事件

EventManager.cpp示例代码如下:


//测试触摸事件
void EventManager::testEventListenerTouch(){
	// 创建一个事件监听器 OneByOne 为单点触摸
	auto listener1 = EventListenerTouchOneByOne::create();
	//设置是否吞没事件,在 onTouchBegan 方法返回 true 时吞没
	//当设置为true时,在 onTouchBegan 中会执行相应的判断,以决定其返回值是 false 还是 true,
	//用来处理触摸事件是否依据显示的顺序关系向后传递。
	listener1->setSwallowTouches(true);

	//官方在此处使用了一个lambda函数,但是我却没有这样做
	//多年的面向对象编程经历,使我养成了一种凡事必须强对象的观念,包括函数的定义也从未使用过匿名函数
	//因此,我在这里明确的定义出了开始触摸的函数
	listener1->onTouchBegan = CC_CALLBACK_2(EventManager::onTouchBegan, this);
	listener1->onTouchEnded = CC_CALLBACK_2(EventManager::onTouchEnded, this);
	listener1->onTouchMoved = CC_CALLBACK_2(EventManager::onTouchMoved, this);

	//CC_CALLBACK说明
	//CC_CALLBACK_0  0个参数
	//CC_CALLBACK_1  1个参数
	//CC_CALLBACK_2  2个参数
	//.................
	//对于这个我有点无力吐槽了,系统默认最多是支持3个,那我如果想传递四个及四个以上的参数怎么办呢?


	// 添加监听器
	//估计此处官方会在后面进行修改吧,这个clone的用法可是有点令人不爽
	//有一点非常重要,FixedPriority listener添加完之后需要手动remove,
	//而SceneGraphPriority listener是跟node绑定的,在node的析构函数中会被移除
	_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3);

}

//开始触摸事件
bool EventManager::onTouchBegan(Touch* touch, Event* event){
    // 获取事件所绑定的 target 
    auto target = static_cast<Sprite*>(event->getCurrentTarget());

    // 获取当前点击点所在相对按钮的位置坐标
    Point locationInNode = target->convertToNodeSpace(touch->getLocation());
    Size s = target->getContentSize();
    Rect rect = Rect(0, 0, s.width, s.height);

    // 点击范围判断检测
    if (rect.containsPoint(locationInNode)){
        log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
        target->setOpacity(180);
        return true;
    }
    return false;
}

//触摸事件终止
void EventManager::onTouchEnded(Touch* touch, Event* event){
    auto target = static_cast<Sprite*>(event->getCurrentTarget());
    log("sprite onTouchesEnded.. ");
    target->setOpacity(255);
    if (target == sprite2){
        sprite1->setLocalZOrder(100);
    }
    else if (target == sprite1){
        sprite1->setLocalZOrder(0);
    }
}

//触摸事件移动
void EventManager::onTouchMoved(Touch* touch, Event* event){
    auto target = static_cast<Sprite*>(event->getCurrentTarget());
    target->setPosition(target->getPosition() + touch->getDelta());
}


//初始化测试Sprite
void EventManager::initSprite(){
    Point origin = Director::getInstance()->getVisibleOrigin();
    Size size = Director::getInstance()->getVisibleSize();

    sprite1 = Sprite::create("Images/CyanSquare.png");
    sprite1->setPosition(origin + Point(size.width / 2, size.height / 2) + Point(-80, 80));
    addChild(sprite1, 10);

    sprite2 = Sprite::create("Images/MagentaSquare.png");
    sprite2->setPosition(origin + Point(size.width / 2, size.height / 2));
    addChild(sprite2, 20);

    sprite3 = Sprite::create("Images/YellowSquare.png");
    sprite3->setPosition(Point(0, 0));
    sprite2->addChild(sprite3, 1);
}

键盘事件

示例代码如下:

//测试键盘事件
void EventManager::testEventListenerKeyboard(){
	// 初始化并绑定
	auto listener = EventListenerKeyboard::create();
	listener->onKeyPressed = CC_CALLBACK_2(EventManager::onKeyPressed, this);
	listener->onKeyReleased = CC_CALLBACK_2(EventManager::onKeyReleased, this);

	_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}

// 键位响应函数原型
void EventManager::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event){
    log("Key with keycode %d pressed", keyCode);
}

void EventManager::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event){
    log("Key with keycode %d released", keyCode);
}


鼠标事件

示例源码如下:

//测试鼠标事件
void EventManager::testEventListenerMouse(){
	auto mouseListener = EventListenerMouse::create();
	mouseListener->onMouseMove = CC_CALLBACK_1(EventManager::onMouseMove, this);
	mouseListener->onMouseUp = CC_CALLBACK_1(EventManager::onMouseUp, this);
	mouseListener->onMouseDown = CC_CALLBACK_1(EventManager::onMouseDown, this);
	mouseListener->onMouseScroll = CC_CALLBACK_1(EventManager::onMouseScroll, this);

	_eventDispatcher->addEventListenerWithSceneGraphPriority(mouseListener, this);
}

void EventManager::onMouseDown(Event *event)
{
    EventMouse* e = (EventMouse*)event;
    //string str = "Mouse Down detected, Key: ";
    //str += tostr(e->getMouseButton());
    log("Mouse Down detected");
    // ...
    //鼠标按下时,分发自定义事件
    dispatchCustomEvent();
}

void EventManager::onMouseUp(Event *event)
{
    EventMouse* e = (EventMouse*)event;
    //string str = "Mouse Up detected, Key: ";
    //str += tostr(e->getMouseButton());
    log("Mouse Up detected");
    // ...
}

void EventManager::onMouseMove(Event *event)
{
    EventMouse* e = (EventMouse*)event;
    //string str = "MousePosition X:";
    //str = str + tostr(e->getCursorX()) + " Y:" + tostr(e->getCursorY());
    //log("MousePosition");
}

void EventManager::onMouseScroll(Event *event)
{
    EventMouse* e = (EventMouse*)event;
    //string str = "Mouse Scroll detected, X: ";
    //str = str + tostr(e->getScrollX()) + " Y: " + tostr(e->getScrollY());
    log("Mouse Scroll detected");
}


自定义事件

示例源码:

void EventManager::testEventListenerCustom(){
	auto listener = EventListenerCustom::create("game_custom_event1", CC_CALLBACK_1(EventManager::onCustomEvent,this));
	_eventDispatcher->addEventListenerWithFixedPriority(listener, 1);
}

void EventManager::dispatchCustomEvent(){
    static int count = 0;
    ++count;
    char* buf = new char[10];
    sprintf(buf, "recept custom event %d", count);
    //自定义事件
    EventCustom event("game_custom_event1");
    //设置事件参数
    event.setUserData(buf);
    //分发事件
    _eventDispatcher->dispatchEvent(&event);
}

void EventManager::onCustomEvent(EventCustom* event){
    log("Custom event 1 received, ");
    char* buf = static_cast<char*>(event->getUserData());
    log(buf);
}

至此,事件机制的内容就介绍完了。事件机制也是游戏中的重要组成部分之一,熟练掌握事件机制,也是前端程序必备的能力之一。下一节,我们将介绍一个非常酷的模块,那就是Cocos的粒子系统,游戏中很多炫酷的效果就是由粒子制作出来的,让我们拭目以待吧。


完整教程索引链接地址

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值