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:addNodeEvent@R_404_6818@ener(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:addNodeEvent@R_404_6818@ener(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:addNodeEvent@R_404_6818@ener(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:addNodeEvent@R_404_6818@ener(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:addNodeEvent@R_404_6818@ener(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:addNodeEvent@R_404_6818@ener(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:addNodeEvent@R_404_6818@ener(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:addNodeEvent@R_404_6818@ener(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:addNodeEvent@R_404_6818@ener(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:addNodeEvent@R_404_6818@ener(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:addNodeEvent@R_404_6818@ener(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:addNodeEvent@R_404_6818@ener(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:addNodeEvent@R_404_6818@ener(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, "多点触摸测试 - 容器的触摸区域由子对象决定")
总结以上是内存溢出为你收集整理的quick-cocos2d-x 学习系列之十三 触摸全部内容,希望文章能够帮你解决quick-cocos2d-x 学习系列之十三 触摸所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)