【问题标题】:How can I animate manually on the iPhone?如何在 iPhone 上手动制作动画?
【发布时间】:2010-10-04 01:01:20
【问题描述】:

我在 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 来制作任何有趣的手动动画吗?

【问题讨论】:

    标签: iphone cocoa-touch animation calayer


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      如果您需要做的只是为从 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,同时有几十个半透明层移动。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

          我发现真正的问题是必须致电[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;
          

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-06-10
            • 2015-08-13
            • 1970-01-01
            • 2020-10-01
            • 2019-03-30
            • 2016-06-23
            相关资源
            最近更新 更多