繁体   English   中英

如何使用SpriteKit将精灵跳转到特定高度?

[英]How to make a sprite jump to a specific height with SpriteKit?

我正在尝试使用applyImpulse使sprite跳转到特定高度。 在下面的示例代码中,动态黑色圆圈跳转到与静态红色圆圈相同的高度,但它仅适用于kludge。

如果我的物理学是正确的,那么将射弹发射到高度Y所需的初始垂直动量由质量* sqrt(2 *重力* Y)给出。 然而,这个公式导致黑圈移动很少。

通过反复试验,我发现通过将脉冲矢量的垂直分量乘以12.3,我可以或多或少准确地使红色圆圈跳跃,如下面的代码所示。

这似乎是完全随意的,让我发疯。 我显然做错了什么。 这样做的正确方法是什么?

以下是我认为相关的代码:

let dy = mass * sqrt( 
    2 * -self.physicsWorld.gravity.dy 
    * (fixedCircle.position.y-jumpingCircle.position.y)) 
    * 12.3

jumpingCircle.physicsBody?.applyImpulse(CGVectorMake(0, CGFloat(dy)))

如果您希望复制和粘贴,这里是完整的GameScene.swift类...

import SpriteKit

class GameScene: SKScene {

var jumpingCircle = SKShapeNode()
var fixedCircle = SKShapeNode()

override func didMoveToView(view: SKView) {

    self.scaleMode = .AspectFit

    // Create an exterior physical boundary
    self.physicsBody = SKPhysicsBody(edgeLoopFromRect:self.frame)
    self.physicsWorld.gravity = CGVectorMake(0, -5);


    // Create the jumping circle
    jumpingCircle = SKShapeNode(circleOfRadius: 50)
    jumpingCircle.position = CGPoint(x: 100,y: 0)
    jumpingCircle.strokeColor = .blackColor()
    jumpingCircle.physicsBody = SKPhysicsBody(circleOfRadius: 50)
    jumpingCircle.physicsBody?.linearDamping = 0.0
    self.addChild(jumpingCircle)


    // Create the fixed circle
    fixedCircle = SKShapeNode(circleOfRadius: 50)
    fixedCircle.position = CGPoint(x: 100,y: 384)
    fixedCircle.strokeColor = .redColor()
    self.addChild(fixedCircle)

}

override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {

    // to reach certain height, initial y velocity should by sqrt(2 * gravity * Y)
    // momentum required to reach this velocity is mass * velocity
    // therefore, vertical impulse should be given by mass * sqrt(2 * gravity * Y)

    if let mass = jumpingCircle.physicsBody?.mass{
        // calculate vertical impulse

        // this formula "should work" but does not
        // let dy = mass * sqrt(2 * -self.physicsWorld.gravity.dy * (fixedCircle.position.y-jumpingCircle.position.y))

        // this formula "works", but has the arbitrary multiplier
        let dy = mass * sqrt(2 * -self.physicsWorld.gravity.dy * (fixedCircle.position.y-jumpingCircle.position.y)) * 12.3

        // apply the Impulse
        jumpingCircle.physicsBody?.applyImpulse(CGVectorMake(0, CGFloat(dy)))
     }
     }
 }

弄清楚了。

SpriteKit显然没有未记录的像素到“米”比率为150。

我发现这一点,当我意识到质量SpriteKit自动计算我的圈子不是 50 * pi * r ^ 2应该是。 我从质量向后工作来计算SpriteKit正在使用的半径,它是7500,恰好是50 * 150。

和12.3? 它恰好是(大约)150的平方根。

因此,要使这些物理模拟工作,您必须考虑这个比例。 我称之为“像素到单位”(PTU),因为尽管Apple坚持认为SpriteKit使用SI单位,但它与米无关。 但由于它没有文档,似乎有可能改变,所以我使用以下代码行开始模拟,以确定真正的PTU:

let ptu = 1.0 / sqrt(SKPhysicsBody(rectangleOfSize: CGSize(width:1,height:1)).mass)

这是一项昂贵的操作,因此只应调用一次。 我在设置初始场景时调用它。

我的冲动计算现在如下:

let dy = mass * sqrt(2 
    * -self.physicsWorld.gravity.dy 
    * (fixedCircle.position.y-jumpingCircle.position.y 
    * ptu))

现在,黑色圆圈跳跃到与红色圆圈完美对齐,我可以在晚上回去睡觉。

而不是applyImpulse使用速度。 速度将更加具体。 jumpingCircle.physicsBody?.velocity = CGVectorMake(jumpingCircle.physicsBody.velocity.dx, 300.0f); 代码未经测试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM