2015-04-08 4 views
1

Проблема: у меня есть небольшая игра, где вы можете поцарапать изображение над другим изображением. Верхнее изображение становится невидимым, когда вы царапаете. Все это помещено в представление SpriteKit. Проблема в том, что на более слабых устройствах (iPhone4) царапающее изображение обновляется только тогда, когда пользователь перестает царапать.CGContext не обновляется сразу

Я предполагаю, что изображение обновляется только тогда, когда пользователь не царапает, пока изображение не будет полностью отображено и отображено.

Может кто-нибудь предложить лучший способ сразу увидеть царапины. Я знаю, что царапины потребляют много производительности, но я не возражаю, если он немного отстает.

Вот код:

-(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; 


} 

UPDATE

Я кончались записи точки, как предложено в правильном ответе. Но кроме обновления изображения в обратном вызове 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; 

} 

более производительный код будет также содержать ссылку на контекст, но мне не удалось получить эту работу. Если кто-то может предложить решение, я был бы счастлив. Тем не менее мой Framerate на iPhone 4 поднялся до 25-30 кадров в секунду со скоростью около 5 кадров в секунду.

ответ

0

Я хотел бы попробовать следующее:

  1. Меру в Instruments.app Time Profiler.
  2. Ускорить рисование, создав CGBitmapContext в качестве переменной экземпляра. Затем вы можете пропустить [_scratchImage drawInRect:...] на каждом шагу.
  3. Отделите рисунок и обработку событий. Прямо сейчас, вы всегда будете создавать новый UIImage для каждого события касания. Было бы лучше объединить поглаженные линии, поэтому создание UIImage происходит не так часто. Например. поместите сегменты линии в очередь и выполните обратный вызов от CADisplayLink.
+0

Благодарю вас за ответ. Я попробую это прямо сейчас. Я не могу дать вам аванс, потому что у меня нет достаточной репутации – ben

0

Я мало знаю о SpriteKit, в UIView, вы должны поместить свой код чертежа в метод drawRect. Это то же самое, что и SpriteKit?