cocos2d-x触摸机制--用户交互事件

cocos2d-x触摸机制--用户交互事件,第1张

概述1,加入用户触摸时间侦听  auto listener=EventListenerTouchOneByOne::create();  listener->setSwallowTouches(true);  //不向下触摸,简单点来说,比如有两个sprite ,A 和 B,A在上B在下(位置重叠),触摸A的时候,B不会受到影响,反之A,B都会受影响 2,lambda,读音为:腊母达    实现的触摸


1,加入用户触摸时间侦听

auto @R_419_6818@ener=Event@R_419_6818@enertouchOneByOne::create();

@R_419_6818@ener->setSwallowtouches(true); //不向下触摸,简单点来说,比如有两个sprite,A 和 B,A在上B在下(位置重叠),触摸A的时候,B不会受到影响,反之A,B都会受影响

2,lambda,读音为:腊母达 实现的触摸机制方法
@R_419_6818@ener->ontouchBegan=[&](touch * t,Event * e){

cclog("no can no bb!!!");
return true;

};

3,注册这个侦听到消息分发器中
_eventdispatcher->addEvent@R_419_6818@enerWithSceneGraPHPriority(@R_419_6818@ener,this);


//单点触摸 virtualboolontouchBegan(touch*touch,Event*unused_event); virtualvoIDontouchmoved(touch*touch,Event*unused_event); voIDontouchended(touch*touch,153); Font-weight:bold; background-color:inherit">voIDontouchCancelled(touch*touch,108); @R_419_6818@-style:decimal-leading-zero outsIDe; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> //多点触摸 voIDontouchesBegan(conststd::vector<touch*>&touches,153); Font-weight:bold; background-color:inherit">voIDontouchesMoved(voIDontouchesEnded(voIDontouchesCancelled( 单点触摸:(即只有注册的Layer才能接收触摸事件)

ontouchBegan: 如果返回true:本层的后续touch事件可以被触发,并阻挡向后层传递

如果返回false,本层的后续touch事件不能被触发,并向后传递,也就是不会调用ontouchmoved


另一种实现方法

//初始化触摸事件监听器
auto @R_419_6818@ener = Event@R_419_6818@enertouchOneByOne::create();
//设置触摸事件是否向下传递
@R_419_6818@ener->setSwallowtouches(true);
//添加触摸监听器的回调函数
@R_419_6818@ener->ontouchBegan = CC_CALLBACK_2(Hao::ontouchBegan,this);
@R_419_6818@ener->ontouchmoved = CC_CALLBACK_2(Hao::ontouchmoved,this);
@R_419_6818@ener->ontouchended = CC_CALLBACK_2(Hao::ontouchended,this);
//将触摸监听添加到eventdispacher中去
_eventdispatcher->addEvent@R_419_6818@enerWithSceneGraPHPriority(@R_419_6818@ener,this);


重写触摸时间方法

bool Hao::ontouchBegan(cocos2d::CCtouch *touch,cocos2d::CCEvent *event){

cclog("you can you bb!!");
return true;
}


--------------------------------------------------------------------------------下面为官方说明文档---------------------------------------------------------------------------



新事件分发机制:在2.x 版本事件处理时,将要触发的事件交给代理(delegate)处理,再通过实现代理里面的ontouchBegan等方法接收事件,最后完成事件的响应。而在新的事件分发机制中,只需通过创建一个事件监听器-用来实现各种触发后的逻辑,然后添加到事件分发器_eventdispatcher,所有事件监听器有这个分发器统一管理,即可完成事件响应。

事件监听器有以下几种:

触摸事件 (Event@R_419_6818@enertouch) 键盘响应事件 (Event@R_419_6818@enerKeyboard) 鼠标响应事件 (Event@R_419_6818@enerMouse) 自定义事件 (Event@R_419_6818@enerCustom) 加速记录事件 (Event@R_419_6818@eneracceleration)

_eventdispatcher的工作由三部分组成:

事件分发器 Eventdispatcher 事件类型 Eventtouch,EventKeyboard 等 事件监听器 Event@R_419_6818@enertouch,Event@R_419_6818@enerKeyboard 等

监听器实现了各种触发后的逻辑,在适当时候由事件分发器分发事件类型,然后调用相应类型的监听器。

用户输入事件 触摸事件

在处理触摸事件时,既可以重写三个方法ontouchBegan,ontouchmovedontouchended,也可以直接通过Lambda表达式完成响应逻辑。

在2.x版本中,开启多点触摸需要在AppController.mm中的application dIDFinishLaunchingWithOptions:launchOptions中添加[__glVIEw setMultipletouchEnabled: YES],另外还需重载5个相应函数:

virtual voID registerWithtouchdispatcher(voID); virtual voID cctouchesBegan(cocos2d::CCSet *ptouches,cocos2d::CCEvent *pEvent); virtual voID cctouchesMoved(cocos2d::CCSet *ptouches,cocos2d::CCEvent *pEvent); virtual voID cctouchesEnded(cocos2d::CCSet *ptouches,cocos2d::CCEvent *pEvent); virtual voID cctouchesCancelled(cocos2d::CCSet *ptouches,cocos2d::CCEvent *pEvent);

而在3.0中,只需创建多点触摸事件监听器,并将其添加到事件分发器中即可。

以下代码在一个界面中添加三个按钮,三个按钮相互遮挡,并且都能触发触摸事件:

// 创建按钮精灵    auto sprite1 = Sprite::create("Images/CyanSquare.png");    sprite1->setposition(origin+Point(size.wIDth/2,size.height/2) + Point(-80,80));    addChild(sprite1,10);    // sprite2    ...    // sprite3    ...

创建好按钮精灵后,创建单点触摸事件监听器,并完成相应逻辑处理

// 创建一个事件监听器类型为 OneByOne 的单点触摸    auto listener1 = EventListenerTouchOneByOne::create();    // 设置是否吞没事件,在 onTouchBegan 方法返回 true 时吞没    listener1->setSwallowTouches(true);    // 使用 lambda 实现 onTouchBegan 事件回调函数    listener1->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,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;        };    // 触摸移动时触发    listener1->onTouchMoved = [](Touch* touch,Event* event){...};    // 点击事件结束处理    listener1->onTouchEnded = [=](Touch* touch,Event* event){...};

最后需要将事件监听器添加到事件分发器

// 添加监听器    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1,sprite1);    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(),sprite2);    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(),sprite3);

以上代码中_eventDispatcher是Node的属性,通过它管理当前节点(场景、层、精灵等)的所有事件的分发。但它本身是一个单例模式值的引用,在Node的构造函数中,通过Director::getInstance()->getEventDispatcher();获取,有了这个属性,就能方便的处理事件。

注意:当再次使用 listener1 的时候,需要使用clone()方法创建一个新的克隆,因为在使用addEventListenerWithSceneGraphPriority或者addEventListenerWithFixedPriority方法时,会对当前使用的事件监听器添加一个已注册的标记,这使得它不能够被添加多次。另外,有一点非常重要,FixedPriority listener添加完之后需要手动remove,而SceneGraphPriority listener是跟Node绑定的,在Node的析构函数中会被移除。具体的示例用法可以参考引擎自带的tests。

我们可以通过以下方法移除一个已经被添加了的监听器。

_eventDispatcher->removeEventListener(listener);

也可以使用如下方法,移除当前事件分发器中所有监听器。

_eventDispatcher->removeAllEventListeners();

当使用removeAll的时候,此节点的所有的监听将被移除,推荐使用 指定删除的方式。removeAll之后菜单也不能响应。因为它也需要接受触摸事件。

键盘响应事件

键盘响应事件和处理触摸事件使用了相同的处理方式,一下代码演示如何处理键盘响应事件:

// 初始化并绑定    auto @R_419_6818@ener = Event@R_419_6818@enerKeyboard::create();    @R_419_6818@ener->onKeypressed = CC_CALLBACK_2(KeyboardTest::onKeypressed,this);    @R_419_6818@ener->onkeyreleased = CC_CALLBACK_2(KeyboardTest::onkeyreleased,this);    _eventdispatcher->addEvent@R_419_6818@enerWithSceneGraPHPriority(@R_419_6818@ener,this);    // 键位响应函数原型    voID KeyboardTest::onKeypressed(EventKeyboard::KeyCode keyCode,Event* event)    {        log("Key with keycode %d pressed",keyCode);    }    voID KeyboardTest::onkeyreleased(EventKeyboard::KeyCode keyCode,Event* event)    {        log("Key with keycode %d released",keyCode);    }
鼠标响应事件

在 3.0 中多了鼠标捕获事件派发,这可以在不同的平台上,丰富我们游戏的用户体验。

下面代码实现鼠标响应事件的实现步骤:

// 创建监听器    _mouse@R_419_6818@ener = Event@R_419_6818@enerMouse::create();    // 时间响应逻辑    _mouse@R_419_6818@ener->onMouseMove = [=](Event *event){    EventMouse* e = (EventMouse*)event;    string str = "Mouse Down detected,Key: ";    str += tostr(e->getMousebutton());    // ...};    _mouse@R_419_6818@ener->onmouseup = [=](Event *event){...};    _mouse@R_419_6818@ener->onMouseDown = [=](Event *event){...};    _mouse@R_419_6818@ener->onMouseScroll = [=](Event *event){...};    // 添加到事件分发器    _eventdispatcher->addEvent@R_419_6818@enerWithSceneGraPHPriority(_mouse@R_419_6818@ener,this);
自定义事件

以上是系统自带的事件类型,事件由系统内部自动触发,如 触摸屏幕,键盘响应等,除此之外,还提供了一种 自定义事件,简而言之,它不是由系统自动触发,而是人为的干涉,如下:

_@R_419_6818@ener = Event@R_419_6818@enerCustom::create("game_custom_event1",[=](EventCustom* event){        std::string str("Custom event 1 received,");        char* buf = static_cast<char*>(event->getUserData());        str += buf;        str += " times";        statusLabel->setString(str.c_str());    });    _eventdispatcher->addEvent@R_419_6818@enerWithFixedPriority(_@R_419_6818@ener,1);

以上定义了一个 “自定义事件监听器”,实现了相关逻辑,并且添加到事件分发器。上面的自定义事件将由以下代码触发:

static int count = 0;    ++count;    char* buf = new char[10];    sprintf(buf,"%d",count);    EventCustom event("game_custom_event1");    event.setUserData(buf);    if(...)    {        _eventdispatcher->dispatchEvent(&event);    }    CC_SAFE_DELETE_ARRAY(buf);

定义一个 EventCustom,并且设置了其 UserData 数据,手动的通过 _eventdispatcher->dispatchEvent(&event); 将此事件分发出去,从而触发之前所实现的逻辑。

加速计事件

除了触摸,移动设备上一个很重要的输入源是设备的方向,因此大多数设备都配备了加速计,用于测量设备静止或匀速运动时所受到的重力方向。

重力感应来自移动设备的加速计,通常支持X,Y和Z三个方向的加速度感应,所以又称为三向加速计。在实际应用中,可以根据3个方向的力度大小来计算手机倾斜的角度或方向。

3.0中,新的事件机制下,我们需要通过创建一个加速计监听器Event@R_419_6818@eneracceleration,其静态create方法中有个acceleration的参数需要注意。acceleration是一个类,包含了加速计获得的3个方向的加速度,相关代码如下:

class acceleration{public:    double x;    double y;    double z;    double timestamp;    acceleration(): x(0),y(0),z(0),timestamp(0) {}};

该类中每个方向的加速度大小都为一个重力加速度大小。

在使用加速计事件监听器之前,需要先启用此硬件设备:

Device::setAccelerometerEnabled(true);

然后创建对应的监听器,在创建回调函数时,可以使用 lambda 表达式创建匿名函数,也可以绑定已有的函数逻辑实现,如下:

auto @R_419_6818@ener = Event@R_419_6818@eneracceleration::create([=](acceleration* acc,Event* event){        //逻辑代码段    });    _eventdispatcher->addEvent@R_419_6818@enerWithSceneGraPHPriority(@R_419_6818@ener,this);
总结

以上是内存溢出为你收集整理的cocos2d-x触摸机制--用户交互事件全部内容,希望文章能够帮你解决cocos2d-x触摸机制--用户交互事件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1001697.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存