我在iPhone上设置了一个非常简单的“游戏”。事物四处移动,旋转,你可以与它们互动,等等。在模拟器中,它运行良好,但在设备上它可以达到0.25 FPS左右,并且它很慢,没有时间识别触摸,显然。 / p>
这最初只是使用了一个带有Item
数组的UIView,每个数组都有一个Tick和Draw函数。在应用程序开始时,我启动了一个以60 FPS拍摄的计时器,它调用了Tick,在Tick结束时,它调用[self setNeedsDisplay];
它的工作速度非常慢,所以我将Item
类转换为CALayer
类的子类,移动图层而不是重新绘制项目。但是,我正在逐帧手动移动CALayer
,显然这并不好。它仍然太慢了。所以我告诉它移动到它的最终目的地并给它一个等于它到达那里的刻度数的长度。
这样做没问题,但是有些情况下,如果你与某些东西互动,它应该停止这种方式并改为做其他事情。所以我回过头来移动每一个勾号,而不仅仅是设置新的位置,我还将它包装在一个CATransaction中,并使交易的长度与刻度相同。
工作正常,但出现了新问题:如果我想动画一些东西,我仍然必须使用[self setNeedsDisplay]每个tick,调用drawInContext:
,这似乎是 major 我>减缓了问题。
难道不是像以前一样手动绘制所有内容的方法吗?我只是在进行CGContext *调用,它在模拟器中运行良好!如果我在J2ME或嵌入式C ++中实现类似的东西,它将工作正常。我错过了什么?我真的需要学习OpenGL来做任何有趣的手动动画吗?
答案 0 :(得分:2)
不确定CG动画层,但OpenGLES是iPhone对高性能图形的回答。在一天结束时,您将获得更好的表现。 openGLES可能很难处理,但是如果你从工作代码开始(参见崩溃应用程序的纹理和视图类),你应该能够抽象出你需要的东西。
老实说,我不太高兴不得不使用openGLES来绘制一些2D精灵,但我得到了大约50fps的完整物理引擎和脚本层,所以我觉得值得。
答案 1 :(得分:1)
如果您需要做的只是动画从A点移动到B点的动画,UIView和CALayer就能够处理这个问题。你真的,真的不想在iPhone上使用Core Graphics,UIViews或Core Animation以60 FPS手动改变精灵的位置。
对于使用CALayer的简单移动,您应该能够执行以下操作:
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:0.5f] forKey:kCATransactionAnimationDuration];
CGSize spriteSize = currentSprite.frame.size;
currentSprite.frame = CGRectMake(newPosition.x, newPosition.y, spriteSize.width, spriteSize.height);
[CATransaction commit];
currentSprite是你的CALayer,newPosition是整个线性移动的终点。这将使用恒定速度从当前位置平滑地动画到新位置。
使用Core Animation,您只需指定图层的最终位置,然后让它完成插入中间帧的工作。如果您通过在同一图层上执行另一个动画来中断此动画,它甚至会从移动到一个位置平滑过渡到另一个位置。可以使用CAKeyframeAnimations设计更复杂的动画。再次,给核心动画一个开始和结束状态,并让它优化其余部分。
使用UIViews,这是CALayers的轻量级包装器,我在设备上获得至少30 FPS,同时有数十个半透明层移动。
答案 2 :(得分:0)
不幸的是,这听起来有点重写,但是你看过Cocos2d引擎了吗?如果您要做的只是在屏幕上围绕一系列精灵制作动画,那么他们会为您提供围绕所有OpenGL调用的好的Objective-C包装器。
答案 3 :(得分:0)
我发现真正的问题是必须致电[self setNeedsDisplay]
。逐帧重绘是不好的结果。所以我在大多数情况下使用图像,我仍然可以通过将CALayer上的动作设置为null来逐帧设置位置。具体做法是:
NSMutableDictionary *customActions=[NSMutableDictionary dictionaryWithDictionary:[self actions]];
[customActions setObject:[NSNull null] forKey:@"position"];
[customActions setObject:[NSNull null] forKey:@"transform"];
[customActions setObject:[NSNull null] forKey:@"opacity"];
self.actions=customActions;
在那次通话之后,逐帧计算时一切都会快得多。