如何精确检测何时触摸 SKShapeNode?
How to detect precisely when a SKShapeNode is touched?
我正在使用 Swift 和 SpriteKit。
我有以下情况:
这里,每个"triangles"都是一个SKShapenode。
我的问题是,我想检测何时有人触摸了正在触摸哪个三角形的屏幕。
我假设所有这些三角形的碰撞箱都是矩形,所以我的函数 returns 我接触了所有碰撞箱,而我只想知道实际接触了哪个碰撞箱。
有什么方法可以让碰撞箱与形状完美匹配,而不是矩形?
这是我当前的代码:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
let touch = touches.first
let touchPosition = touch!.locationInNode(self)
let touchedNodes = self.nodesAtPoint(touchPosition)
print(touchedNodes) //this should return only one "triangle" named node
for touchedNode in touchedNodes
{
if let name = touchedNode.name
{
if name == "triangle"
{
let triangle = touchedNode as! SKShapeNode
// stuff here
}
}
}
}
您可以尝试使用 CGPathContainsPoint
和 SKShapeNode
而不是 nodesAtPoint
,后者更合适:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
let touch = touches.first
let touchPosition = touch!.locationInNode(self)
self.enumerateChildNodesWithName("triangle") { node, _ in
// do something with node
if node is SKShapeNode {
if let p = (node as! SKShapeNode).path {
if CGPathContainsPoint(p, nil, touchPosition, false) {
print("you have touched triangle: \(node.name)")
let triangle = node as! SKShapeNode
// stuff here
}
}
}
}
}
这是最简单的方法。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
for touch in touches {
let location = touch.locationInNode(self)
if theSpriteNode.containsPoint(location) {
//Do Whatever
}
}
}
我使用 Swift 4 的方式:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else {
return
}
let touchPosition = touch.location(in: self)
let touchedNodes = nodes(at: touchPosition)
for node in touchedNodes {
if let mynode = node as? SKShapeNode, node.name == "triangle" {
//stuff here
mynode.fillColor = .orange //...
}
}
}
我正在使用 Swift 和 SpriteKit。
我有以下情况:
这里,每个"triangles"都是一个SKShapenode。 我的问题是,我想检测何时有人触摸了正在触摸哪个三角形的屏幕。 我假设所有这些三角形的碰撞箱都是矩形,所以我的函数 returns 我接触了所有碰撞箱,而我只想知道实际接触了哪个碰撞箱。
有什么方法可以让碰撞箱与形状完美匹配,而不是矩形?
这是我当前的代码:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
let touch = touches.first
let touchPosition = touch!.locationInNode(self)
let touchedNodes = self.nodesAtPoint(touchPosition)
print(touchedNodes) //this should return only one "triangle" named node
for touchedNode in touchedNodes
{
if let name = touchedNode.name
{
if name == "triangle"
{
let triangle = touchedNode as! SKShapeNode
// stuff here
}
}
}
}
您可以尝试使用 CGPathContainsPoint
和 SKShapeNode
而不是 nodesAtPoint
,后者更合适:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
let touch = touches.first
let touchPosition = touch!.locationInNode(self)
self.enumerateChildNodesWithName("triangle") { node, _ in
// do something with node
if node is SKShapeNode {
if let p = (node as! SKShapeNode).path {
if CGPathContainsPoint(p, nil, touchPosition, false) {
print("you have touched triangle: \(node.name)")
let triangle = node as! SKShapeNode
// stuff here
}
}
}
}
}
这是最简单的方法。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
for touch in touches {
let location = touch.locationInNode(self)
if theSpriteNode.containsPoint(location) {
//Do Whatever
}
}
}
我使用 Swift 4 的方式:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else {
return
}
let touchPosition = touch.location(in: self)
let touchedNodes = nodes(at: touchPosition)
for node in touchedNodes {
if let mynode = node as? SKShapeNode, node.name == "triangle" {
//stuff here
mynode.fillColor = .orange //...
}
}
}