应用程序在iOS中扩展动画线... howto

时间:2010-07-29 06:49:41

标签: iphone ipad

基本理念
很容易简化你可以说...一条蛇就像一条线,通过一个让我们说3px线在屏幕上扩展收集并与不同的东西进行交互,可以通过用户输入来控制。就像一条连续的线,你会用钢笔绘制。

我已经开始阅读有关Quartz / CG的Apple文档了。 据我所知,我需要将渲染代码放入UIView的drawRect中。 然后我需要设置一个计时器(在这里和那里找到一些答案/帖子,没有具体的),每秒触发x次并在UIView上调用setNeedsDisplay。

问题:
如何实现以下目标: 在UIView 1 /(Layer?)上有整条蛇,在UIView 2上绘制新部分,合并它们,以便将新部分附加到UIView 1(或CALayer而不是视图?)。我明确地询问我读到的这个原因,不应该一遍又一遍地重绘相同的内容,而只是新的/移动的部分。 我希望你能提供一些示例代码或一些我应该使用的类的详细信息,以及如何使用它们/调用make的策略。


修改
好的,我看到我的想法或我以前用石英和不同的观点来实现这一点的想法并不那么明智......(Daniel Bleisteiner
所以我现在切换到OpenGL,我正在研究它,阅读示例,Jeff LaMarche的OpenGL博客条目等。 我想我能画出我的台词。我想我会为曲线,直线/方向变化等创建类,然后在用户输入上我会创建相关对象(取决于转向输入)将它们存储在一个数组中,然后通过读取重新创建并重绘整行来自每个帧上存储在数组中的对象的对象属性。我会画一个简单的线(来自Beginning iPhone Development的代码)

glDisable(GL_TEXTURE_2D);
GLfloat vertices[4];    
// Convert coordinates
vertices[0] = start.x;
vertices[1] = start.y;
vertices[2] = end.x;
vertices[3] = end.y;
glLineWidth(3.0);
glVertexPointer (2, GL_FLOAT , 0, vertices);
glDrawArrays (GL_LINES, 0, 2);

也许我甚至会找到一种解决它的方法,但

  1. 现在我更好奇我的想法是否足够好,或者是否有更好的策略
  2. 也许有人可以告诉我如何分离hud的代码,线条绘制本身以及我必须显示的一些菜单f.e.在开始...这样很容易从一个“视图”过渡到另一个视图(如淡入淡出)?一些提示?

  3. 也许你还读了一本书,这将解释如何解决这类问题? 或者您可以指出另一个好的答案/示例代码,因为我在查找“动画绘图”示例时遇到了很大的问题。

    this让我更进一步,但对我来说仍然有点模糊。 我不知道如何实现“你绘制的更新路径(只有需要的点+移动的最后一点)”

2 个答案:

答案 0 :(得分:0)

不要尝试合并不同的视图... setNeedsDisplay有一个rect参数,告诉核心图形部分只需要再次渲染屏幕的某个部分。在drawRect方法中尊重此参数,它应该足以用于标准的2D游戏和工具。

如果您打算使用强烈的图形,除了使用OpenGL之外别无选择。性能好多倍,你不必关心优化...... OpenGL在后台做了很多。

答案 1 :(得分:0)

使用OpenGL ES。那么你想要做的是创建一个运行循环函数或方法,由CADisplayLink每秒调用30到60次。 60是最大值。

那么这是如何运作的?

1)为CADisplayLink创建一个assign-property。请勿保留CADisplayLink,因为显示链接和计时器会保留其目标。否则你会创建一个保留周期,这可能会导致内存丢失(这比泄漏更糟糕,更难发现)。

@property (nonatomic, assign) CADisplayLink *displayLink;

2)创建并安排CADisplayLink:

- (void)startRunloop {
    if (!animating) {
        CADisplayLink *dl = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawFrame)];
        [dl setFrameInterval:1];
        [dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        self.displayLink = dl;

        animating = YES;
    }
}

此处需要注意的一些事项:-setFrameInterval:1告诉CADisplayLink不要跳过任何帧。这意味着:您获得最大fps。但是:如果您的代码需要超过1/60秒,这可能会很糟糕。在这种情况下,最好将其设置为2,例如。使您的动画更加流畅。

3)在-drawFrame方法中,照常执行OpenGL ES绘图。唯一的区别是这个代码每秒被调用多次。只需跟踪时间并在代码中确定要绘制的内容以及绘制方式。如果您要设置一个从左下角移动到右上角并且动画持续时间为1秒的矩形动画,则只需应用一个需要时间 t 作为参数的函数,在开始和结束之间插入动画帧。 。有数千种方法可以做到这一点。这是其中之一。

4)当您完成或想要暂停OpenGL ES绘图时,只需使CADisplayLink无效或暂停。像这样:

- (void)stopRunloop {
    if (animating) {
        [self.displayLink invalidate];
        self.displayLink = nil;
        animating = NO;
    }
}