2009-01-28 40 views
1

我在iPhone上设置了一个非常简单的“游戏”。事物四处移动,旋转,可以与它们交互等等。在模拟器中,它运行良好,但在设备上它的速度大约为0.25 FPS,而且速度很慢,显然没有时间识别触摸。如何在iPhone上手动设置动画效果?

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

它的工作速度非常慢,所以我将Item类转换为CALayer类的子类,移动图层而不是重绘项目。但是,我正在手动,逐帧地移动CALayer,而这显然不是好的。它仍然太慢。所以我告诉它移动到它的最终目的地,并给它一个等于它到达那里所需的滴答数量的长度。

工作正常,但有些情况下,如果您与某些东西交互,应该停止移动,并改为执行其他操作。所以我回到移动每个订单,而不是设置新的头寸,而是将其包装在CATransaction中,并为交易赋予与tick相同的长度。

工程确定,但新的问题出现了:如果我想动画的东西,我仍然要使用[自setNeedsDisplay]每一个刻度,它调用drawInContext:,这似乎是一个主要放缓的问题。

是不是只有一种方法来手动绘制像我之前做的一切?我只是在进行CGContext *调用,并且它在模拟器中工作正常!如果我在J2ME或嵌入式C++中实现类似的东西,它会工作的很好。我错过了什么?我真的需要学习OpenGL来做任何有趣的手动动画吗?

回答

0

我发现真正的问题是需要拨打[self setNeedsDisplay]。在逐帧的基础上重新绘制是不好的mojo。所以我大部分都是使用图像,而且我仍然可以通过将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; 

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

2

不确定CG动画层,但OpenGLES是iPhone对高性能图形的答案。在这一天结束时,你将获得更好的表现。 openGLES可能是一个痛苦的工作,但如果你从工作代码开始(请参阅应用程序的纹理和视图类的crashlanding),你应该能够足够的抽象出你需要的东西。

诚实地说,我不太喜欢使用openGLES来画一些2D精灵,但是我得到了一个大约50fps的完整物理引擎和脚本层,所以我猜这是值得的。

0

不幸的是,这听起来像是有点重写,但你看过Cocos2d引擎吗?如果你所要做的只是在屏幕上制作一系列精灵动画,那么你可以在所有的OpenGL调用中使用很好的Objective-C包装。

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

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,同时有数十个半透明层一次移动。

相关问题