SpriteKit: движещият се спрайт безкрайно причинява понякога прекъсване на рамката

всичко. Сега разработвам игра за ios, използвайки комплект спрайтове. Механиката на играта включва: безкрайно превъртане на спрайтове отгоре надолу.

Моята игрова сцена съдържа само 3 спрайта, горен, среден, долу. Имам десетки изображения на спрайтове, така че моето решение е динамично създаване на 3 спрайта (така че спрайтовете да могат да запълнят целия екран), когато долният спрайт е извън екрана, след това го унищожава; когато горният спрайт слезе надолу по горната рамка, създайте нов спрайт възел, след това разменете долния, средния, горния спрайт.

Псевдо кодът: в интерфейсния файл:

 - GameScene:SKScene
 {
      ...
      SKSpriteNode *_topSprite;
      SKSpriteNode *_middleSprite;
      SKSpriteNode *_bottomSprite;
      ...
 }

във файла за изпълнение:

- (void)update:(CFTimeInterval)currentTime 
{
   // 1 compute time interval


   // 2 update sprite node
    _topSprite.position move down  100*timeInterval
   _middleSprite.position move down  100*timeInterval  
   _bottomSprite.position move down    100*timeInterval 

   // 3 crop the off-screen bottom sprite node
   if (_bottomSprite is offScreen)
   {
       [_bottomSprite removeFromParent]
   }

   // 4 check the highest sprite position visible
   // if the highest position is below the frame top,then create new sprite
   _bottomSprite = _middleSprite;  
   _middleSprite = _topSprite;
   _topSprite    = [self createNewNode]; // random a sprite image 
}

fps на играта е 60, а броят на възлите не се увеличава. Всичко изглежда добре, но открих, че понякога играта просто внезапно има много задушаване, което кара движещата се рамка да не е непрекъсната. Интуитивно мислех, че основната причина е причинена от стъпка 4. Но нямам никаква идея как да го разреша. Всякакви предложения ще бъдат оценени.

Ето метода createNewNode:

- (SKSpriteNode *)createNewNode {
    NSString *blockName = [self randomImageName];

    SKSpriteNode *sprite = [[SKSpriteNode alloc] initWithImageNamed:blockName];
    sprite.position = _highestPosition;
    sprite.anchorPoint = CGPointMake(0.5, 0);
    NSLog(@"putAnotherNodeOnTop %@", blockName);
    [self addChild:sprite];
    return sprite;
}

person cartmanie    schedule 11.07.2014    source източник
comment
Какъв е размерът на вашите изображения на спрайтове? Заредени ли са от sprites.atlas?   -  person Akaino    schedule 11.07.2014
comment
Всичките ми изображения на спрайтове са с еднакъв размер: 390*512. Не използвам sprites.atlas.   -  person cartmanie    schedule 11.07.2014
comment
Странно. Не би трябвало да има такъв проблем. Бихте ли публикували своя createNode, моля?   -  person Akaino    schedule 11.07.2014
comment
Поставям кода в публикацията.   -  person cartmanie    schedule 11.07.2014
comment
Използвайте Time Profiler, за да определите кой ред код е най-скъп   -  person Andrey Gordeev    schedule 11.07.2014
comment
1. Използвайте атлас. 2. Не пускайте/създайте нови спрайтове, използвайте едни и същи 3 спрайта в цялата игра. Просто променете позицията им и, ако е необходимо, текстурата им, докато ги местите отдолу нагоре. #2 вероятно е мястото, откъдето идва вашият проблем с производителността, тъй като циклите за разпределяне/освобождаване за спрайтове са скъпи, още повече, ако те трябва да зареждат отделни изображения и тези изображения не са в атлас, което означава, че всяко отделно изображение трябва да бъде заредено, вместо да бъде възможност за предварително зареждане на целия атлас в началото.   -  person LearnCocos2D    schedule 11.07.2014


Отговори (1)


Няколко предложения.

Тъй като използвате едни и същи три изображения, не е необходимо да създавате отново спрайтовете всеки път. Би трябвало да е по-евтино да зададете скритата стойност на ДА, да преместите спрайта някъде, да зададете текстурата и след това да я покажете отново със скрита на НЕ. SpriteKit не рисува скрити възли или такива извън екрана.

Вашият код основно изисква PNG на диска всеки кадър в актуализацията, когато се извика createNewNode:. Трябва да е по-ефективно да заредите текстурите в паметта и да ги присвоите на спрайтове, ако е необходимо. Ако имате само няколко, превръщането им в SKTexture променливи на екземпляр ще бъде лесен начин да го направите.

Използвайте spritesheets (атласи на текстури), много по-бързо е да нарисувате изображение от паметта при нанесени координати, отколкото да го зареждате от диска всеки път. Например с три изображения в spritesheet това може да бъде едно извикване на теглене. От диск това са три отделни повиквания за изтегляне.

Връщате спрайт и го добавяте към сцената в метода createNewNode:. Може би това е, което искате по някаква причина. Изпъкваше като възможно дублиране на усилията.

person Jeremy    schedule 12.07.2014