2017-06-19 58 views
1

我有一些非常简单的Swift代码,它将SKSpriteNode放置在屏幕上位置x:214,y:200处。在更新方法中,我打印出SKSpriteNode的当前位置。如果我省略了所有SKPhysicsBody代码,那么我的SKSpriteNode的位置在调试窗口中显示为(214.0,200.0),正如我所期望的那样。但是,如果我使用SKPhysicsBody代码运行程序,则第一次打印返回正确(214.0,200.0),但后续调用返回(214.000015258789,200.0)。SKSpriteNode在指定SKPhysicsBody时显示非整数位置

在我看来,像物理世界中的某些东西正在影响(尽管以非常小的方式)SKSpriteNode的位置。我无法理解我的生活是什么,可能是。我的代码完全如下所示,仅此而已。我想我已经禁用了可能对这个职位有任何影响的一切。我只是希望我可能错过了一些愚蠢的东西。

这个问题可能看起来微不足道,因为这些值只是微小的关闭,但是当我尝试在屏幕上平滑地移动精灵(在每次更新时增加它的x位置+1),它偶尔会错过整个位置,从289.0到289.99,然后是291.0。

任何帮助将不胜感激。这对我来说就像是一个bug,但是因为我对SpriteKit的物理方面相当陌生,所以我想确定一下。

import SpriteKit 

class GameScene: SKScene { 

private var playerSprite : SKSpriteNode! 

override func didMoveToView(view: SKView) { 
    self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)//borderBody 
    self.physicsWorld.gravity = CGVector(dx: 0, dy: 0) 

    playerSprite = SKSpriteNode(color: UIColor.yellowColor(), size: CGSize(width: 100, height: 100)) 
    playerSprite.position = CGPoint(x: 214, y: 200) 

    playerSprite.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 100, height: 100)) 

    if let playerSpritePhysicsObject = playerSprite.physicsBody { 
     playerSpritePhysicsObject.usesPreciseCollisionDetection = true 
     playerSpritePhysicsObject.affectedByGravity = false 
     playerSpritePhysicsObject.allowsRotation = false 
     playerSpritePhysicsObject.dynamic = false 
     playerSpritePhysicsObject.angularVelocity = 0.0 
     playerSpritePhysicsObject.friction = 0.0 
     playerSpritePhysicsObject.linearDamping = 0.0 
     playerSpritePhysicsObject.angularDamping = 0.0 
     playerSpritePhysicsObject.velocity = CGVectorMake(0, 0) 
     playerSpritePhysicsObject.restitution = 0.0 
    } 
    self.addChild(playerSprite) 
} 

override func update(currentTime: NSTimeInterval) { 
    print("playerSprite Position = \(playerSprite.position)") 
} 
} 

下面是调试窗口输出:

playerSprite Position = (214.0, 200.0) 
2017-06-19 20:39:47.682 PhysicsTest[9193:2340365] <SKMetalLayer: 0x14fe6e760>: calling -display has no effect. 
playerSprite Position = (214.000015258789, 200.0) 
playerSprite Position = (214.000030517578, 200.0) 
playerSprite Position = (214.000030517578, 200.0) 
playerSprite Position = (214.000030517578, 200.0) 
playerSprite Position = (214.000030517578, 200.0) 
+0

后搜索的日子里,我终于发现有人有类似的问题。不幸的是,他们似乎也没有找到解决办法。 https://stackoverflow.com/questions/34236737/adding-physics-body-to-sprite-in-spritekit-alters-its-position-fractionally – PikXells

+0

我也发现这个https://forums.developer.apple.com/thread/27057虽然与我的问题不完全一样,因为我的SKSpriteNode不在SKNode对象内。似乎表明这可能是2年前的一个持续性错误。 – PikXells

+0

我已经为我的代码添加了一项解决方案,确实看起来可以解决问题。这很讨厌但很有效。由于我们可以假定问题出在物理引擎和它的SKSpriteNode的位置,你可以通过在didFinishUpdate()函数中再次设置它的位置来强制它到达正确的位置。 – PikXells

回答

0

一段时间苦苦思索这个问题后,我想我可能已经发现身边工作。这是讨厌的,但伎俩。只需在didSimulatePhysics()函数完成后发生的didFinishUpdate()函数中重置SKSpriteNode的位置即可。

override func didFinishUpdate() { 
    playerSprite.position.x = 214 
} 

经过进一步测试,我发现这不适用于iOS 7.1。为了在老型号设备上工作,你必须把在didSimulatePhysics代码()函数来代替:

override func didSimulatePhysics() { 
    playerSprite.position.x = 214 
}