微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

quick-cocos2d-x 学习系列之十三 触摸

quick-cocos2d-x 学习系列之十三 触摸

现在智能机基本都是触摸屏,除了键盘爱好者们耍键盘。我们要通过这小小的触摸屏上完成整个游戏逻辑的控制,需要对这巴掌大地方进行详细控制了。

1.单点触摸测试

创建精灵函数

function createtouchableSprite(p)

local sprite = display.newScale9Sprite(p.image)

sprite:setContentSize(p.size)

local cs = sprite:getContentSize()

local label = cc.ui.UILabel.new({

UILabelType = 2,

text = p.label,

color = p.labelColor})

label:align(display.CENTER)

label:setPosition(cs.width / 2,label:getContentSize().height)

sprite:addChild(label)

sprite.label = label

return sprite

end

Box

function drawBoundingBox(parent,target,color)

local cbb = target:getCascadeBoundingBox()

local left,bottom, width,height = cbb.origin.x,cbb.origin.y, cbb.size.width,cbb.size.height

local points = {

{left, bottom},

{left + width,bottom},bottom + height},

{left, bottom + height},

}

local Box = display.newpolygon(points,{borderColor = color})

parent:addChild(Box,1000)

end

1.1响应触摸事件

调用函数

self.sprite = createtouchableSprite({

image = "WhiteButton.png",

size = cc.size(500,300),

label = "TOUCH ME !",

labelColor = cc.c3b(255,0,0)})

:pos(display.cx,display.cy)

:addTo(self)

drawBoundingBox(self, self.sprite,cc.c4f(0,1.0, 1.0))

-- 启用触摸

self.sprite:setTouchEnabled(true)

self.sprite:addNodeEventListener(cc.NODE_TOUCH_EVENT,function(event)

-- event.name 是触摸事件的状态:began,moved,ended,cancelled

-- event.x,event.y 是触摸点当前位置

-- event.prevX,event.prevY 是触摸点之前的位置

local label = string.format("sprite: %s x,y: %0.2f,%0.2f",event.name,event.x,event.y)

self.sprite.label:setString(label)

-- 返回 true 表示要响应该触摸事件,并继续接收该触摸事件的状态变化

return true

end)

单点触摸是最直接的使用方式了。

1.2事件穿透和事件捕获

--创建底层触摸层

self.parentButton = createtouchableSprite({

image = "WhiteButton.png",

size = cc.size(600,500),display.cy)

:addTo(self)

self.parentButton.name = "parentButton"

drawBoundingBox(self,self.parentButton, 1.0))

self.parentButton:setTouchEnabled(true)

--给该触摸层增加监听

self.parentButton:addNodeEventListener(cc.NODE_TOUCH_EVENT,function(event)

local label = string.format("parentButton: %s x,event.y)

self.parentButton.label:setString(label)

return true

end)

--在底层创建button1,button1 响应触摸后,会吞噬掉触摸事件

self.button1 = createtouchableSprite({

image = "GreenButton.png",

size = cc.size(400,160),

label = "TOUCH ME !"})

:pos(300, 400)

:addTo(self.parentButton)

cc.ui.UILabel.new({text = "SWALLOW = YES\n事件在当前对象处理后被吞噬",size = 24})

:align(display.CENTER, 200,90)

:addTo(self.button1)

drawBoundingBox(self, self.button1,cc.c4f(1.0, 1.0))

self.button1:setTouchEnabled(true)

self.button1:setTouchSwallowEnabled(true)-- 是否吞噬事件,认值为 true

self.button1:addNodeEventListener(cc.NODE_TOUCH_EVENT,function(event)

local label = string.format("button1: %s x,event.y)

self.button1.label:setString(label)

return true

end)

-- 在底层创建button2,响应触摸后,不会吞噬掉触摸事件

self.button2 = createtouchableSprite({

image = "PinkButton.png", 200)

:addTo(self.parentButton)

cc.ui.UILabel.new({text = "SWALLOW = NO\n事件会传递到下层对象",90)

:addTo(self.button2)

drawBoundingBox(self,self.button2, 1.0))

self.button2:setTouchEnabled(true)

self.button2:setTouchSwallowEnabled(false) -- 当不吞噬事件时,触摸事件会从上层对象往下层对象传递,称为穿透

self.button2:addNodeEventListener(cc.NODE_TOUCH_EVENT,event.y)

self.button2.label:setString(label)

return true

end)

事件穿透通过函数setTouchSwallowEnabled来实现。

如下函数设置是否捕捉触摸

self.parentButton:setTouchCaptureEnabled(button:isButtonSelected())

1.3在事件捕获阶段决定是否接受事件

-- 这个标志变量用于在触摸事件捕获阶段决定是否接受事件

self.isTouchCaptureEnabled_ = true

--parentButton button1 的父节点

self.parentButton = createtouchableSprite({

image = "WhiteButton.png",display.cy)

:addTo(self)

drawBoundingBox(self, 1.0))

self.parentButton.label2 = cc.ui.UILabel.new({text = "",size = 24,color = cc.c3b(0,255)})

:align(display.CENTER, 300,60)

:addTo(self.parentButton)

self.parentButton:setTouchEnabled(true)

self.parentButton:addNodeEventListener(cc.NODE_TOUCH_EVENT,event.y)

self.parentButton.label:setString(label)

printf("%s %s [targeting]","parentButton",event.name)

if event.name == "ended" or event.name == "cancelled" then

print("-----------------------------")

else

print("")

end

return true

end)

-- 可以动态捕获触摸事件,并在捕获触摸事件开始时决定是否接受此次事件

self.parentButton:addNodeEventListener(cc.NODE_TOUCH_CAPTURE_EVENT,function(event)

if event.name == "began" then

print("-----------------------------")

end

local label = string.format("parentButton CAPTURE: %s x,event.y)

self.parentButton.label2:setString(label)

printf("%s %s [CAPTURING]",event.name)

if event.name == "began" or event.name == "moved" then

return self.isTouchCaptureEnabled_

end

end)

-- button1响应触摸后,会吞噬掉触摸事件

self.button1 = createtouchableSprite({

image = "GreenButton.png", 400)

:addTo(self.parentButton)

cc.ui.UILabel.new({text = "SWALLOW = YES\n事件在当前对象处理后被吞噬",90)

:addTo(self.button1)

drawBoundingBox(self,self.button1, 1.0))

self.button1:setTouchEnabled(true)

self.button1:setTouchSwallowEnabled(true) -- 是否吞噬事件,认值为 true

self.button1:addNodeEventListener(cc.NODE_TOUCH_EVENT,event.y)

self.button1.label:setString(label)

printf("%s %s [targeting]","button1",event.name)

if event.name == "ended" or event.name == "cancelled" then

print("-----------------------------")

else

print("")

end

return true

end)

-- button2响应触摸后,不会吞噬掉触摸事件

self.button2 = createtouchableSprite({

image = "PinkButton.png",event.y)

self.button2.label:setString(label)

printf("%s %s [targeting]","button2",event.name)

return true

end)

-- 即便父对象在捕获阶段阻止响应事件,但子对象仍然可以捕获到事件,只是不会触发事件

self.button2:addNodeEventListener(cc.NODE_TOUCH_CAPTURE_EVENT,function(event)

printf("%s %s [CAPTURING]",event.name)

return true

end)

-- 放置一个开关按钮在屏幕上

local labels = {}

labels[true] = "父对象【可以】捕获触摸事件"

labels[false] = "父对象【不能】捕获触摸事件"

local images = {on = "CheckBoxButton2On.png",off = "CheckBoxButton2Off.png"}

self.captureEnabledButton = cc.ui.UICheckBoxButton.new(images)

:setButtonLabel(cc.ui.UILabel.new({text= labels[true],size = 24}))

:setButtonLabelOffset(40,0)

:setButtonSelected(true)

:onButtonStateChanged(function(event)

local button = event.target

button:setButtonLabelString(labels[button:isButtonSelected()])

end)

:onButtonClicked(function(event)

local button = event.target

self.isTouchCaptureEnabled_ = button:isButtonSelected()

end)

:pos(display.cx - 160,display.top- 80)

:addTo(self)

cc.ui.UILabel.new({

text = "事件处理流程:\n1. 【捕获】阶段:从父到子\n2. 【目标】阶段\n3. 【传递】阶段:尝试传递给下层对象",

size= 24})

:align(display.CENTER_TOP,display.cx,display.top - 120)

:addTo(self)

其中NODE_TOUCH_EVENT和 NODE_TOUCH_CAPTURE_EVENT 表示两种事件。

在NODE_TOUCH_CAPTURE_EVENT的处理函数中返回真假,然后决定是否调用NODE_TOUCH_EVENT的处理函数

1.4容器的触摸区域由子对象决定

创建一个node,在node增加几个精灵,精灵的局域决定的触摸的范围。

-- touchableNode 是启用触摸的 Node

self.touchableNode = display.newNode()

self.touchableNode:setPosition(display.cx,display.cy)

self:addChild(self.touchableNode)

-- touchableNode 中加入一些 sprite

local count = math.random(3,8)

local images = {"WhiteButton.png", "BlueButton.png","GreenButton.png", "PinkButton.png"}

for i = 1,count do

local sprite = display.newScale9Sprite(images[math.random(1,4)])

sprite:setContentSize(cc.size(math.random(100,200),math.random(100,200)))

sprite:setPosition(math.random(-200,math.random(-200,200))

self.touchableNode:addChild(sprite)

end

self.stateLabel = cc.ui.UILabel.new({text = ""})

self.stateLabel:align(display.CENTER,display.top - 100)

self:addChild(self.stateLabel)

-- 启用触摸

self.touchableNode:setTouchEnabled(true)

-- 添加触摸事件处理函数

self.touchableNode:addNodeEventListener(cc.NODE_TOUCH_EVENT,function(event)

local label = string.format("touchableNode: %s x,event.y)

self.stateLabel:setString(label)

return true

end)

drawBoundingBox(self, self.touchableNode, 1.0))

2.多点触摸

2.1响应触摸事件

-- createtouchableSprite() 定义在 includes/functions.lua

self.sprite = createtouchableSprite({

image = "WhiteButton.png",600),self.sprite, 1.0))

local labelPoints = cc.ui.UILabel.new({text = "",size = 24})

:align(display.CENTER_TOP,display.top - 120)

:addTo(self)

-- 启用触摸

self.sprite:setTouchEnabled(true)

-- 设置触摸模式

self.sprite:setTouchMode(cc.TOUCH_MODE_ALL_AT_ONCE)-- 多点

--self.sprite:setTouchMode(cc.TOUCH_MODE_ONE_BY_ONE) -- 单点(认模式)

-- 添加触摸事件处理函数

self.sprite:addNodeEventListener(cc.NODE_TOUCH_EVENT,cancelled,added(仅限多点触摸),removed(仅限多点触摸)

-- event.points 包含所有触摸点,按照 events.point[id] = {x = ?,y = ?} 的结构组织

local str = {}

for id,point in pairs(event.points) do

str[#str + 1] = string.format("id: %s,x: %0.2f,y: %0.2f",point.id,point.x,point.y)

end

local pointsCount = #str

table.sort(str)

labelPoints:setString(table.concat(str,"\n"))

if event.name == "began" or event.name == "added" then

self.touchIndex = self.touchIndex + 1

for id,point in pairs(event.points) do

local cursor = display.newSprite("Cursor.png")

:pos(point.x,point.y)

:scale(1.2)

:addTo(self)

self.cursors[id] = cursor

end

elseif event.name == "moved" then

for id,point in pairs(event.points) do

local cursor = self.cursors[id]

local rect = self.sprite:getBoundingBox()

if cc.rectContainsPoint(rect,cc.p(point.x, point.y)) then

-- 检查触摸点的位置是否在矩形内

cursor:setPosition(point.x,point.y)

cursor:setVisible(true)

else

cursor:setVisible(false)

end

end

elseif event.name == "removed" then

for id,point in pairs(event.points) do

self.cursors[id]:removeSelf()

self.cursors[id] = nil

end

else

for _,cursor in pairs(self.cursors) do

cursor:removeSelf()

end

self.cursors = {}

end

local label = string.format("sprite: %s,count = %d,index = %d",pointsCount,self.touchIndex)

self.sprite.label:setString(label)

if event.name == "ended" or event.name == "cancelled" then

self.sprite.label:setString("")

labelPoints:setString("")

end

-- 返回 true 表示要响应该触摸事件,并继续接收该触摸事件的状态变化

return true

end)

cc.ui.UILabel.new({

text = "注册多点触摸后,目标将收到所有触摸点的数据\nadded removed 指示触摸点的加入和移除",

size= 24})

:align(display.CENTER,display.top - 80)

:addTo(self)

2.2在事件捕获阶段决定是否接受事件

-- 这个标志变量用于在触摸事件捕获阶段决定是否接受事件

self.isTouchCaptureEnabled_ = true

--parentButton button1 的父节点

self.parentButton = createtouchableSprite({

image = "WhiteButton.png",function(event)

local label = string.format("parentButton: %s",event.name)

self.parentButton.label:setString(label)

printf("%s %s [targeting]",function(event)

if event.name == "began" then

print("-----------------------------")

end

local label = string.format("parentButton CAPTURE: %s",event.name)

self.parentButton.label2:setString(label)

printf("%s %s [CAPTURING]", 1.0))

self.button1:setTouchEnabled(true)

self.button1:setTouchMode(cc.TOUCH_MODE_ALL_AT_ONCE)-- 多点

self.button1:setTouchSwallowEnabled(true) -- 是否吞噬事件,认值为 true

self.button1:addNodeEventListener(cc.NODE_TOUCH_EVENT,function(event)

local label = string.format("button1: %s count: %d",table.nums(event.points))

self.button1.label:setString(label)

printf("%s %s [targeting]", 1.0))

self.button2:setTouchEnabled(true)

self.button2:setTouchMode(cc.TOUCH_MODE_ALL_AT_ONCE)-- 多点

self.button2:setTouchSwallowEnabled(false) -- 当不吞噬事件时,触摸事件会从上层对象往下层对象传递,称为穿透

self.button2:addNodeEventListener(cc.NODE_TOUCH_EVENT,table.nums(event.points))

self.button2.label:setString(label)

printf("%s %s [targeting]",display.top - 120)

:addTo(self)

2.3容器的触摸区域由子对象决定

-- touchableNode 是启用触摸的 Node

self.touchableNode = display.newNode()

self.touchableNode:setPosition(display.cx,display.top - 100)

self:addChild(self.stateLabel)

-- 启用触摸

self.touchableNode:setTouchEnabled(true)

self.touchableNode:setTouchMode(cc.TOUCH_MODE_ALL_AT_ONCE)-- 多点

-- 添加触摸事件处理函数

self.touchableNode:addNodeEventListener(cc.NODE_TOUCH_EVENT,function(event)

local str = {}

for id,point.y)

end

self.stateLabel:setString(table.concat(str,"\n"))

return true

end)

drawBoundingBox(self,self.touchableNode, 1.0))

--

app:createNextButton(self)

app:createTitle(self, "多点触摸测试 - 容器的触摸区域由子对象决定")

原文地址:https://www.jb51.cc/cocos2dx/343998.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐