精灵套装 - 有时球从屏幕上消失了?

时间:2016-12-08 08:56:10

标签: swift sprite-kit

enter image description here

我是sprite kit的新手。我曾尝试用2名球员进行简单的球弹跳比赛,另一名球员慢慢跟踪球。但我发现了一个问题。当我将线移动到球(带边缘)时,球从屏幕上消失。另一次不是问题,球弹跳。有什么问题?

我有一个GameScene,sks和ViewController。我的精灵节点来自sks。如果有人解释这个案子。会更好。我已经附上了我在下面做的事情。

我的GameScene:

class GameScene: SKScene {

var ball = SKSpriteNode()
var enemy = SKSpriteNode()
var main = SKSpriteNode()

override func didMove(to view: SKView) {

    ball = self.childNode(withName: "ball") as! SKSpriteNode
    enemy = self.childNode(withName: "enemy") as! SKSpriteNode
    main = self.childNode(withName: "main") as! SKSpriteNode

    ball.physicsBody?.applyImpulse(CGVector(dx: -20, dy: -20))
    ball.physicsBody?.linearDamping = 0
    ball.physicsBody?.angularDamping = 0

    let border = SKPhysicsBody(edgeLoopFrom: self.frame)
    border.friction = 0
    border.restitution = 1

    self.physicsBody = border

}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    for touch in touches {

        let location = touch.location(in: self)
        main.run(SKAction.moveTo(x: location.x, duration: 0.2))
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

    for touch in touches {

        let location = touch.location(in: self)
        main.run(SKAction.moveTo(x: location.x, duration: 0.2))
    }

}

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered

    enemy.run(SKAction.moveTo(x: ball.position.x, duration: 0.5))
}

查看控制器:

class GameViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    if let view = self.view as! SKView? {
        // Load the SKScene from 'GameScene.sks'
        if let scene = SKScene(fileNamed: "GameScene") {
            // Set the scale mode to scale to fit the window
            scene.scaleMode = .aspectFill

            // Present the scene
            view.presentScene(scene)
        }

        view.ignoresSiblingOrder = true


    }
}

override var prefersStatusBarHidden: Bool {
    return true
}

打击垫设置:

pad

球设置:

ball

  

一些更新

我在更新功能中尝试了一些消息,然后遇到同样的情况,球从设备的左侧出来(使用iPhone 6S)

enter image description here

enter image description here

  

2016-12-08 14:27:54.436485 Pong [14261:3102941]致命错误:球出界:文件

enter image description here

3 个答案:

答案 0 :(得分:2)

你正在和敌人一起把球撞到墙上。这意味着力最终足以产生足够的球移动速度/力来克服物理系统,因此它会穿过墙壁。如果你让敌人在将球撞向墙壁之前停下来,你应该没事。

由于这行代码而发生这种“引脚”:

enemy.run(SKAction.moveTo(x: ball.position.x, duration: 0.5))

这使得敌人追逐球,这对于一场球赛来说是一个好主意,但是因为它被移动的方式是错误的。使用动作意味着敌人有无限的力量施加在它上面,并且瞄准球的中间。

所以当球到达墙壁时,它会被一个拥有无限静力的物理物体挡住,然后这个敌人出现并从另一侧施加无限的力......然后球在敌人的范围内弹出或者在墙的另一边,因为它被无限的力量压碎了。

所以要么你需要非常好地照顾你如何使用行动来控制敌人,或者使用力来控制敌人,因为这些不会是无限的,物理系统将能够击退敌人

答案 1 :(得分:1)

重现问题有多容易?在update()中,打印球的位置以查看它“消失”时的位置。 (这将产生大量输出,因此请注意)。

根据您发布的内容,看起来球似乎不会与边界碰撞,这意味着球不会对边框做出反应(即反弹)并且边框本身不会移动(因为它是边缘)基于物理的身体)。这一点,加上高速球(来自一次重击)可能会让你用'主'精灵击中球很可能已经穿过边界 - 使用preciseCollisionDetection=true可以解决这个问题但是给出首先是边界类别,然后将其添加到球的collisionBitMask

答案 2 :(得分:1)

这是史蒂夫所说的(在你的.update()

中的一个例子
if ball.position.x > frame.maxX { fatalError(" ball out of right bounds") }
if ball.position.x < frame.minX { fatalError(" ball out of left bounds") }
if ball.position.y > frame.maxY { fatalError(" ball out of top bounds") }
if ball.position.y < frame.minY { fatalError(" ball out of bottom bounds) }

您也可以将调试窗口垃圾邮件:

print(ball.position)

这将帮助您了解发生了什么 - 如果您的球飞过边界,或者它在某处被摧毁,或者其他可能的错误。

作为一种解决方法(目前)我只会替换上面的&#34; fatalError&#34;用&#34; ball.position = CGPoint(x: 0, y: 0)&#34;或者其他一些职位来重置&#34;球在它迷路的情况下。

您甚至可以将其存储在变量中的最后位置,然后将其恢复为上述if语句触发时的位置。

var lastBallLocation = CGPoint(x: 0, y: 0) // Just to initialize
override func update( prams ) {
  if ball.position.x > frame.maxX { ball.position = lastBallLocation }
  // .. copy the other three cases
  lastBallLocation = ball.position // update only on successful position

或者,您可以尝试使墙壁更厚(使用形状节点或spritenode并将它们放置在框架的外部,例如房屋的墙壁,并且您在屏幕上的视图是&#34;房间&#34 ;)

make sure to give SKSpriteNode a physics body so will bounce off the red blocks

每个墙都有一个弹跳的物理体:

enter image description here