我有一个SKSpriteNode作为球,所有的SKPhysicsBody属性都向各个方向移动。我现在想要的是将其设置为unidirectional (仅沿它之前从未移动过的方向移动,并且不返回其已移动过的路径)。目前,我对这个问题有以下想法:

  • fieldBitMask创建到它迭代的路径并排斥
    球不回去
  • 通过force/ impulses方法在球上应用某种touchesBegan/ touchesMoved,以防止其回溯
  • 可以用update方法
  • 处理的东西
  • 是stackflowoverflow的救星,即使在周末也要编码:)

  • 支持代码片段以更好地理解,
    //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)
        }
    }
    

    最佳答案

    嗯,这是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)
                }
            }
        }
    

    关于ios - 使SKPhysicsBody单向,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60018022/

    10-10 21:04