SpriteKit SKAction moveTo: искажается, когда приложение переходит в фоновый режим

#objective-c #sprite-kit #skaction

#objective-c #sprite-kit #skaction

Вопрос:

В игре SpriteKit я использую бесконечное повторение SKAction moveTo: для отображения металлического блеска / мерцания на спрайте. По сути SKCropNode , это маска, которая перемещается из одной позиции в другую, останавливается, возвращается в исходное положение и повторяется. maskNode Само приложение анимируется в обратном направлении.

Это работает нормально, даже если сотни из них на экране работают часами.

Однако, когда приложение переходит в фоновый режим и возвращается, все позиции этих узлов изменились. Анимация все еще продолжается, но в неправильных положениях. Металлическое мерцание повсюду на экране, кроме того места, где оно должно быть.

Я ничего не меняю в методах UIApplication делегирования. Даже если я pause SKView , пока приложение находится в фоновом режиме, происходит то же самое.

 // create the shine node
    SKSpriteNode *shine = [SKSpriteNode spriteNodeWithTexture:@"metal_shine"];
    shine.size = self.size;

// create the mask node
    SKSpriteNode *maskNode = [SKSpriteNode spriteNodeWithTexture:@"disk_mask"]];
    maskNode.size = self.size;

// create the crop node
    SKCropNode *cropNode = [[SKCropNode alloc] init];
    [cropNode addChild:shine];
    cropNode.maskNode = maskNode;
    cropNode.maskNode.position = CGPointMake(self.size.width * 0.5, self.size.height * -0.5);
    cropNode.position = CGPointMake(self.size.width * -0.5, self.size.height * 0.5);
    [self addChild:cropNode];
    
// add actions
    SKAction *delayAction = [SKAction waitForDuration:1.0];
    SKAction *pauseAction = [SKAction waitForDuration:3.0];

    SKAction *resetActionMaskNode = [SKAction moveTo:CGPointMake(self.size.width * 0.5, self.size.height * -0.5) duration:0];
    SKAction *moveActionMaskNode = [SKAction moveTo:CGPointMake(self.size.width * -0.5, self.size.height * 0.5) duration:0.6];
    SKAction *resetActionCropNode = [SKAction moveTo:CGPointMake(self.size.width * -0.5, self.size.height * 0.5) duration:0];
    SKAction *moveActionCropNode = [SKAction moveTo:CGPointMake(self.size.width * 0.5, self.size.height * -0.5) duration:0.6];
    
    SKAction *repeatActionMaskNode = [SKAction repeatActionForever:[SKAction sequence:@[resetActionMaskNode, moveActionMaskNode, pauseAction]]];
    SKAction *repeatActionCropNode = [SKAction repeatActionForever:[SKAction sequence:@[resetActionCropNode, moveActionCropNode, pauseAction]]];


// go
    [cropNode.maskNode runAction:[SKAction sequence:@[delayAction, repeatActionMaskNode]] withKey:@"idleAnimation"];
    [cropNode runAction:[SKAction sequence:@[delayAction, repeatActionCropNode]] withKey:@"idleAnimation"];
  

Комментарии:

1. Я думаю, проблема в том, к (self.position.x self.size.width * 0.5, self.position.y - self.size.height * 0.5) чему self относится? Может быть, сохранить позицию и размер, а не получить их из self ?

2. @skaak спасибо, что это действительно было неправильно. self относится к спрайту, к которому эффект добавляется как дочерний элемент. Однако после исправления проблема все еще существует; после того, как приложение переходит в фоновый режим и возвращается, значения position.x как the cropNode , так и the maskNode внезапно смещаются.

3. Хорошо — здесь вы просто показываете внутреннюю часть. Когда вы вызываете это или внутри какого сообщения это?