【问题标题】:Frame rate compromised with CADisplayLink and drawRectCADisplayLink 和 drawRect 降低了帧速率
【发布时间】:2012-10-17 01:47:20
【问题描述】:

我的问题是关于 iOS 开发的。我正在编写一个简单的游戏,以测试低级核心图形功能(上下文、图层等)以及如何将它与实际的简单视图混合......我解释一下: 我在屏幕上有一个简单的精灵,它使用UIImageView 属性进行动画处理,因此帧速率可以完美运行。 之后,我添加了一个无限的背景,它使用bezier curves 即时生成。为了对此进行动画处理,我使用CADisplayLink,在后台调用方法"animate",将我的点移动到bezier curve,然后我调用setNeedsDisplay。它“或多或少”工作得很好,但是如果我删除背景(或 setNeedsDisplay 调用,所以它不会在每一帧都重新生成)帧速率会增加很多,所以“任何东西”在这部分都不能正常工作...

我也尝试过双缓冲系统,但它的效果比我当前的代码差。我也想使用线程,但我真的没有发现 CPU 在后台做任何困难的事情。

代码如下:

//This is called automatically with CADDisplayLink.
- (void) animate:(CADisplayLink *)sender
{
    //Check for deleting the first point.
    float x = points[firstPoint].x;
    if ( x < -2*DIST ) {
        CGFloat lastX = points[lastPoint].x;
        lastPoint = firstPoint;
        firstPoint = ((firstPoint + 1) % (TOTAL_POINTS));
        points[lastPoint] = CGPointMake(lastX + DIST, [self getNextY]);
    }

    //Move points
    for(int i = 0; i < TOTAL_POINTS; i++) {
        points[i].x -= 7;
    }

    //Mark as "needed to redraw"
    [self setNeedsDisplay];

}

- (void)drawRect:(CGRect)rect
{    
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetLineWidth(context, 3.0);
    CGContextSetRGBStrokeColor(context, 0, 0, 0, 1.0);
    CGContextSetRGBFillColor(context, 1.0, 0, 0, 1.0);
    CGContextSetLineCap(context, kCGLineCapRound);

    //Create path
    CGMutablePathRef path = CGPathCreateMutable();

    //Draw the curve
    [self drawBezierCurveInPath:path];

    //Close and add path
    CGPathAddLineToPoint(path, NULL, 485, -5);
    CGPathAddLineToPoint(path, NULL, -5, -5);
    CGPathCloseSubpath(path);

    CGContextAddPath(context, path);

    CGContextSetFillColorWithColor(context, bg2);

    //    [[UIColor redColor] setFill];
    [[UIColor blackColor] setStroke];

    CGContextDrawPath(context, kCGPathFillStroke);    

    //Release
    CGPathRelease(path);

    //Paint time.
    playintIntervalView.text = [NSString stringWithFormat:@"%f", playingInterval];
}

- (void) drawBezierCurveInPath: (CGMutablePathRef) path
{
    CGPoint fp = midPoint(points[firstPoint], points[(firstPoint+1)%TOTAL_POINTS]);
    CGPathMoveToPoint(path, NULL, fp.x, fp.y);

    int i = firstPoint;
    for (int k = 0; k < TOTAL_POINTS-2; k++) {
        previousPoint2 = points[i];
        previousPoint1 = points[(i+1)%TOTAL_POINTS];
        currentPoint = points[(i+2)%TOTAL_POINTS];

        // calculate mid point
        CGPoint mid2 = midPoint(currentPoint, previousPoint1);

        CGPathAddQuadCurveToPoint(path, nil, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y); 

        i = (i + 1) % TOTAL_POINTS;        
    }

}

我更愿意存储一个UIBezierPath(这样我就可以进行一些碰撞测试),但它不允许你只删除一个点(当它离开左侧的屏幕时),所以我必须也每帧初始化它......我错过了什么吗?

【问题讨论】:

    标签: iphone objective-c ios drawrect cadisplaylink


    【解决方案1】:

    这可能有点晚了,但在这种情况下使用 CADisplayLink 来制作动画是个坏主意。 您应该研究 CoreAnimation 以获得有效的路径动画。

    这里的问题是您尝试每秒重绘 60 次,而 drawRect 中的代码可能无法在您拥有的毫秒数内完成。 通过删除 setNeedsDisplay,您基本上是在告诉它不要更新。

    【讨论】:

      猜你喜欢
      • 2019-11-20
      • 1970-01-01
      • 2017-11-16
      • 1970-01-01
      • 2021-03-26
      • 2013-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多