【问题标题】:FPS drops in SpriteKitSpriteKit 中的 FPS 下降
【发布时间】:2016-12-27 04:18:44
【问题描述】:

我正在使用 Swift 和 SpriteKit 开发一个简单的游戏,我注意到 FPS 从 60 下降到 58-59(并返回)。发生丢包时有明显的延迟——看起来丢了 1 或 2 帧。

CPU 负载约为 20-25% 且变化不大,内存使用量永久约为 8 MB。

截图:

屏幕上有6个对象:标签、红色对象(Sprite)、2x绿色对象(Sprite)、一个盒子(Sprite)和“ground”(矩形节点)。

除标签外的所有对象都有物理实体(以白色边框显示)。

绿色和白色的对象是动态创建的,从右到左移动并在离屏时销毁:

func scheduleAddingLiquid() {
let wait = SKAction.waitForDuration(NSTimeInterval(getRandomNumber(1, end: 3)))
        let block = SKAction.runBlock({
            [unowned self] in

            let liquidNode = LiquidNode(texture: self.liquidTexture, sceneFrame: self.frame)
            self.addChild(liquidNode)
            liquidNode.move()

            self.scheduleAddingLiquid()
        })

        let sequence = SKAction.sequence([wait, block])
        runAction(sequence)

和:

func move() {
        let moveAction = SKAction.moveToX(-frame.width, duration: NSTimeInterval(3))
        let removeBlock = SKAction.runBlock({
            [unowned self] in

            self.removeFromParent()
            })

        runAction(SKAction.sequence([moveAction, removeBlock]))
    }

红色物体在屏幕触摸时“跳跃”:

if touches.count > 0 && isHeroOnGround && heroNode != nil {
            isHeroOnGround = false
            heroNode.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
            heroNode.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 400))
        }

延迟发生在“跳跃”后的随机时间间隔内(跳跃后大约 0.5 到 1.5 秒)。

延迟不是在发生碰撞时发生,而是在红色物体“在空中”时发生。而且不是每次跳跃都会发生。 FPS 下降时 CPU 负载不会增加。

在 iOS 9.3、iPad mini 2 上测试。

更新 1. 在 iOS 9.3 iPhone 6 上测试 — FPS 前几秒约为 50-55,然后一直保持在 60,没有延迟。所以,它只在 iPad mini 2 上滞后(我只有这两个设备,无法在其他设备上测试)。

UPD 2. 我已经注释掉了所有的对象创建代码,除了红色的数字。 “跳跃”时仍然滞后。所以,现在我确定它与 applyImpulse 方法有关。

UPD 3. 这真的很奇怪:我已经从 touchesBegan 方法中删除了所有代码,但它仍然滞后于触摸!该方法是完全空的。我不知道为什么,但是如果我点击几次,FPS 就会下降...

如何调试这个?

【问题讨论】:

  • 我怀疑你的问题在于你如何混合skactiona和物理引擎。我没有看过你的代码,我注意到你正在应用冲动 + 使用 move to。两个人在一起不好相处。所以检查这两个是否没有干扰......这将是一个开始。
  • 更准确地说,如果您已经使用物理引擎移动了这些对象,SKActions 不应该用于移动这些对象。如果您只对联系人感兴趣,那么可以将动作与物理引擎一起使用。
  • 你的眼睛不会注意到 1 到 2 FPS 的下降,所以你所说的滞后,可能不是滞后,可能是主线程上的暂停,或者可能是不希望的由于错误的编程影响。有关实际情况的更多信息可能对您的情况有所帮助,或者您可能想将其发送至codereview.stackexchange.com,让人们看到您的代码哪里出了问题。
  • @Whirlwind 我没有对受冲动影响的对象应用任何 SKAction。 SKAction 仅用于非动态对象。
  • 你有没有被移除的手势在运行?

标签: ios swift sprite-kit


【解决方案1】:

只有在 mini 上出现问题让我觉得你的 mini(或 mini 上的特定包装)有问题。尝试创建一个新项目,将文件复制过来,然后再次运行。另外,您说的是 9.3,但有 9.3.1、9.3.2 等。这两种设备可能有不同的版本。

因此,首先,请确保您的 iphone 和 iPad 运行相同版本的 iOS。可能存在错误,或者他们修补了错误(从而导致一个工作而不是另一个工作)。

另外,尝试在不同的模拟器上运行它......如果它在模拟器上完美运行,那么我更怀疑迷你(在它的当前配置中)。

这样,您还可以查看(可能)问题是否与方向有关(iphone 的宽屏 vs 4:3 或 iPad 的任何内容)。

有时,我的项目文件(即使没有插件)发生了“非常奇怪”的事情,并且只是创建了一个新项目,将所有文件复制到修复它。如果当你点击一个空的“touchesBegan”时它会滞后......让我觉得Xcode/你的迷你在手边有一些错误 - 因为它只发生在那个设备上(到目前为止我们知道)......

需要考虑的其他事项,

  1. 您使用的是哪个版本的 Xcode?尝试最新的测试版/返回 7.3。有什么不同吗?

  2. 您是否有另一台计算机可以尝试构建项目?

  3. 如果换出 [unowned self] 或将其留在里面没有解决任何问题,那么我的建议是使用 print 语句加载您的代码,看看发生了什么。

    李>
  4. 如果您使用场景编辑器制作精灵节点,请将它们全部删除并重新制作,或者尝试以编程方式制作它们。这修复了我的一些项目中的随机错误(似乎没有原因)。

我们需要更多代码/信息,但以上内容有望解决您的问题。

【讨论】:

  • 感谢您的回复!我只有 2 台设备,iPad mini 2 和 iPhone 6,现在都有相同的版本(9.3.5)。我试过在模拟器上运行游戏,在 5s/6 上没问题,但在 6+/6s+ 上滞后(我认为这是因为屏幕尺寸的原因)。 1. Xcode是最新的稳定版本,我会试试beta。 2. 我只有一个 MBP(最新稳定的 OS X)。 3. 已经尝试过了,没有任何改变。 4. 不,我没有使用它。最奇怪的是它只在触摸时滞后,即使没有处理触摸的代码。
  • @RankoR 很有趣。它不会滞后于硬件手机,但会滞后于虚拟手机。你的 Macbook 是 core i 还是 core2duo?我肯定会尝试新项目导入,beta Xcode。如果这不起作用,您应该将项目放在 GH 上,以便我们看看。我有一个 4.5ghz 四核 hackintosh 和 r295x2 .. xD 如果它滞后,它必须是代码。我也有 ipad 3、air 和普通的 iphone 5....
  • 另外,我将开始制作滞后/不滞后的不同配置的电子表格。它可能有用,也可能没有用,但如果未来的项目开始出现类似的错误,则可能需要考虑。如果 xcode 或 iOS 中存在实际错误,该数据也将帮助 Apple 修复它。
  • 它是带有 i7 的 MBP Retina 2013 15"。稍后我将在 XCode beta 中尝试。我还将尝试重现新项目的滞后并将放入 GitHub(我不能由于保密协议,把当前的放在那里)。
【解决方案2】:

好吧,我想这有点晚了,但是当我在我的场景中添加一些 SKShapeNode 时,我的性能下降了。我没有滞后 200+ 普通 SKSpriteNode 并且当有 80 个节点,其中只有大约 30 个 SKShapeNode 时,一切都开始冻结。当然没有额外的功能,只有路径、描边/填充颜色和线宽

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-08
    • 1970-01-01
    相关资源
    最近更新 更多