iPhone动画效率解决方案,分层问题

时间:2009-12-01 16:19:02

标签: iphone objective-c performance opengl-es core-animation

我正在写一个相当基本的应用程序。它使用最小的触摸输入,大多数只是播放奇特的动画。没有太多的动画,但它目前的方式似乎超级低效,并使用了太多的内存。

视图分为两部分,底部1/5只是一个不会改变的图像。其余部分是动画播放的地方。目前,它通过将32个图像加载到一个数组然后播放它们(8fps)来完成。它通过每个动画总共执行4次。图片并不大,但它们仍然很大。我还想知道将它们存储为最佳文件格式,无论是在整体大小还是所需的开销方面。

这是一种超级简单的方法,它可以工作,但它似乎并没有随心所欲地切割它,​​它使用太多了。

我的建议是将动画分成几层,因为我认为可以采用不同的方式做一些事情:

  • 使背景成为静态图像,因此不必成为动画的一部分
  • 取出一些“doodads”,例如移动图形和进度条,并在动画的顶部或下方制作它们自己的部分透明图层。对于我来说,这也将为未来的创作自由敞开大门。
  • 剪下顶部的文字并使用iPhone以编程方式显示文字。使用iPhone绘制文本或加载带有文本的图像是否更好?作为一个Web开发人员,我发现加载任何带有文本的图像都很愚蠢。
  • 播放这些东西之后剩下的东西作为动画,这将会相当小。

总的来说,我们看的是1个静态背景,3-5个小动画和一个大动画。我可以使用图层将这些元素分开,并依靠iPhone来绘制最终图像吗?这就是我认为我可以让它运行得更好的地方,将所有内容合并为一个你翻转的大图片似乎很愚蠢,当你可以改为加载一些在app范围内使用的较小元素时,做得更有效率。

或者,我是否完全过于复杂,是否有更好的方法呢?

编辑:我一直在浏览,看来使用图层会更有效率。不过,我还有另外一个问题。将动画的每个帧作为自己的文件,加载到数组中进行动画,或者使用包含所有帧的一个巨型精灵图像,让iPhone使用坐标从精灵表中抓取每一帧是否更好?编程?

编辑2:我们已经完成了所有工作,check it out on the App store.

2 个答案:

答案 0 :(得分:1)

假设整个动画序列是静态的,你最好把它编成电影,并使用电影播放器​​框架来播放它:

MPMoviePlayerController

这将允许iPhone为显示器使用自定义硬件,并将使电池使用率降低。至于用户交互,您只需设置movieControlMode属性以防止用户与电影交互:

  

MPMovieControlModeHidden不要   显示任何控件。这种模式   阻止用户控制   回放。

     

适用于iPhone OS 2.0及更高版本。

     

在MPMoviePlayerController.h中声明。

答案 1 :(得分:0)

这是我用来解决问题的极早版本。我很清楚它并不是理想的,但它确实有效。如果你觉得你需要更加出色地写这个,那么一定要这样做。我会尽力回过头来发布更新。

计时器失去了它的准时能力@ <0.1秒,所以如果你设置为28fps,图像渲染为28fps,它将丢帧,但非常不明显。

    - (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"VDL");
    [animationFrame initWithInteger:1];
    [self animation];
    NSLog(@"VDL Completed");
}

- (void)animation {
    CGRect animationRect = CGRectMake(0, 0, 320, 384);
    //NSLog(@"animationRect defined");
    animationImages = [[UIImageView alloc] initWithFrame:animationRect];
    [self.view addSubview:animationImages];
    //NSLog(@"animationImages allocated, init'd");
    animationTimer = [NSTimer scheduledTimerWithTimeInterval:0.0357 target: self selector:@selector(blah) userInfo:nil repeats:YES];
    [animationImages setImage:[UIImage imageNamed:[NSString stringWithFormat:@"SCAN%d.jpg", animationFrame]]];
    //NSLog(@"animationTimer started");
    animationTimer = nil;
    //NSLog(@"animationTimer set to nil");
}

- (void)blah {
    if (animationFrame <= 336){
        animationFrame += 1;
        [animationImages setImage:[UIImage imageNamed:[NSString stringWithFormat:@"SCAN%d.jpg", animationFrame]]];
        NSLog(@"%d", animationFrame);
    }
    else {
        animationFrame = 1;
        NSLog(@"restart");
    }
}