在SKScene中间放置一个physicsBody



我不确定如何问这个问题,但我有一个SKSpriteNode在我的SKScene。我希望它位于y轴的中间,但在滑动(向上/向下)时,要让重力影响它,直到它返回到y轴的中间。

示例设置:
1- SKSpriteNode在默认位置(在x轴上的位置并不重要,但在y轴的中间)
2-用户向上滑动
3- SKSpriteNode受到applyImpulse()在+y或-y方向的影响
重力影响SKSpriteNote在-y或+y(分别)方向
5- SKSpriteNode移动回默认位置(因为重力)

我该如何执行呢?
我尝试过的事情:
- radialGravityField(没有达到我的预期)
- linearGravityFieldWithVector(我有点失败了)
-创建2个不同重力的矩形(失败了)
-检查SKSpriteNode y位置是否为<或>,而不是屏幕中间,这取决于滑动是向上还是向下,如果是,重置位置。正在检查didSimulatePhysics。这不起作用,据我所知,它会重置位置,但在调试时,即使重置后SKSpriteNode也不在y轴的中间

让我知道,如果你需要我的代码,但所有我正在寻找的是这样做的方法

谢谢:)

编辑

下面是我用来检查精灵位置是否为<或>大于y轴的中间

override func didMoveToView(view: SKView) {
//set the players default position
playerDefaultPosition = CGPoint(x: self.size.width * 0.2, y: self.size.height / 2)

//background
backgroundColor = SKColor.whiteColor()
//world physics
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
//create player
playerNode.position = playerDefaultPosition
playerNode.physicsBody = SKPhysicsBody(rectangleOfSize: playerNode.size)
playerNode.physicsBody?.mass = 300
playerNode.physicsBody?.linearDamping = 0
addChild(playerNode)

}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let yTouch = touches.first?.locationInNode(self).y {
        self.touches.append(yTouch)
        startTime = NSDate()
        }
    }
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let yTouch = touches.first?.locationInNode(self).y {
        self.touches.append(yTouch)
    }
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let yTouch = touches.first?.locationInNode(self).y {
        endTime = NSDate()
        self.touches.append(yTouch)
        if !self.touches.isEmpty {
            let velocity = getVelocity(self.touches, startTime: startTime, endTime: endTime)
            movePlayer(velocity)
        }

    }
func getVelocity(touchArray: [CGFloat], startTime: NSDate, endTime: NSDate) -> CGFloat {
    var v: CGFloat = 0
    if !touchArray.isEmpty {
        //get velocity from v = d/t
        let t = CGFloat(endTime.timeIntervalSinceDate(startTime))
        let d = touchArray.last! - touchArray.first!
        v = d / t
    }
    return v
}
func movePlayer(v: CGFloat) {
    let vector = CGVector(dx: 0.0, dy: v * 30)
    if vector.dy > 0 {
        //player going in +y direction
        swipedUp = true
        self.physicsWorld.gravity = CGVector(dx: 0.0, dy: -10)
    } else {
        //player going in -y direction
        swipedUp = false
        self.physicsWorld.gravity = CGVector(dx: 0.0, dy: 10)
    }
    playerNode.physicsBody?.applyImpulse(vector)

}
override func didSimulatePhysics() {
    if playerNode.position.y < (self.view?.frame.height)! / 2 - 1 && swipedUp || playerNode.position.y > (self.view?.frame.height)! / 2 + 1 && !swipedUp {
        self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
        playerNode.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 0))
        print("gravity set to 0")
        playerNode.position = playerDefaultPosition
    }
}

经过更多的调试,似乎在它设置了playerNode.position = playerDefaultPosition之后,下一帧的playerNode.position.y < (self.view?.frame.height)! / 2 - 1 && swipedUp仍然为真

编辑2

查看文档,我实现了在一帧期间调用的每个函数,并检查了每个函数调用期间的位置playerNode.position.y,似乎发生了一些事情,当SKScene模拟物理,使playerNode从其默认位置移动到不同的位置。

也许只是检查节点的y位置,当节点的y <框架。midley(或>)关闭该节点的重力。

尝试将Y方向的脉冲矢量设置回0

override func update(currentTime: NSTimeInterval) {
    if playerNode.position.y < (self.view?.frame.height)! / 2 - 1 && swipedUp || playerNode.position.y > (self.view?.frame.height)! / 2 + 1 && !swipedUp {
        self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
        print("gravity set to 0")
        let vector = CGVector(dx: 0.0, dy: 0.0)
        playerNode.physicsBody?.applyImpulse(vector)
        playerNode.position = playerDefaultPosition

    }
}

@Steve在didSimulatePhysics()中对applyImpulse()说的话是对的。因为这个物体仍然有一个力作用在它上面(由于它下落),我不得不把它移走。你可以通过找到它下来的力来做到这一点(这对我来说比必要的代码更多),或者我可以让它成为.dynamic = false,并在我需要的时候重新启用它。

下面是我现在的文字:

override func didFinishUpdate() {
    print(playerNode.position.y)
    if playerNode.position.y < (self.view?.frame.height)! / 2 - 10 && swipedUp || playerNode.position.y > (self.view?.frame.height)! / 2 + 10 && !swipedUp {
        //turn off all forces on the Node    
        playerNode.physicsBody?.dynamic = false
        self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
        playerNode.position = playerDefaultPosition
    }
}

最新更新