【问题标题】:Getting an exact node count and performance issues in Swift/SpriteKit在 Swift/SpriteKit 中获取准确的节点数和性能问题
【发布时间】:2016-09-01 19:24:39
【问题描述】:

我正在使用 SpriteKit 制作我的第一款游戏,其中敌人从一侧进入屏幕并从另一侧穿过屏幕。我注意到,在游戏后期,当渲染不同类型的敌人时,FPS 下降并且 CPU 使用率接近 100%(~95-99%)。我想知道是否有办法在场景中获取准确的节点数(不仅仅是在屏幕上呈现的节点数),以判断我是否没有正确删除它们。我已经有一个更新的全局节点计数器,它似乎工作正常——总节点数通常是一致的。还有其他我可以做的事情来尝试调试吗?谢谢!

【问题讨论】:

  • 写一个递归函数,从场景开始,计算孩子。还要覆盖 deinit,并在那里添加一个打印语句。这会告诉你节点是否正在死亡。
  • @Knight0fDragon 你认为删除这些节点可能失败会导致如此高的 CPU 使用率吗?至于递归函数,你的意思是这样的吗? enumerateChildNodesWithName("//.") { (node, _) -> Void in print("Node: \(node.name)") }
  • 是的,不删除节点是个问题

标签: swift sprite-kit frame-rate


【解决方案1】:

您也可以创建SKNode的扩展来计算子树中从当前节点开始的所有节点。

extension SKNode {
    func subtreeCount() -> Int {
        return children.reduce(1) { $0 + $1.subtreeCount() }
    }
}

现在在你的场景中简单地写

let totalNodes = subtreeCount()

【讨论】:

  • @Knight0fDragon:谢谢,这与您用函数式编程风格编写的答案的逻辑基本相同。
  • 我喜欢这种做法,非常优雅。
【解决方案2】:

类似这样的:

func childrenCount(node : SKNode) -> Int
{
    var count = 0
    for child in node.children
    {
        count += childrenCount(child)
    }
    count += node.children.count
    return count
}

print("Nodes: \(childrenCount(scene) + 1)")  //+ 1 to count scene

【讨论】:

  • self.children.count,其中 self 是一个场景,将返回节点树中所有节点的数量(如果我没记错的话)。如果这不起作用(并且它只返回直接子级),有一种方法可以使用 enumerateChildNodeWithName 方法和特定的搜索字符串来返回节点树中所有节点的数量。因此,不需要手动执行此操作;)
  • @Whirlwind enumaerateChildNodeWithName 会给你所有的节点,但是你怎么计算它,你必须遍历整个列表并增加我猜
  • @Whirlwind self.children 是一个 [SKNode] 所以 count 只会提供直接的孩子(我一直使用它,所以我能够验证)我想知道 //* 是否足够聪明,可以忽略字符串搜索并抓取所有节点,找出哪种方法更快会很有趣
  • @knight0fDragon 我不认为在计算节点数后导致高 CPU 使用率的节点堆积。如果您认为这提供了任何额外的见解,我发布了时间分析器的更新。
  • 这不是解决你的问题,而是回答你的问题
【解决方案3】:

调试游戏的性能问题需要一些策略才能确定您的目标。只是出于好奇,您的陈述是基于模拟器还是基于设备?如果是模拟器,请注意,即使您的节点数不是特别高,您实际上也可以获得一些糟糕的 FPS 和 CPU 使用率。因此,在查看性能时,您真的应该在设备上。

你已经有了一些关于获取节点数的答案,所以我不打算回答这部分。根据您管理节点的方式,您可能还需要考虑隐藏节点。那些有答案的当前方法处理所有节点;可见与否(我知道 q 的一部分与计算所有节点有关)。如果您使用隐藏节点,那么您应该至少有 2 个与节点相关的指标:可见和总计。另一个可能有用的细分是节点“类型”以及节点使用的纹理。

进一步研究性能问题,您可能希望专注于运行仪器。特别是 Time Profiler 和 OpenGL ES 分析。您还可以在 Xcode 中使用 GPU 报告。运行 Time Profiler 时,当您认为 CPU 使用率上升时,我会让游戏运行几秒钟。这是为了允许更多的样本点更容易地磨练违规区域。

攻击帧率很大程度上取决于您构建和运行游戏的方式。例如,使用单个纹理与图集、纹理大小等。这些类型的设计决策确实会影响性能。

请记住,解决这些性能问题没有灵丹妙药。每个游戏的实现方式都不同,因此适合您的解决方案/方法可能不适合其他游戏。

如果您仍然卡住,构建一些机制来禁用项目或使用它们的更简化版本总是有帮助的。这样您就可以关闭项目并查看对帧速率的净影响。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多