ios - 将物理主体保留在 SKScene 的中间?

标签 ios swift sprite-kit

我不知道如何问这个问题,但我的 SKScene 中有一个 SKSpriteNode。我希望它位于 y 轴的中间,但通过滑动(向上/向下)使其受到重力影响,直到它返回到 y 轴的中间。

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

我将如何执行此操作?
我尝试过的事情:
- RadialGravityField(未按我的预期执行)
- LinearGravityFieldWithVector(我有点失败了)
- 创建 2 个具有不同重力的矩形(失败得很惨)
- 检查 SKSpriteNode y 位置是否 < 或 > 于屏幕中间,具体取决于滑动是向上还是向下,如果是,则重置位置。签到didSimulatePhysics 。这不起作用,据我所知,它会重置位置,但是在调试时,即使在重置之后,SKSpriteNode 也不位于 y 轴的中间

如果您需要我的代码,请告诉我,但我正在寻找的只是一种执行此操作的方法

谢谢:)

编辑

这是我用来检查 Sprite 位置是否 < 或 > 于 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

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

最佳答案

也许只检查节点的 y 位置,当节点的 y < frame.middleY (或 > )时关闭该节点的重力。滑动后重新打开。

关于ios - 将物理主体保留在 SKScene 的中间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32742525/

相关文章:

ios - 如何使用外部文件 .plist 或 .xcconfig 启用部分代码

ios - iPad 纵向模式下的 Split View - 弹出按钮标题

ios - 如何在 MKMapView swift 中添加覆盖路径

ios - 修复具有大量状态的巨型 View Controller

ios - Sprite-kit:运动过程中位移的物理体

ios - 暂停 Sprite Kit 物理游戏在 iOS 9 上无法正常工作

Sprite-Kit 为单个接触注册多个碰撞

ios - 如何更改 iOS SDK 4.2 的 UISwitch 文本?

ios - 从 'const b2Shape*' 到 'b2PolygonShape*' 的动态转换会放弃限定符吗?

swift - 从 swift 1.0 到 1.2 的固定功能