【问题标题】:Sprite Kit physicsBody.resting behaviorSprite Kit 的物理身体休息行为
【发布时间】:2014-08-24 11:48:16
【问题描述】:

我正在使用 Swift 和 Sprite Kit 在 XCode Beta 6 上开发游戏。 为了检测是否所有节点都在休眠,我检查了它们的物理body.resting 属性。 在更新方法中,我打印出结果。

import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {

    var hero:SKSpriteNode!

    override func didMoveToView(view: SKView) {
        self.physicsWorld.gravity = CGVectorMake(0, 0)
        self.physicsWorld.contactDelegate = self
        self.physicsBody = SKPhysicsBody(edgeLoopFromRect:self.frame)


        hero = SKSpriteNode(imageNamed: "Spaceship")
        hero.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame))
        hero.zPosition = 10.0
        hero.physicsBody = SKPhysicsBody(circleOfRadius: hero.size.width/2)
        hero.physicsBody.allowsRotation = false
        hero.physicsBody.linearDamping = 0.5
        self.addChild(hero)
    }

    override func update(currentTime: CFTimeInterval) {
        if hero.physicsBody.resting {
            println("resting")
        } else {
            println("moving")
        }
    }
}

令我惊讶的是,结果是:

移动 休息 移动 (n次相同) 移动 休息

那么为什么英雄在移动,虽然我什么都没做。节点移动 N 次并休息(休息),然后继续移动。

谁能解释这种行为?这是一个错误还是我错过了什么?提前致谢。

【问题讨论】:

    标签: swift sprite-kit game-physics


    【解决方案1】:

    如果您检查一个物理物体的速度,您会发现它确实在移动,但速度是无法感知的。这就是未设置 resting 属性的原因。检查 SKPhysicsBody 是否处于静止状态的一种更可靠的方法是测试其线速度和角速度是否接近于零。以下是如何做到这一点的示例:

    func speed(velocity:CGVector) -> Float {
        let dx = Float(velocity.dx);
        let dy = Float(velocity.dy);
        return sqrtf(dx*dx+dy*dy)
    }
    
    func angularSpeed(velocity:CGFloat) -> Float {
        return abs(Float(velocity))
    }
    
    // This is a more reliable test for a physicsBody at "rest"
    func nearlyAtRest(node:SKNode) -> Bool {
        return (self.speed(node.physicsBody.velocity)<self.verySmallValue
            && self.angularSpeed(node.physicsBody.angularVelocity) < self.verySmallValue)
    }
    
    override func update(_ currentTime: TimeInterval) {
        /* Enumerate over child nodes with names starting with "circle" */
        enumerateChildNodesWithName("circle*") {
            node, stop in
            if (node.physicsBody.resting) {
                println("\(node.name) is resting")
            }
            if (self.nearlyAtRest(node)) {
                println("\(node.name) is nearly resting")
            }
        }
    }
    

    【讨论】:

    • 感谢您的重播。你的方法看起来很棒。我正在开发一款需要联网的回合制游戏。这种方式也可靠吗?因为我必须确保球的位置在每个玩家的设备中显示相同。
    • 是的,它适用于通过网络玩的游戏。
    • 我认为 sqrtf(dxdx+dy+dy) 应该是 sqrtf(dxdx+dy*dy)
    • 只是一个小评论 - 调用sqrtf 是不必要的,因为您可以将结果与verySmallValue 的平方进行比较(可以预先计算)。
    • 伙计们:在这种情况下,什么是合理的verySmallValue?由于我对速度和角速度的检查显示 0.0
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多