【问题标题】:Differentiate between touch count SKSpriteNode区分触摸计数 SKSpriteNode
【发布时间】:2016-09-12 13:31:33
【问题描述】:

下面,我已经实现了测试来了解可触摸精灵的触摸计数行为 (sprite.isUserInteractionEnabled = true)

入住时:

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch: AnyObject in touches {
        print("touched sprite = name:'WalkBoyTouchSprite'", "tapCount=", touch.tapCount, NSDate())
    }
}

以下是我的一些触摸结果:

当我经常触摸时,它只会不断增加触摸次数:

touched sprite = name:'WalkBoyTouchSprite' tapCount= 1 2016-09-12 13:11:50 +0000
performSingleTapActions
触摸精灵 = 名称:'WalkBoyTouchSprite' tapCount= 2 2016-09-12 13:11:51 +0000
performDoubleTapActions
触摸精灵 = 名称:'WalkBoyTouchSprite' tapCount= 3 2016-09-12 13:11:51 +0000
performTriippleTapActions
触摸精灵 = 名称:'WalkBoyTouchSprite' tapCount= 4 2016-09-12 13:11:51 +0000
触摸精灵 = 名称:'WalkBoyTouchSprite' tapCount= 5 2016-09-12 13:11:51 +0000
触摸精灵 = 名称:'WalkBoyTouchSprite' tapCount= 6 2016-09-12 13:11:52 +0000
触摸精灵 = 名称:'WalkBoyTouchSprite' tapCount= 7 2016-09-12 13:11:52 +0000


然后,一旦我暂停了一段时间,它就会从 1 开始计数,再次检查休息时间。

touched sprite = name:'WalkBoyTouchSprite' tapCount= 1 2016-09-12 13:11:53 +0000
执行SingleTapActions


touched sprite = name:'WalkBoyTouchSprite' tapCount= 1 2016-09-12 13:12:16 +0000
performSingleTapActions
触摸精灵 = 名称:'WalkBoyTouchSprite' tapCount= 2 2016-09-12 13:12:17 +0000
performDoubleTapActions
触摸精灵 = 名称:'WalkBoyTouchSprite' tapCount= 3 2016-09-12 13:12:17 +0000
执行TriippleTapActions


touched sprite = name:'WalkBoyTouchSprite' tapCount= 1 2016-09-12 13:12:18 +0000
performSingleTapActions
触摸精灵 = 名称:'WalkBoyTouchSprite' tapCount= 1 2016-09-12 13:12:20 +0000
执行SingleTapActions


touched sprite = name:'WalkBoyTouchSprite' tapCount= 1 2016-09-12 13:12:21 +0000
performSingleTapActions
触摸精灵 = 名称:'WalkBoyTouchSprite' tapCount= 2 2016-09-12 13:12:21 +0000
执行DoubleTapActions

一旦点击 1 次,我需要执行一项操作,如果点击 2 次,则执行另一项操作(如您在测试日志中看到的那样)。但问题是它按顺序调用。这意味着如果我在各自的触摸计数上应用 Action1、Action2 和 Action3,所有 3 都将被激活。

什么是区分单点触控和多点触控的聪明方法?就像我能得到确切的所需暂停时间(之后它从 1 开始计数),或者其他更好的东西。

【问题讨论】:

  • 只在 switch 语句中使用点击计数
  • 仍然会调用 case 1 然后 2 然后 3。
  • 哦,我明白了,如果你双击,你希望第一个被忽略
  • 是的,没错,在所有水龙头的情况下都是一样的。每个点击计数都需要作为不同的事件。即使计数不同也不要触摸。
  • 然后点击计数不是你想要的,你可以切换到将所需的动作保存在一个块中,然后将一个点击手势附加到视图,当手势命令执行时,触发对应的块触摸

标签: ios swift cocos2d-iphone sprite-kit touch


【解决方案1】:

UITouch 包含 tapCount 以及 timestamp。为了做你想做的事,你需要定义一套清晰的点击规则。这定义了您支持的抽头数量以及可接受的持续时间和抽头的截止时间。其中一些需要玩游戏来调整最有效的时间值。

根据您的规则,您可以创建一个状态机来控制触发游戏事件的原因(例如,这是一个 1 次点击事件)。关键部分是一旦您确定发生了事件,就能够“清除”来自额外触摸的任何传入噪音。

让我们从 1 次触摸事件开始。为此,您需要在抽头之间定义一些 dt(增量时间),这构成了 dt 在没有另一个抽头的情况下被超过,它将被视为只有 1 个抽头。因此,即使您获得更多基于点击的触摸事件,一旦超过 dt 阈值,您将忽略它们。

为了做到这一点,您需要定期运行额外的逻辑(通常是帧速率),以跟踪过去的输入(即,您正在跟踪输入的历史记录)。例如,逻辑可能是这样的:

if  (now - lastGoodTap.timestamp) > THRESHOLD) {
    // Do my one tap goodness
}

您真的希望在 2 个地方运行:跟踪输入历史的周期性输入逻辑和处理 touchesEnded 事件的输入逻辑(检查 lastGoodTap 和当前时间戳是否按顺序超过阈值分类是 1 点击还是现在 2)。在touchesEnded 中,如果您收到下一个tapCount(即tapCount == 2)并且尚未达到阈值,您现在将此事件归类为2 次点击场景。

执行 2 次和 3 次点击是 1 次点击情况的扩展。对于具有特殊动作或进行多次点击的游戏,您实际上需要跟踪输入状态。我通常支持特殊动作以及诸如调试之类的秘密输入。通常我会创建另一个类来跟踪这个历史状态。它引用了UITouch,但复制了timestamp,并跟踪它认为当前的点击计数是多少。

请记住,您将使用 UITouch 实例作为输入流的键/引用,因为这会让您知道您正在查看相同的触摸。如果您使用多点触控,这一点很重要。

此外,您将需要处理不间断多次点击的情况,以确保您做正确的事情(例如,您总是可以丢弃一个 tapCount > 3 的 UITouch)。

对此进行建模的一种简单方法是使用空项目并使用NSLog 来帮助实时观看事件和状态。

【讨论】:

    【解决方案2】:

    我找到了解决方案,或者说 Hack。我给它一些时间让用户点击。这次从用户的第一次点击开始,在 X 秒后结束。在此期间注册的所有点击都将是我将招待的点击计数。

    类似这样的:

    var touchCount = 0
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        //to implement multiple touch
    
        if self.touchCount == 0 {
            self.delay(1.0, closure: {
                //self.delegate?.touched(self, touches: touches, with : event)
                self.touchingFinished()
            })
        }
    
        //increment touch count
        self.touchCount += 1
    }
    
    func touchingFinished() {
        print("tapping finished, count = ", touchCount)
        switch self.touchCount {
        case 1://do one thing
        case 2://do other thing
        default://do somethign
            break;
        }
        //touch task done now re initialize touchCount
        self.touchCount = 0
    }
    

    一旦你开始你的任务序列,别忘了禁用userInteraction

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2018-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多