为什么被触摸的 SKSpriteNode 在被快速拖离和进入游戏视图后停止移动?
Why has the touched SKSpriteNode stopped moving after being quickly dragged off and on game view?
我已经在我的游戏中实现了 SKSpriteNodes 的多点触控拖动。
它正在运行,但是当然有一个错误。
在 iOS 模拟器中,
情况 1:如果我在可视屏幕周围拖动一个节点,然后继续将节点拖离可视屏幕,它会消失,然后继续将节点拖回到屏幕上,它会正常显示。这很好。只有慢慢来才有效。
案例 2:如果我做完全相同的动作(如案例 1 中所述),除了这次我做的非常快,当节点重新出现在屏幕上时,它会 "stick" 到一个点屏幕。此时我还没有结束触摸,即鼠标按钮仍然被按住。在模拟器上看起来我什么也没拖。
预期的行为是触摸开始后,在触摸位置创建节点(工作正常),拖动节点(工作)然后如果节点被拖出屏幕,触摸应该结束,并且应删除该节点。
正在字典数组中跟踪节点和触摸。
在屏幕截图中,我单击一次,节点出现,一直按住并开始多次快速将其拖到屏幕左侧。它创建了许多本应消失的节点。如果我慢慢地拖出屏幕然后再拖回到屏幕上,它不会产生 "extra" 个节点。
我已经在 GitHub 上放置了我的代码的简化版本,供您自己尝试这个问题。我在这个问题上花了大约 10 个小时,但没有找到解决方案。非常感谢您的帮助。
GitHub repository Whosebug Game1 project
var selectedNodes:[UITouch:SKSpriteNode] = [UITouch:SKSpriteNode]()
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
for touch:AnyObject in touches{
var location = touch.locationInNode(self)
// Add in the node
var hero = SKSpriteNode(imageNamed: "Player")
hero.name = "player"
// Make sure it is not off of the screen.
hero.position = location
self.addChild(hero)
let touchObj = touch as UITouch
selectedNodes[touchObj] = hero
}
}
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
for touch:AnyObject in touches {
//println("touhex count \(touches.count)")
let location = touch.locationInNode(self)
let touchObj = touch as UITouch
//println("Touches moved current loc: \(location)")
// Update the position of the sprites
if let node:SKSpriteNode? = selectedNodes[touchObj] {
if (node?.name == "player" || node?.name == "bar")
{
let size:CGFloat = CGFloat(node!.size.width)/2
node?.position = location
}
}
}
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
for touch:AnyObject in touches {
let touchObj = touch as UITouch
let location = touch.locationInNode(self)
println("Touch Ended \(location)")
if let exists:AnyObject? = selectedNodes[touchObj] {
println("attempt to remove")
let node:SKSpriteNode? = self.nodeAtPoint(location) as? SKSpriteNode
println("ended touch locaiton \(location)")
println("ended npde position \(node?.position)")
for (node) in selectedNodes{
println("Touch n1 \(node.1.position)")
}
if (node?.name == "player")
{
println("removed")
node?.removeFromParent()
selectedNodes[touchObj] = nil
}
}
}
}
问题是当你快速移动它时,touchesEnded
函数可能会在没有更新位置的情况下触发。
在您的 touchesEnded
函数中,不要使用 nodeAtPoint
,只需使用 exists.removeFromParent()
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
for touch:AnyObject in touches {
let touchObj = touch as UITouch
if let exists:SKNode = selectedNodes[touchObj] {
if (exists.name == "player")
{
exists.removeFromParent()
selectedNodes[touchObj] = nil
}
}
}
}
我已经在我的游戏中实现了 SKSpriteNodes 的多点触控拖动。
它正在运行,但是当然有一个错误。
在 iOS 模拟器中, 情况 1:如果我在可视屏幕周围拖动一个节点,然后继续将节点拖离可视屏幕,它会消失,然后继续将节点拖回到屏幕上,它会正常显示。这很好。只有慢慢来才有效。
案例 2:如果我做完全相同的动作(如案例 1 中所述),除了这次我做的非常快,当节点重新出现在屏幕上时,它会 "stick" 到一个点屏幕。此时我还没有结束触摸,即鼠标按钮仍然被按住。在模拟器上看起来我什么也没拖。
预期的行为是触摸开始后,在触摸位置创建节点(工作正常),拖动节点(工作)然后如果节点被拖出屏幕,触摸应该结束,并且应删除该节点。
正在字典数组中跟踪节点和触摸。
在屏幕截图中,我单击一次,节点出现,一直按住并开始多次快速将其拖到屏幕左侧。它创建了许多本应消失的节点。如果我慢慢地拖出屏幕然后再拖回到屏幕上,它不会产生 "extra" 个节点。
我已经在 GitHub 上放置了我的代码的简化版本,供您自己尝试这个问题。我在这个问题上花了大约 10 个小时,但没有找到解决方案。非常感谢您的帮助。 GitHub repository Whosebug Game1 project
var selectedNodes:[UITouch:SKSpriteNode] = [UITouch:SKSpriteNode]()
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
for touch:AnyObject in touches{
var location = touch.locationInNode(self)
// Add in the node
var hero = SKSpriteNode(imageNamed: "Player")
hero.name = "player"
// Make sure it is not off of the screen.
hero.position = location
self.addChild(hero)
let touchObj = touch as UITouch
selectedNodes[touchObj] = hero
}
}
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
for touch:AnyObject in touches {
//println("touhex count \(touches.count)")
let location = touch.locationInNode(self)
let touchObj = touch as UITouch
//println("Touches moved current loc: \(location)")
// Update the position of the sprites
if let node:SKSpriteNode? = selectedNodes[touchObj] {
if (node?.name == "player" || node?.name == "bar")
{
let size:CGFloat = CGFloat(node!.size.width)/2
node?.position = location
}
}
}
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
for touch:AnyObject in touches {
let touchObj = touch as UITouch
let location = touch.locationInNode(self)
println("Touch Ended \(location)")
if let exists:AnyObject? = selectedNodes[touchObj] {
println("attempt to remove")
let node:SKSpriteNode? = self.nodeAtPoint(location) as? SKSpriteNode
println("ended touch locaiton \(location)")
println("ended npde position \(node?.position)")
for (node) in selectedNodes{
println("Touch n1 \(node.1.position)")
}
if (node?.name == "player")
{
println("removed")
node?.removeFromParent()
selectedNodes[touchObj] = nil
}
}
}
}
问题是当你快速移动它时,touchesEnded
函数可能会在没有更新位置的情况下触发。
在您的 touchesEnded
函数中,不要使用 nodeAtPoint
,只需使用 exists.removeFromParent()
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
for touch:AnyObject in touches {
let touchObj = touch as UITouch
if let exists:SKNode = selectedNodes[touchObj] {
if (exists.name == "player")
{
exists.removeFromParent()
selectedNodes[touchObj] = nil
}
}
}
}