使SKPhysicsBody单向运动

3

我有一个SKSpriteNode球,它已经被赋予了所有的SKPhysicsBody属性,可以在所有方向上移动。现在我想让它变为单向(只能向它之前没有移动过的方向移动,并且不回到之前移动过的路径中)。目前我对解决这个问题有以下想法:

  • 通过创建一个fieldBitMask,将迭代的路径上的球反弹,以防止其返回。
  • touchesBegan/ touchesMoved方法中对球施加某种力/脉冲,使其不会回去。
  • update方法中处理。
  • 从Stack Overflow得到的代码实现,感谢贡献者! :)

以下是支持性代码片段,以更好地理解问题:

//getting current touch position by using UIEvent methods
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch = touches.first else {return}
        let location = touch.location(in: self)
        lastTouchPoint = location
    }
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch = touches.first else {return}
        let location = touch.location(in: self)
        lastTouchPoint = location
    }
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        lastTouchPoint = nil
    }
    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        lastTouchPoint = nil
    }

//ball created
    func createPlayer(){
        player = SKSpriteNode(imageNamed: "player")
        player.position = CGPoint(x: 220, y: 420)
        player.zPosition = 1

    //physics for ball
    player.physicsBody = SKPhysicsBody(circleOfRadius: player.size.width / 2)
    player.physicsBody?.allowsRotation = false
    player.physicsBody?.linearDamping =  0.5


    player.physicsBody?.categoryBitMask = collisionTypes.player.rawValue
    player.physicsBody?.contactTestBitMask = collisionTypes.finish.rawValue
    player.physicsBody?.collisionBitMask = collisionTypes.wall.rawValue

    addChild(player)
}

//unwarp the optional property, calclulate the postion between player touch and current ball position
override func update(_ currentTime: TimeInterval) {
    guard isGameOver == false else { return }
    if let lastTouchPosition = lastTouchPoint {
        //this usually gives a large value (related to screen size of the device) so /100 to normalize it
        let diff = CGPoint(x: lastTouchPosition.x - player.position.x, y: lastTouchPosition.y - player.position.y)
        physicsWorld.gravity = CGVector(dx: diff.x/100, dy: diff.y/100)
    }
}

明天我要提交这个,任何帮助都将不胜感激;( - Frostmourne
1个回答

0

这是一些在touchesBegan/ touchesMovedupdate函数中的小技巧组合。

首先,您需要捕获触摸发生的位置,并获取其名称(在我的情况下,我创建了alpha为0的节点,但在移动到它们上方时变得可见,即alpha为1)。在touchesBegan, touchesMoved中按如下方式操作:

                        guard let touch = touches.first else {return}
                        let location = touch.location(in: self)
                        lastTouchPoint = location

                        let positionInScene = touch.location(in: self)
                        let touchedNode = self.atPoint(positionInScene)

                        if let name = touchedNode.name
                        {
                            if name == "vortex"
                            {
                                touching = false
                                self.view!.isUserInteractionEnabled = false
                                print("Touched on the interacted node")
                            }else{
                                self.view!.isUserInteractionEnabled = true
                                touching = true
                            }
                        }
                    }

其次,使用BOOL touching来跟踪用户在屏幕上的交互,可以通过设置一个点击识别器来实现,如下所示:

func setupTapDetection() {
        let t = UITapGestureRecognizer(target: self, action: #selector(tapped(_:)))
        view?.addGestureRecognizer(t)
    }

@objc func tapped(_ tap: UITapGestureRecognizer) {
        touching = true
    }

最后在update中添加以下检查:

        guard isGameOver == false else { return }
        self.view!.isUserInteractionEnabled = true

        if(touching ?? true){
            if let lastTouchPosition = lastTouchPoint {
                //this usually gives a large value (related to screen size of the device) so /100 to normalize it
                let diff = CGPoint(x: lastTouchPosition.x - player.position.x, y: lastTouchPosition.y - player.position.y)
                physicsWorld.gravity = CGVector(dx: diff.x/100, dy: diff.y/100)
            }
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接