Ios nodeAtPoint错误节点

Ios nodeAtPoint错误节点,ios,swift,sprite-kit,Ios,Swift,Sprite Kit,我正在用swift和spritekit制作一个游戏,我有一个功能,可以让多个精灵从屏幕顶部掉落。我还制作了它,这样我就可以使用nodeAtPoint检测到精灵上的触摸,并可以轻弹精灵。我的问题是,由于nodeAtPoint拖动树中最深的节点,当我单击并拖动精灵时,场景中最新的精灵会被拉向我的触摸方向,而不是我最初触摸的那个。如果有人对如何只影响我接触的节点有一些建议,我会非常感激 class GameScene: SKScene { var ball = SKSpriteNod

我正在用swift和spritekit制作一个游戏,我有一个功能,可以让多个精灵从屏幕顶部掉落。我还制作了它,这样我就可以使用nodeAtPoint检测到精灵上的触摸,并可以轻弹精灵。我的问题是,由于nodeAtPoint拖动树中最深的节点,当我单击并拖动精灵时,场景中最新的精灵会被拉向我的触摸方向,而不是我最初触摸的那个。如果有人对如何只影响我接触的节点有一些建议,我会非常感激

    class GameScene: SKScene {

    var ball = SKSpriteNode(imagedNamed: "blueBlue")

    var touchedNode: SKNode? = SKNode()

     override func didMoveToView(view: SKView) {

       var create = SKAction.runBlock({() in self.createTargets()})
            var wait = SKAction.waitForDuration(2)
            var waitAndCreateForever = SKAction.repeatActionForever(SKAction.sequence([create, wait]))
            self.runAction(waitAndCreateForever)
    }


        func createTargets() {
             ball = SKSpriteNode(imageNamed: "blueBlue")
             let randomx = Int(arc4random_uniform(170) + 290)
             ball.zPosition = 0
            ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.width / 11)

            ball.physicsBody?.dynamic = true
            ball.size = CGSize(width: ball.size.width / 1.5, height: ball.size.height / 1.5)
            let random = Int(arc4random_uniform(35))

            let textures = [texture1, texture2, texture3, texture4, texture5, texture6, texture7, texture8, texture9, texture10, texture11, texture12, texture13, texture14, texture15, texture16, texture17, texture18, texture19, texture20, texture21, texture22, texture23, texture24, texture25, texture1, texture7, texture18, texture24, texture25, texture1, texture7, texture18, texture24, texture25]

            ball.texture = textures[random] 
            ball.position = CGPoint(x: randomx, y: 1400) 
            addChild(ball)
    }
        override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
            let touch = touches.first as! UITouch
            let touchLocation = touch.locationInNode(self)
           touchedNode = self.nodeAtPoint(touchLocation)
            if touchedNode.frame.contains(touchLocation) {
            touching = true
            touchPoint = touchLocation
            }
       }

        override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
            let touch = touches.first as! UITouch
            let touchLocation = touch.locationInNode(self)
            touching = true
            touchPoint = touchLocation

        }
     override func update(currentTime: NSTimeInterval) {

            if touching {

                if touchPoint != touchedNode.position {

                    let dt: CGFloat = 0.1

                    let distance = CGVector(dx: touchPoint.x - touchedNode.position.x, dy: touchPoint.y - touchedNode.position.y)

                    let vel = CGVector(dx: distance.dx / dt, dy: distance.dy / dt)

                    if touchedNode.parent != nil {

                    touchedNode.physicsBody?.velocity = vel

                }    
             }
            }  
        }
    }
class游戏场景:SKScene{
var ball=SKSpriteNode(图像名称:“蓝蓝蓝”)
var touchedNode:SKNode?=SKNode()
覆盖func didMoveToView(视图:SKView){
var create=SKAction.runBlock({()在self.createTargets()中)
var wait=SKAction.waitForDuration(2)
var waitAndCreateForever=SKAction.repeatActionForever(SKAction.sequence([create,wait]))
self.runAction(waitAndCreateForever)
}
func createTargets(){
ball=SKSpriteNode(图像名为:“蓝蓝蓝”)
设randomx=Int(arc4random_均匀(170)+290)
ball.zPosition=0
ball.physicsBody=SKPhysicsBody(圆形半径:ball.size.width/11)
ball.physicsBody?动态=真
ball.size=CGSize(宽度:ball.size.width/1.5,高度:ball.size.height/1.5)
设random=Int(arc4random_均匀(35))
让纹理=[纹理1、纹理2、纹理3、纹理4、纹理5、纹理6、纹理7、纹理8、纹理9、纹理10、纹理11、纹理12、纹理13、纹理14、纹理15、纹理16、纹理17、纹理18、纹理19、纹理20、纹理21、纹理22、纹理23、纹理24、纹理25、纹理17、纹理18、纹理18、纹理18、纹理18,纹理24,纹理25]
ball.texture=纹理[随机]
ball.position=CGPoint(x:randomx,y:1400)
addChild(球)
}
覆盖func touchesBegined(触摸:设置,withEvent事件:UIEvent){
让touch=touch.first as!UITouch
让touchLocation=touch.locationInNode(自身)
touchedNode=self.nodeAtPoint(touchLocation)
如果touchedNode.frame.contains(触摸位置){
触摸=真实
接触点=接触位置
}
}
覆盖功能触摸移动(触摸:设置,withEvent事件:UIEvent){
让touch=touch.first as!UITouch
让touchLocation=touch.locationInNode(自身)
触摸=真实
接触点=接触位置
}
覆盖函数更新(当前时间:NSTimeInterval){
如果接触{
如果接触点!=touchedNode.position{
设dt:CGFloat=0.1
让距离=CGVector(dx:touchPoint.x-touchedNode.position.x,dy:touchPoint.y-touchedNode.position.y)
设vel=CGVector(dx:distance.dx/dt,dy:distance.dy/dt)
如果touchedNode.parent!=nil{
touchedNode.physicsBody?.velocity=vel
}    
}
}  
}
}

我建议您对代码进行以下更改:

  • 添加检查以查看是否已移动精灵(如果是,则不执行任何操作)
  • 关闭正在移动的精灵的
    受重力影响的属性
  • 触摸结束时重置
    touched节点
    触摸
    变量
  • 下面是一个包含上述更改的实现

    触摸开始
    触摸移动
    替换为以下内容

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        let touch = touches.first as! UITouch
        let touchLocation = touch.locationInNode(self)
        if (!touching) {
            let node = self.nodeAtPoint(touchLocation)
            if node is SKSpriteNode {
                touchedNode = node
                touching = true
                touchPoint = touchLocation
                touchedNode!.physicsBody?.affectedByGravity = false
            }
        }
    }
    
    override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
        if (touching) {
            let touch = touches.first as! UITouch
            let touchLocation = touch.locationInNode(self)
            touchPoint = touchLocation
        }
    }
    
    override func touchsbegined(touchs:Set,withEvent-event:UIEvent){
    让touch=touch.first as!UITouch
    让touchLocation=touch.locationInNode(自身)
    如果(!触摸){
    让node=self.nodeAtPoint(touchLocation)
    如果节点是SKSpriteNode{
    touchedNode=节点
    触摸=真实
    接触点=接触位置
    touchedNode!.physicsBody?.affectedByGravity=false
    }
    }
    }
    覆盖功能触摸移动(触摸:设置,withEvent事件:UIEvent){
    如果(触摸){
    让touch=touch.first as!UITouch
    让touchLocation=touch.locationInNode(自身)
    接触点=接触位置
    }
    }
    
    并添加此方法

    override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
        if (touchedNode != nil) {
            touchedNode!.physicsBody!.affectedByGravity = true
        }
        touchedNode = nil
        touching = false
    }
    
    override func touchesend(touchs:Set,withEvent-event:UIEvent){
    if(touchedNode!=nil){
    touchedNode!.physicsBody!.affectedByGravity=true
    }
    touchedNode=nil
    触摸=错误
    }
    
    嘿,谢谢你的建议。我使用了你的代码,不幸的是我仍然有同样的问题。但是我注意到,如果我让节点陷得更深一点,我可以成功地拖动我单击的节点。也许这可以帮助我尝试做什么?我没有遇到你描述的问题,我看不到这是怎么发生的ing提供了代码。我可以正确选择并拖动从屏幕顶部掉落的精灵。我没有发布完整的代码,因此可能代码中有其他内容干扰了它。总之,这一切都很好,因为我将游戏更改为不需要拖动这些节点。再次感谢不确定这是否有助于您,但请参见:@EpicByte looks就像OP的代码是基于你的帖子。我发现很有趣的是,代码设置了移动物理体的速度,而不是使用力或脉冲。我从其他人那里得到了代码,他们可能是从你的帖子中得到的。@0x141E我总是选择直接设置速度,而不是通过applyImpulse/force方法间接设置速度,特别是如果我正在执行自定义实时计算,例如移动到某个点,模拟浮力等,它也会稍微快一点,让我完全控制计算。我应用冲量和力的唯一时间是在我不进行计算的情况下