SKSpriteKit在碰撞后保持恒定的速度

时间:2016-08-24 22:23:44

标签: ios iphone swift xcode physics

我正在尝试制作我的第一个iOS应用,目前遇到了一个问题。

在我的游戏中,当球反弹时,我希望它以相同的速度反弹回相同的高度。目前它做得很好。然而,当我旋转六边形并且它撞到一个角度时,它最终会失去速度而不会弹到相同的高度。

所以我的问题是:如何在碰撞时强迫球保持相同的速度?

以下是我的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
}

以下是GIF以视觉形式解释问题: enter image description here

2 个答案:

答案 0 :(得分:1)

问题在于,如果球以一定角度碰撞,则其总速度在新速度矢量的垂直和水平分量之间分配。因为你限制了球的水平位置的运动,水平速度会丢失,并且球不会反弹得高。

一种可能的解决方案是覆盖场景中的didSimulatePhysics,并检查球的速度是否不足以使其达到所需的高度。如果不是,那么就增加它的速度。

let neededVelocity = sqrt(2 * physicsWorld.gravity.dy * (intendedHeight - ball.posiiton.y))
if ball.physicsBody.velocity.dy < neededVelocity && ball.physicsBody.velocity.dy > 0 {
    ball.physicsBody.velocity = CGVector(dx: 0, dy: neededVelocity)
}

答案 1 :(得分:1)

我不确定你是否还在寻找答案,但是......

如果你总是希望球在同一垂直方向上反弹,那你为什么不:

  • 创建一个单独的水平SKShapeNode,其中六边形的底线为。
  • 将填充和描边颜色设置为“清除”。
  • 为它设置物理体 - 这样球就会反弹。
  • 从彩色六边形中移除物理体。

这将避免任何'角度反弹'问题。

如果您想检测与相关十六进制形状的接触,您可以跟踪底部的内容,或者:

  • 将新物理盒向下移动1个点。
  • 在您的六边形形状上添加接触面罩(不是“碰撞”),这样您就可以获得接触但没有物理碰撞。