skSpriteKit提高了性能

时间:2014-09-18 10:26:34

标签: ios iphone performance sprite-kit

我正在写一个自上而下的赛车游戏。这就像“开放世界”游戏,没有圈数,但自由漫游。由于很多原因,我没有使用平铺地图,所以我有一个2048x2048的大背景图像。移动此图像不是导致性能下降的原因。在这张图片上,我插入了一些物理对象来创建墙壁。现在我已经插入了其他汽车来模拟交通,每辆汽车都在一条cgpath上移动,这是一个永远重复的车道。每辆车都响应红绿灯,并通过隐形活动区域和循环cgrectIntersect检查系统停止。这辆车没有物理机身,因为每辆车增加了物理机身,只有3或4辆车后游戏性能不佳......所以我写了一种方法来处理接触,交通信号灯,停车等等......它工作正常但在iphone 4上我只能管理15辆汽车才能获得不良性能。这个性能问题的第一个原因是我写的方法。我正在尝试优化,在我的方法中,我有一些递归循环(例如:对于每次更新,我检查每辆车的内部有另一个循环来检查其他汽车之间的联系人......)

for (int i=0; i<[ArrayCars count]; i++) {   

  CGRect Frame=[[ArrayCars objectAtIndex:i] frame];

  for (int z=0; z<[ArrayCars count]; z++) {

        CGRect Frame1=[[ArrayCars objectAtIndex:z] frame];
        SKSpriteNode *Car=[ArrayCars objectAtIndex:z];


        if (CGRectEqualToRect(Frame,Frame1)==NO && [Car speed]==0) {

            if ([self CheckIntersection:Car.frame :Frame]) {

              //set some flags that identifies the contact


            }



        }



    }
}

我如何对这样的递归进行优化?我的方法是通过update方法启动的,但是我已经尝试在didEvaluateActions中移动它而没有明显的收益。

1 个答案:

答案 0 :(得分:1)

有许多&#34;优化&#34;你可以使用快速枚举开始:

for (SKSpriteNode* car1 in ArrayCars) 
{   
  CGRect Frame1 = car1.frame;

  for (SKSpriteNode* car2 in ArrayCars) 
  {
        CGRect Frame2 = car2.frame;

        if (CGRectEqualToRect(Frame1, Frame2) == NO && [car2 speed] == 0)
        {
            if ([self CheckIntersection:Frame2 :Frame1]) 
            {
              //set some flags that identifies the contact
            }
        }
    }
}

我打赌这会给你一些改进。

接下来的优化步骤是考虑到每个car2都不需要检查car1。基本上,如果你检查car1和car2是否相撞,ca​​r2与car1的反向检查是多余的。

此变体检查每辆车1对所有car2。它会自动跳过支票,而不是以前的车,因为它们已经过检查。因此,每次外循环完成迭代时,内循环的迭代次数越来越少。数学不太好,但我相信这会减少总迭代次数。遗憾的是,您无法对内循环使用快速枚举。

NSUInteger numCars = ArrayCars.count;
int otherCarsStartIndex = 0;

for (SKSpriteNode* car1 in ArrayCars) 
{   
  CGRect Frame1 = car1.frame;
  otherCarsStartIndex++;

  for (int i = otherCarsStartIndex; i < numCars; i++) 
  {
      SKSpriteNode* car2 = [ArrayCars objectAtIndex:i];

      // previous code omitted...
  }
}

另一个优化是内联CheckIntersection代码或将其重写为C函数以避免ObjC消息传递开销。

此外,如果您的大多数汽车碰巧有速度== 0,如果您首先枚举ArrayCars以构建仅包含速度非零的汽车的新阵列,那么它可能会提高性能。新阵列可能需要大约原始车辆数量的一半或更少,否则填充新阵列的开销可能太高而无法获得好处。

最后,您可以使用C样式数组来存储您的汽车,从而挤出更多性能,但这需要手动内存管理,并且没有像NSArray那样的缓冲区溢出/下溢保护。

PS:请记住,与其继承者iPhone 4S相比,iPhone 4非常慢。 iPhone 4基本上是一款iPhone 3GS,其33%的速度提升,因其必须为其Retina显示屏绘制四倍的像素而过度征税。