【问题标题】:Handling touch events, check if one is holding a button处理触摸事件,检查是否持有按钮
【发布时间】:2014-02-25 15:44:45
【问题描述】:

我为此制作了自己的脚本,但是它不想正常工作:

  1. 当您不直接触摸图像时,它不会做出反应。
  2. 如果触摸正常但稍微移动了一点,那就是卡顿了,拍摄按钮不起作用。

如果它像这样工作,我会很高兴:

  1. 当触摸按钮周围或周围时,旋转我的船。 完成
  2. 当您稍微移动手指时,仍要旋转飞船。 完成
  3. 如果您只是点击,然后稍微旋转一下。 完成
  4. 如果您将手指放在按钮上,则旋转 5°,稍长一点后旋转约 8°。 完成
  5. 现在,当我触摸其中一个 dpad 并触摸拍摄按钮时,它会停止旋转。这需要修复,我不知道如何。我需要能够在旋转时进行拍摄。

好吧,这就是我用我的代码尝试过的。

local isPressed = false
local tmr_holdFlight
local touchedXTimes = 0

function holdingLeft()
    if isPressed == true then
        if rotationOfship > 0 then
            if touchedXTimes < 10 then
                rotationOfship = rotationOfship-2
                touchedXTimes = touchedXTimes + 1
                ship.rotation = rotationOfship
            elseif touchedXTimes > 9 then 
                rotationOfship = rotationOfship-5
                touchedXTimes = touchedXTimes + 1
                ship.rotation = rotationOfship  
            elseif touchedXTimes > 29 then
                rotationOfship = rotationOfship-8
                touchedXTimes = touchedXTimes + 1
                ship.rotation = rotationOfship                                       
            end 
            print(touchedXTimes)
        else 
            rotationOfship = 360
        end
    elseif isPressed == false then 
        timer.cancel(tmr_hold)
        isPressed = false
    end
end

function holdingRight()
    if isPressed == true then
        if rotationOfship < 360 then
            if touchedXTimes < 10 then
                rotationOfship = rotationOfship+2
                touchedXTimes = touchedXTimes + 1
                ship.rotation = rotationOfship
            elseif touchedXTimes > 9 then 
                rotationOfship = rotationOfship+5
                touchedXTimes = touchedXTimes + 1
                ship.rotation = rotationOfship  
            elseif touchedXTimes > 29 then
                rotationOfship = rotationOfship+8
                touchedXTimes = touchedXTimes + 1
                ship.rotation = rotationOfship                                       
            end 
            print(touchedXTimes)
        else 
            rotationOfship = 0
        end
    elseif isPressed == false then 
        timer.cancel(tmr_hold)
    end
end

function onDpadLeftTouch(event)
    -- body
    if event.phase=='began' then
        display.getCurrentStage():setFocus(event.target)
    end

     if event.phase=='began' then
        isPressed = true
        if tmr_hold ~= nil then timer.cancel(tmr_hold) end
        tmr_hold = timer.performWithDelay( 8, holdingLeft, 0)
    elseif event.phase == "ended" then
        isPressed = false
        timer.cancel(tmr_hold)
        display.getCurrentStage():setFocus(nil)
        touchedXTimes = 0
    end
end

function onDpadRightTouch(event)
    -- body
    if event.phase=='began' then
        display.getCurrentStage():setFocus(event.target)
    end

    if event.phase=='began' then
        isPressed = true
        if tmr_hold ~= nil then timer.cancel(tmr_hold) end
        tmr_hold = timer.performWithDelay( 8, holdingRight, 0)
    elseif event.phase=='ended' then
        isPressed = false
        timer.cancel(tmr_hold)
        display.getCurrentStage():setFocus(nil)
        touchedXTimes = 0
    end
end

local function pointAtDistance(angle, distance)
    -- Convert angle to radians as lua math functions expect radians
    local r = math.rad(angle)
    local x = math.cos(r) * distance
    local y = math.sin(r) * distance    
    return x, y
end

local isShooting = false

function resetShooting()
    isShooting = false
end

function onLaserButtonTouch(event)
    if event.phase == "began" and isShooting == false then
        isShooting = true

        bullet = display.newImageRect("images/laser.png",math.random(5,20),5/2)
            bullet.x = halfW
            bullet.y = halfH                
            bullet.name = "bullet"
            bullet.rotation = rotationOfship-90
            physics.addBody( bullet, "dynamic", { isSensor=true, radius=10} )
            group:insert(bullet)

        ship:toFront()

        audio.play( laserSound, { channel=2, loops=0}  )

        local newX, newY = pointAtDistance(rotationOfship-90, 400)

        bullet:setLinearVelocity( newX/2, newY/2 )

        tmr_shoot = timer.performWithDelay( math.random(300,400), resetShooting, 1)
    elseif event.phase=='ended' then

    end     
end

dpad_left = display.newImageRect("images/dpad/left.png", 78/2, 78/2)
    dpad_left.x = 50
    dpad_left.y = 260
    group:insert(dpad_left)
    dpad_left:addEventListener("touch", onDpadLeftTouch)

dpad_right = display.newImageRect("images/dpad/right.png", 78/2, 78/2)
    dpad_right.x = 100
    dpad_right.y = 260
    group:insert(dpad_right)
    dpad_right:addEventListener("touch", onDpadRightTouch)

laser_button = display.newImageRect("images/dpad/laser.png", 78/2, 78/2)
    laser_button.x = 430
    laser_button.y = 260
    group:insert(laser_button)
    laser_button:addEventListener("touch", onLaserButtonTouch)

【问题讨论】:

  • 你的描述很难理解,所以我重新格式化以显示它是如何出现的,请看一下。假设是这样,那么你的问题就太多了:一次解决每一件事情。就像,首先让要求 1 工作,然后是 2,然后是 3,然后是 4。在 1 工作之前不要从 2 开始。您可能会发现在 SO 上您只剩下这四个项目中的一个,然后您可以大大简化您的问题,您将获得更多有用的帮助(詹姆斯的回答是一个勇敢的努力,但很难判断它是否再次提及所有 4 个项目,太多了)。
  • 您好,感谢您的帮助,所以我昨天坐下来解决了所有 4 个问题。谢谢你告诉我我应该一块一块地解决它。我认为它为我节省了一些时间:D。现在我只有一个问题,然后我就解决了所有问题。并且问题已添加到列表及其编号 5 中。其他一切都按我希望的方式工作。谢谢你的时间:)
  • 很高兴听到,这比我预期的要好。我把它变成了一个答案。
  • 是的,现在只剩下第 5 个问题。 :/ 你知道怎么解决吗?

标签: lua coronasdk


【解决方案1】:

据我了解,您的左右方向键触摸事件不需要任何类型的拖动。在这种情况下,不需要事件的“移动”阶段。您只需要检查开始和结束。考虑一下,一旦用户的手指开始触摸事件,您的按钮就会“按下”。

function onDpadLeftTouch(event)
    -- body
    if event.phase=='began' then
        display.getCurrentStage():setFocus(event.target)
        isPressed = true
        if tmr_hold ~= nil then timer.cancel(tmr_hold) end
        tmr_hold = timer.performWithDelay( 8, holdingLeft, 0)
    elseif event.phase == "ended" then
        isPressed = false
        timer.cancel(tmr_hold)
        display.getCurrentStage():setFocus(nil)
    end
end

function onDpadRightTouch(event)
    -- body
    if event.phase=='began' then
        display.getCurrentStage():setFocus(event.target)
        isPressed = true
        if tmr_hold ~= nil then timer.cancel(tmr_hold) end
        tmr_hold = timer.performWithDelay( 8, holdingRight, 0)
    elseif event.phase=='ended' then
        isPressed = false
        timer.cancel(tmr_hold)
        display.getCurrentStage():setFocus(nil)
    end
end

免责声明:我没有在 Corona 中与 getCurrentStage() 合作过,所以我不知道这是否会产生连锁反应。此外(这应该不是问题,但请注意以防事件永远结束)如果用户将手指从按钮上拖到按钮的不同部分,您可能必须取消事件提升前的屏幕。这只是将检查添加到每个按钮事件的移动阶段的情况(您显然会将其放回同一位置)。示例(假设中心锚点/参考点):

elseif event.phase == "moved" then
    if(event.x > (dpad_left.x + (dpad_left.contentWidth/2))) or (event.x < (dpad_left.x - (dpad_left.contentWidth/2))) or (event.y > (dpad_left.y + (dpad_left.contentHeight/2))) or (event.y < (dpad_left.y - (dpad_left.contentHeight/2))) then 
        isPressed = false
        timer.cancel(tmr_hold)
        display.getCurrentStage():setFocus(nil)
    end
elseif event.phase == "ended" or event.phase == "cancelled" then
    --etc...

可能看起来有点乱,但它可以完成工作。

编辑:为了完整性,还建议在触摸事件的“向上”部分检查“结束”和“取消”,因为“取消”处理系统在没有您请求的情况下取消您的触摸事件的任何情况.所以代替:

elseif event.phase == "ended" then

使用:

elseif event.phase == "ended" or event.phase == "cancelled" then

【讨论】:

  • 哦,嘿,谢谢你的回答。但是当我移动手指时,计时器不会取消
  • 在 timer.cancel 事件的开头添加一个打印,这样你就可以看到它实际上被调用了。如果不是,则向已移动部分添加打印,该部分打印 dpad 对象(dpad_left 或 dpad_right)的边界和事件的位置(x 和 y)。当你移动手指时,你会得到很多打印,但它会告诉你正在检查哪些值,这应该让你知道为什么没有调用 timer.cancel 事件
  • 感谢您的帮助,现在我只有一个问题 :) 它的数字 5,如果您知道我会非常感激
  • 抱歉延迟响应,但如果您还没有解决它,请检查其中一个触摸事件是否没有修改正在以取消旋转事件的方式旋转的对象跨度>
【解决方案2】:

您的描述很难理解,所以我重新格式化以显示它是如何出现的,请看一下。

假设我猜对了,那么您的问题中包含的内容太多了:一次解决每个问题。就像,首先让要求 1 工作,然后是 2,然后是 3,然后是 4。在 1 工作之前不要从 2 开始。您可能会发现一切正常,不需要 SO!否则,您将了解得更具体,这样您就可以大大简化您的问题,并获得更多有用的帮助。

更新:既然你已经解决了所有 4 个问题(路要走!),你的新项目(#5):

我的猜测是,一旦您触摸拍摄,来自 dpad 的触摸事件就会结束,这会关闭保持左/右的计时器。您可能可以使用multitouch:您将检查处理程序中的 event.id 并且您将能够忽略它拍摄触摸,因此您的旋转将继续。

【讨论】:

    【解决方案3】:

    您想在物体旋转时拍摄物体,那么您需要定义两个不同的事件。例如:旋转对象的触摸事件和拍摄对象的点击事件..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      • 1970-01-01
      • 2011-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多