【问题标题】:What is the best way to animate a sequence of images on the iPhone?在 iPhone 上为一系列图像制作动画的最佳方式是什么?
【发布时间】:2012-08-13 04:55:52
【问题描述】:

我正在制作一个有胜利状态和失败状态的游戏。对于每个状态,我想显示一个 2-3 秒的短动画。第一个动画由 60 个 PNG 组成,速率为 30 fps,第二个动画由 80 个 PNG 组成,也是 30 fps。我尝试了各种方法,并广泛搜索了解决方案,但我一直发现的前两个结果是使用 UIImageView animationImages 和 Core Animation。在模拟器中使用 UIImageView 效果很好,但第一次在设备上运行需要很长时间。我认为这是因为图像需要加载到内存中。我正在使用“imageNamed”来填充animationImages数组,但我猜他们需要在第一次调用动画时渲染?我已经尝试在应用程序加载时预渲染它们,这似乎可以解决问题,但是预渲染所有这些图像需要将近 10 秒,这对用户不友好。我也愿意使用 Core Animation,但我对它的了解非常有限,因此非常感谢详细的解释。谢谢!

当您说我需要在应用启动时加载所有内容时,您究竟是什么意思?现在,我在应用加载时初始化两个动画图像数组,如下所示:

// Create thinnestAnimation Array
thinnestAnimation = [[NSMutableArray alloc] init];
for(int i = 1; i <= 60; i++)
{
    UIImage *thinImage = [UIImage imageNamed:[NSString stringWithFormat:@"ThinnestJump_%d.png", i]];
    [thinnestAnimation addObject:thinImage];
}

thinAnimationImageView.animationImages = (NSArray *)thinnestAnimation;
thinAnimationImageView.animationDuration = 2.0;
thinAnimationImageView.animationRepeatCount = 1;

thinAnimationImageView 是我界面中的一个 IBOutlet,当我想为图像序列设置动画时,我调用了[thinAnimationImageView startAnimating];。这严重滞后于第一次通话,但此后很好。有没有办法防止它第一次滞后?

【问题讨论】:

  • 抱歉,动画的计算成本很高。 Apple尽可能地编写了UIImageView。使用它。
  • 如果你有预渲染的帧,你只想按顺序绘制,那么核心动画不会真正帮助你;它更适用于涉及移动或转换现有图像(或一组图像)和/或添加某些特殊效果的动画。现在,如果您想要的视觉效果符合该描述,您可以使用 CA 代替您的图像序列。
  • 您还可以研究如何优化图像。他们有阿尔法吗?他们真的需要吗?屏幕的大面积是每帧都在变化,还是只是一小部分?它作为视频可能会更好吗?

标签: iphone image animation sequence


【解决方案1】:

UIImageView 的内置动画功能是一个很好的方法。但是,您需要在需要动画之前加载所有内容,例如在应用程序启动时。如果您需要准备好多个不同的动画,请在启动时加载多个 UIImageView 对象,然后使用其startAnimating 方法调用您需要的对象。

还有其他方法可以制作动画,例如使用 Cocos2D,它使用 OpenGL 制作动画,性能更快。但是,您已经在一个完全不同的框架中构建了您的应用程序,这可能有点过头了,具体取决于您的应用程序中发生的其他情况。

【讨论】:

  • 至于在启动时加载 UIImageView 对象,我初始化了它们,但动画的第一次运行仍然滞后。所以相反,我在启动时在隐藏视图中执行了这两个动画,所以当用户使用应用程序时它们很好。唯一的缺点是加载应用需要 6-8 秒。
  • 如果你有一个动画重的应用程序,你可以考虑除 UIKit 之外的其他库,例如 Cocos2D
  • 就是那两个短动画
【解决方案2】:

正如 andrews 所说,UIImageView 具有动画的内置属性

就像你有一个图像数组(imgarray)和一个图像视图

用于创建图像数组

NSMutableArray *imgarray = [NSMutableArray arrayWithCapacity:100]
for (int i = 0; i < 100; ++i) {
  NSString *name = [NSString stringWithFormat:@"img%d.png",i];
  UIImage *image = [UIImage imageNamed:name];
  [imgarray addObject:image];
}

然后是动画

UIImageView *imgview;

imgview.animationimages=imgarray;

然后设置

 imgview.animationDuration=2.0;  //in seconds

     [imgview startAnimating];

stopanimating 用于停止动画 还有一个动画重复计数的属性

希望对您有所帮助.....

【讨论】:

    【解决方案3】:

    您可能想查看this article 关于使用 CALayer 使用精灵表制作动画的信息。图层的开销与 spritesheet 一样少。

    【讨论】:

      【解决方案4】:

      迟到的答案,但我自己处理了这个问题,发现以下有用:

      第三个答案的底部,Animation using array of images in sequence

      基本上,使用 imageNamed: 比直接从包中提取图像要慢。以下是我所做的让我的加载速度更快的做法:

      NSMutableArray *imagesArray = [NSMutableArray new];
      
      for (int i = 0; i < 150; i++)
      {
          [imagesArray addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"pngSlice-%d", i]
                                                                                                  ofType:@"png"]]];
      }
      
      self.myImageView.animationImages = imagesArray;
      self.myImageView.animationRepeatCount = 1;
      self.myImageView.animationDuration = 2.5;
      
      [self.myImageView startAnimating];
      
      imagesArray = nil;
      

      如果您将图像直接添加到包中并按顺序命名它们(即 pngSlice-0、pngSlice-1、pngSlice-2...),则此方法有效。我有 150 张图片,更改条件以匹配您的图片总数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-10
        • 2014-06-07
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多