1

我在 iPhone 上设置了一个非常简单的“游戏”。物体四处移动,旋转,您可以与它们进行交互等。在模拟器中,它运行良好,但在设备上它达到 0.25 FPS 左右,而且速度非常慢,显然没有时间识别触摸。

这最初只是使用带有Items 数组的 UIView,每个数组都有一个 Tick 和一个 Draw 函数。在应用程序开始时,我启动了一个以 60 FPS 拍摄的 Timer,它调用 Tick,在 Tick 结束时,它调用[self setNeedsDisplay];

它工作得非常慢,所以我把这个Item类变成了这个类的一个子CALayer类,移动图层而不是重绘项目。但是,我是CALayer逐帧手动移动的,这显然不好。还是太慢了。所以我告诉它移动到它的最终目的地,并给它一个与到达那里所需的滴答数相等的长度。

这没问题,但是在某些情况下,如果您与某物交互,它应该停止以这种方式移动并转而做其他事情。所以我回到移动每个刻度,而不是仅仅设置新位置,我还将它包装在一个 CATransaction 中,并赋予交易与刻度相同的长度。

工作正常,但出现了新问题:如果我想为某些东西制作动画,我仍然必须在每个滴答声中使用 [self setNeedsDisplay] ,它调用drawInContext:,这似乎是一个主要的减速问题。

难道没有一种方法可以像我以前那样手动绘制所有内容吗?我只是在进行 CGContext* 调用,它在模拟器中运行良好!如果我在 J2ME 或嵌入式 C++ 中实现类似的东西,它会工作得很好。我错过了什么?我真的需要学习 OpenGL 来制作任何有趣的手动动画吗?

4

4 回答 4

2

不确定 CG 动画层,但 OpenGLES 是 iPhone 对高性能图形的回答。在一天结束时,您将获得更好的性能。使用 openGLES 可能会很痛苦,但如果您从工作代码开始(请参阅崩溃应用程序的纹理和视图类),您应该能够从中/围绕它抽象出足够多的东西。

老实说,我不太高兴不得不使用 openGLES 来绘制一些 2D 精灵,但我得到了大约 50fps 的完整物理引擎和脚本层,所以我想这是值得的。

于 2009-01-28T16:07:52.710 回答
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 设计更复杂的动画。同样,只需给 Core Animation 开始和结束状态,让它优化其余部分。

UIViews 是 CALayers 的轻量级包装器,我在设备上获得至少 30 FPS 的速度,同时有几十个半透明层同时移动。

于 2009-01-29T18:53:17.330 回答
0

不幸的是,这听起来有点重写,但是你看过 Cocos2d 引擎吗?如果您要做的只是为屏幕周围的一系列 sprite 设置动画,那么它们会让您在所有 OpenGL 调用周围使用漂亮的 Objective-C 包装器。

http://code.google.com/p/cocos2d-iphone/

于 2009-01-28T17:54:16.520 回答
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;

在那次调用之后,逐帧计算时一切都会快得多。

于 2009-01-30T17:32:51.237 回答