我有一个应用程序,每隔1秒在屏幕上产生一个球。现在,我希望用户触摸那些使它们消失的球(removeFromParent())。据我所知,我必须通过touchesBegan设置触摸功能,我这样做,这是我的代码:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches{
let positionOfTouch = touch.location(in: self)
enumerateChildNodes(withName: "BALL") { (node: SKNode, nil) in
if positionOfTouch == node.position {
print("just touched the ball")
}
else{
print("error")
}
}
}
问题是,当我触摸屏幕/球时控制台打印错误而不是只是触球,这意味着我的代码不起作用。此外,控制台将错误消息打印为我视图中的球数。我不知道我做错了什么,以及如何真正设置这个功能。 这是我的createBall函数,它从我的BallNode类(类型SKShapeNode)实现:
func createBall(){
let ball = BallNode(radius: 65)
print(ball.Name)
print(ball._subName!)
ball.position.y = ((frame.size.height) - 200)
let ballXPosition = arc4random_uniform(UInt32(frame.size.width)) // set the ball a randon position from the top of the screen
ball.position.x = CGFloat(ballXPosition)
ball.physicsBody?.categoryBitMask = PhysicsCategory.ball // ball's category bitMask
ball.physicsBody?.collisionBitMask = PhysicsCategory.ball // prevent objects from intersecting
ball.physicsBody?.contactTestBitMask = PhysicsCategory.topBorder // when need to know if two objects touch each other
addChild(ball)
}
你可以帮帮我吗?因为我快速退出了swift,我也希望得到一些关于这种触摸检测的解释(和一般的接触 - 苹果文档很差)。
答案 0 :(得分:2)
每次触摸屏幕时,您都会在所有球中骑自行车,看看您是否正在触摸其中一个。如果你在屏幕上有50个球,它会通过它们看看你是否正在接触1.这不是一个有效的方法来确定你是否正在接触1。
有很多方法可以做到这一点,但我要做的是处理Ball类内部的触摸。这样你就不必弄清楚你是否正在接触一个球以及它可能是一个球。
在您的BallNode课程中协议的解释(尽我所能)现在看起来似乎有点多了,但你学习和理解的协议越快,你就越好(IMO)。
在这个例子中,我们将使用一个协议来设置一个委托 BallNode类。协议是一组用户定义的规则&#34;那一定是 然后是您指定符合该协议的任何类。 在我的例子中,我声明一个类要符合 BallNodeDelegate协议它必须包含didClick func。当你 在GameScene之后添加BallNodeDelegate,你说明了这一点 class将符合该协议。所以,如果你在GameScene中做到了 没有didClick func它会导致错误。所有这些都被放入了 这样你就可以轻松地在你的人之间进行交流 BallNode实例和您的GameScene类(无需传递 围绕每个BallNode的GameScene引用)。每个BallNode 然后有一个委托(GameScene)你可以传回来 信息到。
确保您拥有isUserInteraction = true
创建一个协议,将触摸信息发送回GameScene
protocol BallNodeDelegate: class {
func didClick(ball: BallNode)
}
在BallNode类中创建一个委托变量
weak var delegate: BallNodeDelegate!
移动触摸开始你的BallNode类
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.delegate?.didClick(ball: self)
}
GameScene中的将合规性添加到BallNode协议
class GameScene: SKScene, BallNodeDelegate
当你创建一个Ball时,在GameScene中确保你设置了它的代表
let ball = BallNode()
ball.delegate = self
在GameScene中添加嵌套。用于处理点击的func
func didClick(ball: BallNode) {
print("clicked ball")
}
答案 1 :(得分:1)
您正在将完全触摸点与节点的完全位置进行比较,这些位置不太可能相同。
if positionOfTouch == node.position {
相反,您需要进行测试,以确定用户的触摸是否足够接近到球的位置。
一种选择是使用SKNode
的{{1}}函数,它将为您处理此问题。
contains
旁注:您可能希望使用if node.contains(positionOfTouch) {
代替SKSpriteNode
,因为SKShapeNode
在SpriteKit中的效果不佳。
答案 2 :(得分:0)