处理触摸事件,检查是否有按钮

时间:2014-02-23 12:43:50

标签: lua corona

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

  1. 当你没有触摸图像时,它没有反应。
  2. 如果你正确触摸但移动了一点,那么它是滞后的,并且拍摄按钮不起作用。
  3. 如果它像这样工作我会很高兴:

    1. 当触摸按钮时或按下按钮时,请旋转我的船。的完成
    2. 当你稍微移动手指然后仍然旋转船。的完成
    3. 如果你只是点击,然后旋转一点。的完成
    4. 如果您将手指放在按钮上,则旋转5°,然后再旋转约8°。 完成
    5. 现在,当我触摸其中一个dpads并触摸拍摄按钮时,它会停止旋转。这需要修复,我不知道如何。我需要能够在旋转时拍摄。
    6. 那么这就是我尝试使用我的代码。

      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)
      

3 个答案:

答案 0 :(得分:0)

根据我的理解,您的左右D-pad触摸事件不需要拖动任何类型。在这种情况下,不需要事件的“移动”阶段。你只需要检查开始和结束。想一想,一旦用户的手指开始触摸事件,你的按钮就会被“按下”。

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

答案 1 :(得分:0)

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

假设我猜错了,那么你的问题就太多了:每次解决一件事。比如,首先让需求1工作,然后是2,然后是3,然后是4.不要从2开始直到1工作。您可能会发现它一切正常,不需要SO!否则,您将更加具体地了解您,以便您可以大大简化您的问题,并获得更多有用的帮助。

更新:现在你已经解决了所有4个(方式去!),你的新项目(#5):

我的猜测是,一旦你触摸拍摄,dpad的触摸事件就会结束,这会关闭holdLeft / Right的计时器。你可能可以使用multitouch来处理它:你将检查处理程序中的event.id,你将能够忽略它的触摸,所以你的旋转将继续。

答案 2 :(得分:0)

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