事件处理步骤:

1.创建一个触摸事件监听器(单点触摸或多点触摸)

2.实现触摸事件的响应方法

3.添加事件监听器(场景优先或固定值优先)

4.当用户触摸时,事件分发器就会将事件分发给监听器进行响应

  首先,用户点击屏幕,这时候cocos会把用户点击的信息,包括点击的坐标,优先顺序的值...等等,包含在一个Touch类型的变量中,可以是t。然后把这个信息传递给事件分发器,再由事件分发器分发给相应的事件监听器。事件监听器根据事件的类型,就是一个Event类型的变量,可以是e。决定要响应什么样的动作,这个响应的动作可以用Lambda表达式为架构,里面放上一个回调函数。

  一个事件监听器可以有多个事件处理响应的Lambda表达式,但是只能响应一个实例对象,这个实例对象可以是this(其实是指layer),或者sprite,或者其他的Node类的子类。而且事件分发器只允许注册一次监听器,也就是在事件分发器里面不能有重名的监听器。所以,如果要让多个对象都可以被监听到相同的监听器,可以在注册监听器的时候用listener1->clone(),sprite2。

  listener1->setSwallowTouches(true)是设置是否吞并事件,我们平时点击或者触摸的时候,如果有多个对象重叠的时候,而且每个重叠的对象都有自己的监听器和响应的Lambda。如果我们把它设置为true,吞并触摸,那么事件响应的时候只响应最上层的那个对象,就是只处理最上层对象的事件传递和响应。而如果我们把它设置成false,那么事件响应的时候会按照对象zOrder的大小来依次处理各个对象的事件传递和响应。也就是不吞并触摸,让所有在这一点下的对象都被触摸到,而不是被最上层的对象吞掉。

实例代码:

bool HelloWorld::init()
{
if (!Layer::init())
{
return false;
}
auto visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();

//删除触摸监听器
auto removeAllTouchItem = MenuItemFont::create("shanchu suoyou de chumo jiantingqi", [this](Ref * sender){
  auto senderItem = static_cast<MenuItemFont*>(sender);
  senderItem->setString("chumo jiantingqi shanchu chenggong");
  _eventDispatcher->removeEventListenersForType(EventListener::Type::TOUCH_ONE_BY_ONE);
});
removeAllTouchItem->setPosition(visibleSize.width / 2, visibleSize.height*0.2);

//标题标签
auto title = Label::createWithSystemFont("dan dian chumo ceshi", "", 64);
title->setPosition(visibleSize.width / 2, visibleSize.height*0.9);
this->addChild(title);

//提示标签
auto subtitle = Label::createWithSystemFont("qing dan ji huozhe tuo dong huakuai", "", 32);
subtitle->setPosition(visibleSize.width / 2, visibleSize.height*0.8);
this->addChild(subtitle);

//创建三个精灵对象
auto sprite1 = Sprite::create("CyanSquare.png");
sprite1->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2) + Vec2(-80, 80));
addChild(sprite1, 10);

auto sprite2 = Sprite::create("MagentaSquare.png");
sprite2->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));
addChild(sprite2, 20);

auto sprite3 = Sprite::create("YellowSquare.png");
sprite3->setPosition(Vec2(0, 0));
sprite2->addChild(sprite3, 1);

//创建一个单点触摸事件监听器,处理触摸事件逻辑
auto listener1 = EventListenerTouchOneByOne::create();
//设置是否向下传递触摸
listener1->setSwallowTouches(true);
//通过Lambda表达式直接实现触摸事件的响应方法
listener1->onTouchBegan = [](Touch * touch, Event * event){
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("OnTouchBegan...x=%f,y=%f", locationInNode.x, locationInNode.y);
  target->setOpacity(180);
  return true;
}
return false;
};

listener1->onTouchMoved = [](Touch * touch, Event * event){
  log("OnTouchMoved...");
  auto target = static_cast<Sprite*>(event->getCurrentTarget());
  target->setPosition(target->getPosition() + touch->getDelta());
};

listener1->onTouchEnded = [=](Touch * touch, Event * event){
  auto target = static_cast<Sprite*>(event->getCurrentTarget());
  target->setOpacity(255);
  std::string name;
  if (target == sprite2)
  {
    name = "MagentaSquare.png";
    sprite1->setZOrder(100);
    subtitle->setString("xiang ying shijian de shi jiuhongse,qingse de Zorder zhi bei xiu gai wei100");

  }
  else if (target == sprite1)
  {
    name = "CyanSquare.png";
    sprite1->setZOrder(0);
    subtitle->setString("xiang ying shijian de shi qingse ,qingse de Zorder zhi bei xiu gai wei 0");
  }
  else
  {
    name = "YellowSquare.png";
  }
  log("OnTocuhEnded...your touch is%s", name.c_str());
};

//添加场景优先事件监听器
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3);

return true;
}

7月25日

事件响应是写在HelloWorld类中的.cpp文件里面的init方法里面的

1.首先判断是什么事件类型

EventListenerPhysicsContact  //物理碰撞事件

EventListenerTouchOneByOne  //单点触摸事件

EventListenerTouchAllAtOnce  //多点触摸事件

EventListenerAcceleration  //加速度计事件

EventListenerKeyboard  //按键事件

EventListenerMouse  //鼠标事件

EventListenerCustom  //自定义事件

2.创建出相应的事件监听器

第一种:auto listener = EventListenerTouchOneByOne::create();

第二种:在.h文件的属性定义里面定义EventListenerTouchOneByOne * listener;

在.cpp文件的init方法里面写listener = EventListenerTouchOneByOne::create();

3.设置事件监听器,结构是Lambda表达式,里面有一个回调函数,当被监听的对象满足事件监听器的要求时,执行回调函数里面的内容,this指的是当前层,Touch * t是用户的触摸各种属性, Event * e是事件类型。

listener->onTouchBegan = [this](Touch * t, Event * e){

  for (auto it = this->gcs.begin(); it != this->gcs.end(); it++) {
    auto gc = *it;

    if (gc->getEdge()->getBoundingBox().containsPoint(t->getLocation())) {
    gc->onTouch();
    break;
    }
  }

  return false;

};

4.把事件监听器添加到事件分发器中,当用户触摸时,事件分发器就会将相应事件分发给相应的监听器进行响应,listener就是要添加的监听器,this指的是监听对象,就是当前层。

Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

注意:

MOVED类型的鼠标点击事件,是把MOVED所对应的事件函数执行一遍,然后停留在执行完后的状态,直到ENDED类型的鼠标点击事件的函数被调用。

case Widget::TouchEventType::MOVED:
gamecontroller->onCreep();
break;

case Widget::TouchEventType::ENDED:
gamecontroller->onNormal();
break;

关于Cocos2d-x事件处理机制的更多相关文章

  1. cocos2d触摸事件处理机制(2.x和3.x变化)

    2.x的触摸事件的版本号 触摸事件处理有2种子.以下单点触摸的样本.(另一种多点触摸屏). 创建cocos2d 该项目. 1. 重写下面虚函数. bool ccTouchBegan(cocos2d:: ...

  2. Cocos2d-x之事件处理机制

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. 事件处理机制分为单点触屏,多点触屏,加速度事件,键盘事件和鼠标事件.在现在的智能手机中,触屏的应用比较的广泛,尤其是多点触屏事件的技术,使 ...

  3. java 事件处理机制:按下上下左右键控制小球的运动

    /** * 加深对事件处理机制的理解 * 通过上下左右键来控制一个小球的位置 */package com.test3;import java.awt.*;import javax.swing.*;im ...

  4. Android事件处理机制

    包括监听和回调两种机制. 1. 基于监听的事件处理: 事件监听包含三类对象,事件源,事件,事件监听器.Android的事件处理机制是一种委派式(Delegation)事件处理方式:普通组件(事件源)将 ...

  5. Android的两种事件处理机制

    UI编程通常都会伴随事件处理,Android也不例外,它提供了两种方式的事件处理:基于回调的事件处理和基于监听器的事件处理. 对于基于监听器的事件处理而言,主要就是为Android界面组件绑定特定的事 ...

  6. Android的Touch事件处理机制

    Android的Touch事件处理机制比较复杂,特别是在考虑了多点触摸以及事件拦截之后. Android的Touch事件处理分3个层面:Activity层,ViewGroup层,View层. 首先说一 ...

  7. IOS事件处理机制(关于触发者和响应者的确认)

    事件处理机制 在iOS中发生触摸后,事件会加入到UIApplication事件队列(在这个系列关于iOS开发的第一篇文章中我们分析iOS程序原理的时候就说过程序运行后UIApplication会循环监 ...

  8. Java Swing事件处理机制

    Java Swing的事件处理机制 Swing GUI启动后,Java虚拟机就启动三个线程,分别为主线程,事件派发线程(也是事件处理线程)和系统工具包线程. 主线程 :负责创建并显示该程序的初始界面: ...

  9. Qt事件处理机制

    研一的时候开始使用Qt,感觉用Qt开发图形界面比MFC的一套框架来方便的多.后来由于项目的需要,也没有再接触Qt了.现在要重新拾起来,于是要从基础学起. Now,开始学习Qt事件处理机制. 先给出原文 ...

  10. core java 8~9(GUI & AWT事件处理机制)

    MODULE 8 GUIs--------------------------------GUI中的包: java.awt.*; javax.swing.*; java.awt.event.*; 要求 ...

随机推荐

  1. 套接字I/O超时设置方法和用select实现超时

    注:如无特殊说明,sockfd 原始状态都是阻塞的. 一.使用alarm 函数设置超时  C++ Code  1 2 3 4 5 6 7 8 9 10 11 12 13   void handler( ...

  2. [DLX] hust 1017 Exact cover

    题意: 给你N个包,要拿到M个东西(编号1~M每一个仅仅能有一个) 然后每一个包里有k个东西,每一个东西都有编号. 思路: 舞蹈连模板题 代码: #include"stdio.h" ...

  3. Nginx 的线程池与性能剖析【转载】

    正如我们所知,NGINX采用了异步.事件驱动的方法来处理连接.这种处理方式无需(像使用传统架构的服务器一样)为每个请求创建额外的专用进程或者线程,而是在一个工作进程中处理多个连接和请求.为此,NGIN ...

  4. unity, multi pass shader中的surface pass

    今天尝试写一个multi pass shader,但其中有一个Pass是surface pass,总是莫名奇妙地报错.后来看到下面帖子: http://forum.unity3d.com/thread ...

  5. unity5 where is "Edit->Render Settings"?

    The Render Settings logic has changed a bit. To find the settings you will need to go to "Windo ...

  6. SVN的搭建与使用

    1.什么是SVN? SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很多版本控制服务已从CVS迁移到 ...

  7. 【Linux】VMware中为CentOS设置静态IP(非动态获取IP)

    在VMware上安装好Linux后,默认设置的动态IP,每次启动的IP都不同,远程连接挺费劲的. 于是,需要设置静态的IP,至少我从远程工具连接上去方便多了.另外,为了安装一些软件,也需要访问互联网. ...

  8. 随记MySQL的时间差函数(TIMESTAMPDIFF、DATEDIFF)、日期转换计算函数(date_add、day、date_format、str_to_date)

    时间差函数(TIMESTAMPDIFF.DATEDIFF) 需要用MySQL计算时间差,使用TIMESTAMPDIFF.DATEDIFF,记录一下实验结果 select datediff(now(), ...

  9. 让input变成不可编辑状态的方法

    有时候,我们希望表单中的文本框是只读的,让用户不能修改其中的信息,如使<input type="text" name="input1" value=&qu ...

  10. pssh安装和使用

    前提,安装了python.pssh安装下载pssh-2.2.2.tar.gztar zxvf pssh-2.2.2.tar.gzcd pssh-2.2.2python setup.py buildpy ...