我正在尝试将节点放在触摸位置,但遇到.nodes()
返回父节点和同一“位置的其他节点的问题。
我尝试了十几种不同的代码配置,但似乎无法找到使用SKScene.convert()
或SKScene.convertPoint()
和其他人的正确顺序....
基本上,我有一个垂直节点的分层树...顶部是父节点,下面每个节点都是直接在顶部的子节点...(见下图)
当我点击最底部节点时,我在我的场景中运行.nodes()
获得了多次点击...我正在尝试仅在我点击的确切位置获取节点...当我点击某个地方我不希望父节点或其他节点在同一个“位置”或相同的“.position”打印...我只是试图获得我触摸的确切位置的节点... < / p>
以下是我正在使用的图片...当您点击/点按屏幕时,它会打印出哪些节点位于触摸位置:
这是我的点击代码(请记住,每个节点都是从上到下的父/子,而SKNode.name
只是一个数字作为标识符):
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let allNodes = nodes(at: touches.first!.location(in: self))
for node in allNodes { print( node.name! ) }
}
我已经尝试了十几种不同的方式将触摸点转换为UIView
或SKNode
坐标等等。我无法正确...这是我点击时的输出右下角的节点:
(同样,数字只是创建顺序中节点的名称......):
8
7
5
4
2
1
当我点击右下方的节点时,应该只打印1-2个节点,而是我打印了6个节点......这是因为他们.postion
是“相同的”我相信SK的混乱坐标系统有时= /
所以,我的解决方法是创建一个基于Y值工作的过滤器...换句话说,只有我点击的一般区域周围的节点才会被打印...但是我的操作已经很密集了,所以我试图不必为这个列表创建一个过滤器......
我真的认为有一种方法可以在我点击的地方获取节点
但是我无法找到.nodes()
和.location(in:)
的正确组合来做到这一点。
我尝试过玩.atPoint
并使用.position
,但没有运气......
我现在迷路了,不想创建一个文件管理器:{
答案 0 :(得分:3)
如果我在您的项目中了解您的节点,每个节点都有不同的父节点。当您点击屏幕时,您触摸了一个特定的点,但在当前场景中检测到这一点&#39; self&#39; (你所在的班级touchesBegan
)所以当你触摸关系父母/孩子中最深的节点时,触摸的节点也会显示他的父母。
但是你只想要触点可见区域中涉及的节点/节点,所以我认为你在这种情况下可以做的是获取转换到当前类(self)的每个节点的帧并检查触点是否包含在此框架中。
在下面的这个例子中,我使用了4个节点:
import SpriteKit
class GameScene: SKScene {
var node5:SKSpriteNode!
var node6:SKSpriteNode!
var node7:SKSpriteNode!
var node8:SKSpriteNode!
override func didMove(to view: SKView) {
let startPos = CGPoint(x:self.frame.midX,y:self.frame.midY)
node5 = SKSpriteNode.init(color: .yellow, size: CGSize(width:50,height:60))
self.addChild(node5)
node5.name = "5"
node5.position = CGPoint(x:startPos.x+35,y:startPos.y-180)
node6 = SKSpriteNode.init(color: .blue, size: CGSize(width:50,height:60))
node5.addChild(node6)
node6.name = "6"
node6.position = CGPoint(x:60,y:0)
node7 = SKSpriteNode.init(color: .green, size: CGSize(width:80,height:60))
node6.addChild(node7)
node7.name = "7"
node7.position = CGPoint(x:60,y:10)
node8 = SKSpriteNode.init(color: .red, size: CGSize(width:80,height:60))
node7.addChild(node8)
node8.name = "8"
node8.position = CGPoint(x:-10,y:20)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let positionInScene = touch!.location(in: self)
let allNodes = nodes(at: positionInScene)
for node in allNodes {
let nodePositionConverted = self.convert(node.position, from: node)
let nodeFrameConverted = CGRect(origin: CGPoint(x:nodePositionConverted.x-node.frame.maxX,y:nodePositionConverted.y-node.frame.maxY),size:node.frame.size)
if nodeFrameConverted.contains(positionInScene), let n = node.name {print(n)}
}
}
}
<强>输出强>:
此输出显示不同的水龙头。第一次点击涉及3个节点,红色8,绿色7和蓝色6.确实你需要调试控制台:
第二次点击只涉及绿色7和蓝色6:
第三和第四次点击仅涉及蓝色和黄色节点,因此您只分别触及每个节点的数量。
最后一次点击涉及红色8和蓝色6,所以你有:
希望这对你的触摸有所帮助。