所以我制作了一个非常简单的iOS游戏,它有多个对象在屏幕上滚动并检查沿途的碰撞。目前要移动它们,我有一个NSTimer,每0.01秒左右触发一次,并将帧移动2个像素。然后它会检查玩家的相交帧位置,并采取相应的行动。
这非常有效,我在自己的设备上没有任何问题,但是我注意到,当屏幕上有超过20个对象在旧设备上同时移动时(例如例如iPad 3。
在对应用程序进行概要分析后,似乎有大约70%的CPU进入这一个线程。这是正常的吗?如果我将每个对象添加到单个固定视图上的CALayer并更新该层上的位置,而不是在屏幕上同时移动25-30个单独的UIImageViews,它会减少CPU上的负载吗?或者有更好的方法吗?
我认为在解决所有代码转换为图层之前我会遇到麻烦。有没有人有过编写这样的游戏的经验而没有任何旧设备上的延迟?
我想支持尽可能多的设备,但是较旧的设备似乎很难运行(我发现这很奇怪,因为与我制作的其他设备相比,游戏非常简单。)
部署目标:5.0
iPad设备iOS:7.0.6
iPhone 5设备iOS:7.0.6
XCode版本:5.0.2
这是在触发计时器时运行的代码。 CView
基本上是一个UIImageView,带有一些额外的int / bool属性。
for(CView* c in self.view.subviews)
{
if(![c isKindOfClass: [CView class]])
{
continue;
}
[c setFrame:[CRect rect:c.frame withNewY:c.frame.origin.y+2]];
if(fabsf(c.frame.origin.y + c.frame.size.height - (player.frame.origin.y+player.frame.size.height)) <= player.frame.size.height)
{
if([player collideWith:c.x])
[self gameOver];
}
else if((c.frame.origin.y + c.frame.size.height) > (player.frame.origin.y + player.frame.size.height) && c.passed == NO)
{
c.passed = YES;
score++;
}
if(c.frame.origin.y > [CRect height])
{
[self removeView:c];
}
}
if(score != score2)
[scoreLabel setText:[NSString stringWithFormat:@"%d",score]];
score2 = score;
reps++;
if(reps < 0)
return;
NSArray* formation = [formations objectAtIndex:(int)[Global randomFloatBetween:0 andLarge:11.99]];
float max = 0;
for(int i = 0; i < formation.count; i++)
{
if([[formation objectAtIndex:i] intValue] == -1)
continue;
if([[formation objectAtIndex:i] floatValue] > max)
max = [[formation objectAtIndex:i] floatValue];
float x = [CRect centerX:(player.laneWidth*5)+(player.lineWidth*4)] + ((i) * (player.xWidth+player.lineWidth)) + player.margin;
float y = -101 + ([[formation objectAtIndex:i] floatValue] * (-130));
CView* c = [[CView alloc] initWithFrame:CGRectMake(x, y, 49, 101)];
[c setX:i+1];
[c setImage:[images objectAtIndex:(int)[Global randomFloatBetween:0 andLarge:images.count-0.01]]];
[self.view insertSubview:c belowSubview:adBanner];
}
reps = (-101 * (max+1)) - 202;
reps /= 1.75;
这可能与我以这种方式创建CViews
有关,并且当它们离屏时只是取消它们吗?如果我使用固定数字并重新使用旧的CViews
(只是将它们放在屏幕的另一端并在完成交叉时重新运行它们)会提高性能吗?我不知道ARC收集垃圾的频率。
答案 0 :(得分:2)
您应该考虑使用现有的游戏引擎,例如cocos-2d,或者花些时间使用常见模式和最佳实践来优化自己的引擎。如果您决定使用现有的引擎,除了阅读他们的文档之外没什么好说的,如果您遇到问题就会询问具体问题。不要问有关使用什么引擎的问题。这种问题不适合Stack Overflow。
如果您继续使用自己的引擎,我仍然建议您学习cocos-2d和Sprite Kit的文档和编程指南。这将有助于您构建自己的引擎。例如,这是一个来自Sprite Kit Programming Guide的图片,解释了游戏循环。
如果您有兴趣使用Core Animation编写游戏引擎,那么我建议您阅读this series of blog posts by Matt Gallagher。它已经有几年了,但仍然应该是最重要的。
将游戏引擎结构化为这些步骤
然后,您可以开始测量不同步骤的性能和内存效率,并继续处理最重的部分,直到达到可接受的性能。
当他们离开屏幕时,也许值得重新使用视图,也许你的碰撞检测太昂贵而且应该进行优化,也许移动到图层是值得的。你必须先测量一下,知道在哪里花费你的时间和精力。
但是,我会告诉您,您应该删除NSTimer并使用单个CADisplayLink进行游戏循环,以使更新与显示保持同步。
作为旁注:
我不知道ARC收集垃圾的频率。
这句话让我很担心。它表明你还没有理解ARC是什么以及它是如何工作的。 ARC不是垃圾收集器。我建议你回过头来再看看Objective-C中的内存管理