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

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

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},

        {left + width, bottom + height},

        {left, bottom + height},

        {left, bottom},

    }

    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, 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 是触摸点之前的位置

        locallabel = 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),

            label = "TOUCH ME !",

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

        :pos(display.cx, display.cy)

        :addTo(self)

    self.parentButton.name = "parentButton"

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

self.parentButton:setTouchEnabled(true)

--给该触摸层增加监听

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

        locallabel = string.format("parentButton: %s x,y: %0.2f, %0.2f",event.name, event.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,0, 0, 1.0))

 

self.button1:setTouchEnabled(true)

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

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

        locallabel = string.format("button1: %s x,y: %0.2f, %0.2f",event.name, event.x,event.y)

        self.button1.label:setString(label)

        return true

    end)

 

 

 

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

    self.button2 = createTouchableSprite({

            image = "PinkButton.png",

            size = cc.size(400,160),

            label = "TOUCH ME !"})

        :pos(300, 200)

        :addTo(self.parentButton)

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

        :align(display.CENTER, 200, 90)

        :addTo(self.button2)

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

 

    self.button2:setTouchEnabled(true)

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

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

        locallabel = string.format("button1: %s x,y: %0.2f, %0.2f",event.name, event.x,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",

            size = cc.size(600,500),

            label = "TOUCH ME !",

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

        :pos(display.cx, display.cy)

        :addTo(self)

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

 

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

        :align(display.CENTER, 300, 60)

        :addTo(self.parentButton)

 

    self.parentButton:setTouchEnabled(true)

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

        locallabel = string.format("parentButton: %s x,y: %0.2f, %0.2f",event.name, event.x,event.y)

        self.parentButton.label:setString(label)

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

        if event.name == "ended" orevent.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

 

        locallabel = string.format("parentButton CAPTURE: %s x,y: %0.2f, %0.2f",event.name, event.x,event.y)

        self.parentButton.label2:setString(label)

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

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

            returnself.isTouchCaptureEnabled_

        end

    end)

 

    -- 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,0, 0, 1.0))

 

    self.button1:setTouchEnabled(true)

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

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

        locallabel = string.format("button1: %s x,y: %0.2f, %0.2f",event.name, event.x,event.y)

        self.button1.label:setString(label)

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

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

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

        else

            print("")

        end

        return true

    end)

 

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

    self.button2 = createTouchableSprite({

            image = "PinkButton.png",

            size = cc.size(400,160),

            label = "TOUCH ME !"})

        :pos(300, 200)

        :addTo(self.parentButton)

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

        :align(display.CENTER, 200, 90)

        :addTo(self.button2)

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

 

    self.button2:setTouchEnabled(true)

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

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

        locallabel = string.format("button1: %s x,y: %0.2f, %0.2f",event.name, event.x,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]","button2", 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)

            localbutton = event.target

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

        end)

        :onButtonClicked(function(event)

            localbutton = 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, countdo

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

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

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

        self.touchableNode:addChild(sprite)

    end

 

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

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

    self:addChild(self.stateLabel)

 

    -- 启用触摸

    self.touchableNode:setTouchEnabled(true)

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

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

        locallabel = string.format("touchableNode: %s x,y: %0.2f, %0.2f",event.name, event.x,event.y)

        self.stateLabel:setString(label)

        return true

    end)

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

 

 

2.  多点触摸

 

2.1         响应触摸事件

 

 

 

-- createTouchableSprite() 定义在 includes/functions.lua中

    self.sprite = createTouchableSprite({

            image = "WhiteButton.png",

            size = cc.size(500,600),

            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, 0, 1.0))

 

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

        :align(display.CENTER_TOP, display.cx,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,function(event)

        -- event.name 是触摸事件的状态:began, moved, ended, cancelled, added(仅限多点触摸), removed(仅限多点触摸)

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

        localstr = {}

        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

        localpointsCount = #str

        table.sort(str)

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

 

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

            self.touchIndex = self.touchIndex + 1

            forid, point in pairs(event.points)do

                localcursor = display.newSprite("Cursor.png")

                    :pos(point.x,point.y)

                    :scale(1.2)

                    :addTo(self)

                self.cursors[id] =cursor

            end

        elseifevent.name == "moved"then

            forid, point in pairs(event.points)do

                localcursor = self.cursors[id]

                localrect = 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

        elseifevent.name == "removed"then

            forid, 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

 

        locallabel = string.format("sprite: %s , count = %d, index = %d",event.name, pointsCount,self.touchIndex)

        self.sprite.label:setString(label)

 

        if event.name == "ended" orevent.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.cx,display.top -80)

        :addTo(self)

 

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

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

    self.isTouchCaptureEnabled_ =true

 

    --parentButton 是 button1的父节点

    self.parentButton = createTouchableSprite({

            image = "WhiteButton.png",

            size = cc.size(600,500),

            label = "TOUCH ME !",

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

        :pos(display.cx, display.cy)

        :addTo(self)

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

 

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

        :align(display.CENTER, 300, 60)

        :addTo(self.parentButton)

 

    self.parentButton:setTouchEnabled(true)

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

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

        self.parentButton.label:setString(label)

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

        if event.name == "ended" orevent.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

 

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

        self.parentButton.label2:setString(label)

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

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

            returnself.isTouchCaptureEnabled_

        end

    end)

 

    -- 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,0, 0, 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)

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

        self.button1.label:setString(label)

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

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

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

        else

            print("")

        end

        return true

    end)

 

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

    self.button2 = createTouchableSprite({

            image = "PinkButton.png",

            size = cc.size(400,160),

            label = "TOUCH ME !"})

        :pos(300, 200)

        :addTo(self.parentButton)

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

        :align(display.CENTER, 200, 90)

        :addTo(self.button2)

    drawBoundingBox(self,self.button2, cc.c4f(0,0, 1.0, 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,function(event)

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

        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]","button2", 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)

            localbutton = event.target

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

        end)

        :onButtonClicked(function(event)

            localbutton = 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)

 

 

 

 

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

-- touchableNode 是启用触摸的 Node

    self.touchableNode = display.newNode()

   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值