SKSpriteNode在碰撞时失去速度

时间:2016-08-29 17:01:50

标签: ios iphone swift xcode sprite-kit

我正在制作iOS应用并遇到一些物理问题。正如您可以通过下面的.GIF所知,当我旋转六边形并且球以一定角度撞击矩形时,它会失去一些速度并且不会反弹得那么高。这是因为共享here的原因(主要是因为我约束球的水平位置,它只是在击中角度时使用垂直速度,从而失去速度)。

我无法为我的生活找到解决方案来解决这个问题。有没有人有任何想法?

Ball节点代码:

func createBallNode(ballColor: String) -> SKSpriteNode {
    let ball = SKSpriteNode(imageNamed: ballColor)
    ball.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame)+30)
    ball.zPosition = 1

    ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.width/2)
    ball.physicsBody?.affectedByGravity = true
    ball.physicsBody?.restitution = 1
    ball.physicsBody?.linearDamping = 0
    ball.physicsBody?.friction = 0

    ball.physicsBody?.categoryBitMask = ColliderType.Ball.rawValue
    ball.physicsBody?.contactTestBitMask = ColliderType.Rect.rawValue
    ball.physicsBody?.collisionBitMask = ColliderType.Rect.rawValue

    let centerX = ball.position.x
    let range = SKRange(lowerLimit: centerX, upperLimit: centerX)

    let constraint = SKConstraint.positionX(range)
    ball.constraints = [constraint]

    return ball
}

enter image description here

1 个答案:

答案 0 :(得分:1)

是的,问题可能是因为当球没有完全“对齐”时,球击中六边形。在这种情况下,球的垂直速度会偏离水平轴。

因为你想要一个“离散逻辑”我相信这种情况你应该避免物理学(至少对于弹跳部分)。重复垂直移动球的SKAction会容易得多。

实施例

我准备了一个简单的例子

class GameScene: SKScene {

    override func didMove(to view: SKView) {
        super.didMove(to: view)
        let ball = createBallNode()
        self.addChild(ball)
    }

    func createBallNode() -> SKSpriteNode {
        let ball = SKSpriteNode(imageNamed: "ball")
        ball.position = CGPoint(x: frame.midX, y: frame.minY + ball.frame.height / 2)

        let goUp = SKAction.move(by: CGVector(dx: 0, dy: 600), duration: 1)
        goUp.timingMode = .easeOut

        let goDown = SKAction.move(by: CGVector(dx: 0, dy: -600), duration: 1)
        goDown.timingMode = .easeIn

        let goUpAndDown = SKAction.sequence([goUp, goDown])
        let forever = SKAction.repeatForever(goUpAndDown)
        ball.run(forever)
        return ball
    }
}

enter image description here

更新

如果您需要在每次球接触Hexagon底座时执行检查,您可以使用此代码

class GameScene: SKScene {

    override func didMove(to view: SKView) {
        super.didMove(to: view)
        let ball = createBallNode()
        self.addChild(ball)
    }

    func createBallNode() -> SKSpriteNode {
        let ball = SKSpriteNode(imageNamed: "ball")
        ball.position = CGPoint(x: frame.midX, y: frame.minY + ball.frame.height / 2)

        let goUp = SKAction.move(by: CGVector(dx: 0, dy: 600), duration: 1)
        goUp.timingMode = .easeOut

        let goDown = SKAction.move(by: CGVector(dx: 0, dy: -600), duration: 1)
        goDown.timingMode = .easeIn

        let check = SKAction.customAction(withDuration: 0) { (node, elapsedTime) in
            self.ballTouchesBase()
        }

        let goUpAndDown = SKAction.sequence([goUp, goDown, check])
        let forever = SKAction.repeatForever(goUpAndDown)
        ball.run(forever)
        return ball
    }

    private func ballTouchesBase() {
        print("The ball touched the base")
    }
}

正如您现在所看到的,每当球是一个较低的y坐标时,就会调用方法ballTouchesBase。这是添加六边形颜色检查的正确位置。