cocos-lua学习笔记(十一)事件分发机制
一、Quick框架的事件按照功能和用途分为:
- 节点事件
- 桢事件
- 键盘事件
- 加速计事件
- 触摸时间
节点事件
Node进入和退出场景时触发,加入一个层或者其他的Node,添加清楚数据,也会触发。
function MainScene:ctor()
--事件分发机制-节点事件
local function createTestScene(name)
local scene = display.newScene(name)
scene:addNodeEventListener(cc.NODE_EVENT, function(event) printf("node in scene [%s] NODE_EVENT:%s",name,event.name)end)
return scene
end
self:performWithDelay(function ()
local scene1 = createTestScene("scene1")
display.replaceScene(scene1)
scene1:performWithDelay(function ()
print("-----------")
local scene2 = createTestScene("scene2")
display.replaceScene(scene2)
end, 1.0)
end, 1.0)
end
帧事件
每一帧会触发
--事件分发机制-节点事件
local function createTestScene(name)
local scene = display.newScene(name)
scene:addNodeEventListener(cc.NODE_EVENT, function(event) printf("node in scene [%s] NODE_EVENT:%s",name,event.name)end)
return scene
end
self:performWithDelay(function ()
local scene1 = createTestScene("scene1")
display.replaceScene(scene1)
scene1:performWithDelay(function ()
print("-----------")
local scene2 = createTestScene("scene2")
display.replaceScene(scene2)
end, 1.0)
end, 1.0)
键盘事件
监听代码如下:
function MainScene:ctor()
self:setKeypadEnabled(true)
self:addNodeEventListener(cc.KEYPAD_EVENT, function(event)
print("test"..event.key)
end
)
end
加速计事件
手机上接收 x,y,z三个方向重力感应
cc.Device:setAccelerometerEnabled(true)
local function accelerometerListener(event,x,y,z,timestamp)
print("TestAccelerateEvent"..x..y..z..timestamp)
end
local listener = cc.EventListenerAcceleration:create(accelerometerListener)
self:getEventDispatcher():addEventListenerWithSceneGraphPriority(listener, self)
触摸事件
--单点触摸
local MainScene = class("MainScene", function()
return display.newScene("MainScene")
end)
function MainScene:ctor()
--触摸事件:单点触摸
local node = display.newSprite("dog.png")
node:addNodeEventListener(cc.NODE_TOUCH_EVENT,function ( event )
printf("Sprite:%s | x = %0.2f | y = %0.2f",event.name,event.x,event.y)
if event.name == "began" then
return true
end
end)
self:addChild(node)
node:setPosition(display.cx+100,display.cy+100)
node:setTouchEnabled(true)
node:setTouchMode(cc.TOUCH_MODE_ONE_BY_ONE)
end
function MainScene:onEnter()
end
function MainScene:onExit()
end
return MainScene
--多点触摸
--触摸事件:多点触摸
local node = display.newSprite("dog.png")
node:addNodeEventListener(cc.NODE_TOUCH_EVENT,function (event)
for id,point in pairs(event.points) do
printf("event [%s] | id = %s | x = %0.2f | y = %0.2f",event.name,id,point.x,point.y)
end
if event.name == "began" then
return true
end
end)
self:addChild(node)
node:setPosition(display.cx+100,display.cy+100)
node:setTouchEnabled(true)
node:setTouchMode(cc.TOUCH_MODE_ALL_AT_ONCE)
二、事件的过程
触摸事件吞噬
Node响应触摸后(在began状态返回true,表示要响应触摸),就会阻止事件继续传递给Node的父对象(更下层的Node),成为事件吞噬
setTouchSwallowEnabled()可以改变这个行为,默认为true。如果为false,则事件还会继续传递
isTouchSwallowEnabled()检查Node的吞噬状态
禁用触摸
setTouchEnabled()是否允许Node响应触摸,默认为false。尽管该节点被禁止,不会影响Node的子节点响应
isTouchEnabled()判断是否允许触摸
setTouchCaptureEnabled()检查是否允许Node捕获触摸,默认为true,当设置为false时,该Node及所有的子Node都无法触摸事件
isTouchCaptureEnabled()检查是否允许捕获触摸
setTouchEnabled只影响当前节点
setTouchCaptureEnabled会影响当前及所有子节点
触摸事件的三个阶段
(1)捕获
(2)触发
(3)冒泡
用一个手指触碰屏幕
1.遍历所有响应的触摸Node,找出显示层级最高,并且触摸区域包含触摸的位置 的那个Node。该Node称为TargetNode(目标Node)
2.检查targetnode 的isTouchCaptureEnabled结果,返回false则重复(1) 这个阶段叫capturing
3.在targetnode触发事件,这个阶段叫targeting
4.返回false,表示targetnode不响应事件,重复步骤(1)开始查找符合条件的Node
5.targetnode触发事件完毕,检查isTouchSwallowEnabled。如果为true取消bubbling阶段
6.从targetnode开始往其父node触发事件,直到某个Node返回false或者事件吞噬,这个阶段叫bubbling。
事件冒泡补充:
当事件发生后,这个事件就要开始传播(从里到外或者从外向里)。为什么要传播呢?因为事件源本身(可能)并没有处理事件的能力,即处理事件的函数(方法)并未绑定在该事件源上。例如我们点击一个按钮时,就会产生一个click事件,但这个按钮本身可能不能处理这个事件,事件必须从这个按钮传播出去,从而到达能够处理这个事件的代码中(例如我们给按钮的onclick属性赋一个函数的名字,就是让这个函数去处理该按钮的click事件),或者按钮的父级绑定有事件函数,当该点击事件发生在按钮上,按钮本身并无处理事件函数,则传播到父级去处理。