CGContext不会立即更新

时间:2015-04-08 08:33:20

标签: ios sprite-kit cgcontext

问题:我有一个小游戏,你可以在另一个图像上划伤图像。在你刮擦的地方,上面的图像变得不可见。整个事情被放入SpriteKit视图中。问题是,在较弱的设备(iPhone4)上,刮擦图像仅在用户停止刮擦时才更新。

我认为只有在用户没有划伤之后才会更新图像,直到图像完全呈现并显示出来。

有人可以建议一种更好的方法来立即看到刮痕。我知道刮擦消耗了很多性能,但我不介意它是否有点滞后。

这里是代码:

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];


UIGraphicsBeginImageContext(self.view.frame.size);

[_scratchImage drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];

CGContextMoveToPoint(UIGraphicsGetCurrentContext(), _lastPoint.x, _lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 25.0f );
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 0.0, 1.0);

CGContextSetBlendMode (UIGraphicsGetCurrentContext(), kCGBlendModeClear);

CGContextStrokePath(UIGraphicsGetCurrentContext());

_scratchImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

_lastPoint = currentPoint;

SKTexture* scratchTexture = [SKTexture textureWithImage:_scratchImage];

_scratchSprite.texture = scratchTexture;


}

更新

我最后按正确答案中的建议录制了积分。但除了在CADisplayLink回调中更新图像之外,我在

中更新了屏幕
-(void)update(float currentTime) 

来自SpriteKit的回调(对于SpriteKit用例来说是一样的)

我在更新方法中的代码如下所示:

-(void)displayUpdated
 {


UIGraphicsBeginImageContext(self.view.frame.size);

[_scratchImage drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];

CGMutablePathRef linePath = nil;
linePath = CGPathCreateMutable();


CGPathMoveToPoint(linePath, NULL, _lastPoint.x, _lastPoint.y);


for (NSValue* val in _recordedPoints) {

    CGPoint p = [val CGPointValue];

    CGPathAddLineToPoint(linePath, NULL, p.x, p.y);

    NSLog(@"%f, %f", p.x, p.y);

    _lastPoint = p;

}
//flush array
[_recordedPoints removeAllObjects];


CGContextAddPath(UIGraphicsGetCurrentContext(), linePath);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 25.0f );
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 0.0, 1.0);

CGContextSetBlendMode (UIGraphicsGetCurrentContext(), kCGBlendModeClear);

CGContextStrokePath(UIGraphicsGetCurrentContext());

_scratchImage = UIGraphicsGetImageFromCurrentImageContext();

CGPathRelease(linePath);

UIGraphicsEndImageContext();

SKTexture* scratchTexture = [SKTexture textureWithImage:_scratchImage];



_scratchSprite.texture = scratchTexture;

 }

性能更高的代码也会引用上下文,但我无法让它工作。如果有人可以提出解决方案,我会很高兴。不过,我在iPhone 4上的Framerate从大约5 fps上升到了25-30 fps。

2 个答案:

答案 0 :(得分:0)

我对SpriteKit了解不多,在UIView中,你应该把你的绘图代码放在drawRect方法中。它和SpriteKit一样吗?

答案 1 :(得分:0)

我会尝试以下方法:

  1. 在Instruments.app中测量Time Profiler
  2. 通过创建CGBitmapContext作为实例变量来加快绘图速度。然后,您可以在每个步骤中跳过[_scratchImage drawInRect:...]
  3. 分离绘图和事件处理。现在,您将始终为每个触摸事件创建一个新的UIImage。合并行描线可能会更好,因此UIImage的创建不会经常发生。例如。将线段放入队列并从CADisplayLink中回调。