【问题标题】:Rendering hundreds of "block" images -vs- Partially rendering a "map" of blocks渲染数百个“块”图像 -vs- 部分渲染块的“地图”
【发布时间】:2010-05-19 16:01:43
【问题描述】:

似乎这些解决方案都没有消除与将图像渲染到屏幕上相关的延迟(无论是来自 .png 还是使用 CG)。

有一个 28x16 的方块网格,每个方块都是 16x16 像素,在游戏中的某些点,大约一半的方块需要因为状态变化而改变它们的图像。将每个块作为主视图的子视图会导致一半的块需要单独更改其图像(从 .png 或使用 CG)。

我尝试了一个“地图”视图,其 drawRect: 方法是:

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);

// width and height are defined as the width and height of the grid (28x16 for iPhone)
for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
        // states[] is an enum instance variable that holds the states of each block in the map (state determines image)
        if (states[(x * height) + y] == PXBlockStateEmpty) {
            CGContextSetFillColorWithColor(context, [UIColor colorWithRed:153.0/255.0 green:153.0/255.0 blue:153.0/255.0 alpha:0.5].CGColor);
            CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5].CGColor);
            CGContextAddRect(context, CGRectMake(x * 16, y * 16, 16, 16));
            CGContextDrawPath(context, kCGPathFillStroke);
        } else if (states[(x * height) + y] == PXBlockStateSolid || states[(x * height) + y] == PXBlockStateSolidEdge) {
            CGContextSetFillColorWithColor(context, [UIColor colorWithRed:0.0 green:0.0 blue:102.0/255.0 alpha:0.9].CGColor);
            CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5].CGColor);
            CGContextAddRect(context, CGRectMake(x * 16, y * 16, 16, 16));
            CGContextDrawPath(context, kCGPathFillStroke);
        } else if (states[(x * height) + y] == PXBlockStateBuilding) {
            CGContextSetFillColorWithColor(context, [UIColor colorWithRed:51.0/255.0 green:51.0/255.0 blue:51.0/255.0 alpha:0.5].CGColor);
            CGContextFillRect(context, CGRectMake(x * 16, y * 16, 16, 16));
        }
    }
}

所以我的解决方案是在地图上调用 setNeedsDisplayInRect:,传递状态发生变化的块的框架(16x16 矩形)。我是在错误地使用 setNeedsDisplayInRect:,还是这只是一种低效的方法?

两个选项(一个子视图与数百个子视图)在很多棋盘上都填满不同图像时会稍微滞后一点,而当任何块的图像需要更新时,第二个解决方案尤其滞后。

有什么想法吗?感谢您的帮助!

【问题讨论】:

    标签: iphone objective-c graphics performance rendering


    【解决方案1】:

    调用 setNeedsDisplayInRect: 会影响 drawRect: 的参数,但在其他方面与 setneedsDisplay 相同。矩形 drawRect: 接收是所有脏矩形的并集。如果您只绘制与该矩形相交的内容,而不触及其他内容,您可能会看到速度有所提高。从上面的代码 sn-p 来看,您每次都绘制每个图块。由于它是一个联合,您也可以单独跟踪脏瓷砖,并且只绘制脏瓷砖。在这种情况下,请为单个图块调用 CGContextClearRect 而不是清除整个上下文,除非它们都是脏的。

    CGContextAddRect 向将要绘制的路径添加一个矩形。由于您在每个循环处绘制路径而不开始新路径,因此随着循环的进行重绘区域。使用 CGContextFillRect 和 CGContextStrokeRect 而不是路径可能会更快。

    将每个 tile 设为单独的 UIView 会比绘制整体产生更多开销。一旦解决了问题,您应该能够通过这种方法获得更快的速度。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 1970-01-01
    • 2011-02-26
    • 2017-10-19
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    相关资源
    最近更新 更多