SpriteKit 跟踪多次触摸
SpriteKit tracking multiple touches
我有几个移动主角的按钮。 (向左、向右、跳跃等)但是,当我一次触摸多个按钮时,前一个按钮就结束了。我的问题是,如何在触摸期间保持两个触摸都有效?例如,这将允许角色向前移动并同时跳跃。我已将 multipleTouchEnabled 设置为 true。我读过使用字典来跟踪触摸会有所帮助,但我似乎无法理解实现。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInView(nil)
if location.x < self.size.width / 2 && location.y > self.size.height / 2 {
movingLeft = true
}
if location.x > self.size.width / 2 && location.y > self.size.height / 2 {
movingRight = true
}
if location.x < self.size.width / 2 && location.y < self.size.height / 2 {
jump()
}
if location.x > self.size.width / 2 && location.y < self.size.height / 2 {
jump()
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
movingLeft = false
movingRight = false
}
func jump() {
mainCharacter.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
mainCharacter.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 400))
}
逻辑
您应该创建一个活动触摸字典。
private var activeTouches = [UITouch:String]()
每次触摸开始时,您都会将其保存到字典中并为其指定一个标签。
activeTouches[touch] = "left"
所以当触摸结束时你可以在你的字典中搜索它并找到相关的标签。现在你知道用户释放了哪个按钮了。
let button = activeTouches[touch]
if button == "left" { ... }
别忘了将其从字典中删除。
activeTouches[touch] = nil
实施
class GameScene: SKScene {
private var activeTouches = [UITouch:String]()
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let button = findButtonName(from:touch)
activeTouches[touch] = button
tapBegin(on: button)
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
guard let button = activeTouches[touch] else { fatalError("Touch just ended but not found into activeTouches")}
activeTouches[touch] = nil
tapEnd(on: button)
}
}
private func tapBegin(on button: String) {
print("Begin press \(button)")
// your custom logic goes here
}
private func tapEnd(on button:String) {
print("End press \(button)")
// your custom logic goes here
}
private func findButtonName(from touch: UITouch) -> String {
// replace this with your custom logic to detect a button location
let location = touch.locationInView(self.view)
if location.x > self.view?.frame.midX {
return "right"
} else {
return "left"
}
}
}
在上面的代码中,您应该将自己的代码放入
tapBegin
:这个方法接收一个按钮的标签并开始一些动作。
E.g. start running.
tapEnd
:此方法接收按钮的标签并停止某些操作。
E.g. stop running.
findButtonName
:该方法接收一个UITouch
和returns用户按下按钮的标签。
测试
我在 iPhone 上测试了之前的代码。我执行了以下操作。
- 开始按屏幕右
- 开始按屏幕左
- 从屏幕右边移除手指
- 从屏幕左侧移除手指
正如您在以下日志中看到的,代码能够识别不同的触摸
Begin press right
Begin press left
End press right
End press left
结论
我希望我说清楚了。如果不是,请告诉我。
我有几个移动主角的按钮。 (向左、向右、跳跃等)但是,当我一次触摸多个按钮时,前一个按钮就结束了。我的问题是,如何在触摸期间保持两个触摸都有效?例如,这将允许角色向前移动并同时跳跃。我已将 multipleTouchEnabled 设置为 true。我读过使用字典来跟踪触摸会有所帮助,但我似乎无法理解实现。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInView(nil)
if location.x < self.size.width / 2 && location.y > self.size.height / 2 {
movingLeft = true
}
if location.x > self.size.width / 2 && location.y > self.size.height / 2 {
movingRight = true
}
if location.x < self.size.width / 2 && location.y < self.size.height / 2 {
jump()
}
if location.x > self.size.width / 2 && location.y < self.size.height / 2 {
jump()
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
movingLeft = false
movingRight = false
}
func jump() {
mainCharacter.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
mainCharacter.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 400))
}
逻辑
您应该创建一个活动触摸字典。
private var activeTouches = [UITouch:String]()
每次触摸开始时,您都会将其保存到字典中并为其指定一个标签。
activeTouches[touch] = "left"
所以当触摸结束时你可以在你的字典中搜索它并找到相关的标签。现在你知道用户释放了哪个按钮了。
let button = activeTouches[touch]
if button == "left" { ... }
别忘了将其从字典中删除。
activeTouches[touch] = nil
实施
class GameScene: SKScene {
private var activeTouches = [UITouch:String]()
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let button = findButtonName(from:touch)
activeTouches[touch] = button
tapBegin(on: button)
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
guard let button = activeTouches[touch] else { fatalError("Touch just ended but not found into activeTouches")}
activeTouches[touch] = nil
tapEnd(on: button)
}
}
private func tapBegin(on button: String) {
print("Begin press \(button)")
// your custom logic goes here
}
private func tapEnd(on button:String) {
print("End press \(button)")
// your custom logic goes here
}
private func findButtonName(from touch: UITouch) -> String {
// replace this with your custom logic to detect a button location
let location = touch.locationInView(self.view)
if location.x > self.view?.frame.midX {
return "right"
} else {
return "left"
}
}
}
在上面的代码中,您应该将自己的代码放入
tapBegin
:这个方法接收一个按钮的标签并开始一些动作。E.g. start running.
tapEnd
:此方法接收按钮的标签并停止某些操作。E.g. stop running.
findButtonName
:该方法接收一个UITouch
和returns用户按下按钮的标签。
测试
我在 iPhone 上测试了之前的代码。我执行了以下操作。
- 开始按屏幕右
- 开始按屏幕左
- 从屏幕右边移除手指
- 从屏幕左侧移除手指
正如您在以下日志中看到的,代码能够识别不同的触摸
Begin press right
Begin press left
End press right
End press left
结论
我希望我说清楚了。如果不是,请告诉我。