iOS Sprite Kit, как отключить пользовательские прикосновения к сцене во время воспроизведения анимации?

У меня есть пошаговая игра, в которой объекты перемещаются по игровому полю. Это движение требует времени, около 0,4 секунды на ход. Я хочу отключить дальнейшие касания сцены, пока мой объект не достигнет места назначения, и я не смогу выполнить вычисления для новой позиции.

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

[selectedModel runAction:[SKAction moveTo:[MapOfTiles positionForTileCoord:s.position] duration:0.75] completion:^{
    [self animateNextMove];
    if(reachedDestination)
    {
        isAnimatingMove = NO;
    }
}];

Я заметил, что наложение прозрачного SpriteNode с взаимодействием с пользователем, установленным на NO, кажется, по-прежнему фиксирует прикосновения (я планировал добавить прозрачное наложение и включить/выключить его взаимодействие с пользователем для захвата прикосновений.

Как лучше всего отключить кнопки и касания узлов, пока Sprite Kit выполняет некоторую анимацию?


person Alex Stone    schedule 14.12.2013    source источник


Ответы (3)


Сделайте [self setUserInteractionEnabled:NO]; на своей сцене:

[selectedModel runAction:[SKAction moveTo:[MapOfTiles positionForTileCoord:s.position] duration:0.75] completion:^{
    [self animateNextMove];
    [self setUserInteractionEnabled:NO];
    if(reachedDestination)
    {
        [self setUserInteractionEnabled:YES];
    }
}];

Это предотвратит все прикосновения к вашей сцене, пока reachedDestination не станет истинным... Это то, что вы искали?

person Ponyboy47    schedule 14.12.2013
comment
Я пробовал оба self.userInteractionEnabled = NO; self.view.userInteractionEnabled = НЕТ; Оба по-прежнему позволяли запускать весь сенсорный код. - person Alex Stone; 15.12.2013

Похоже, это работает:

cover — переменная узла instance, при добавлении в сцену не пропускает касания. Возможно, вам придется поиграть с размером вашей сцены, у меня пейзаж.

-(void)preventUserInteraction:(BOOL)prevent
{
    if(cover == nil)
    {
        cover = [[SKSpriteNode alloc] initWithColor:[UIColor clearColor] size:CGSizeMake(1024,768 )];
        cover.position = CGPointMake(1024/2, 768/2);
    }
    if(prevent)
    {
        [self addChild:cover];
    }else
    {
        [cover removeFromParent];
    }
}
person Alex Stone    schedule 15.12.2013

Вот как я это сделал:

//Disable user interaction
[self setUserInteractionEnabled: NO];

// Grab our hero sprite node, create an image atlas of textures and push into an action
SKSpriteNode *hero = (SKSpriteNode *)[self childNodeWithName: @"hero"];

SKTextureAtlas *heroPunchAtlas = [SKTextureAtlas atlasNamed: @"heroPunch"];

SKTexture *punchF1 = [heroPunchAtlas textureNamed: @"heroPunchF1"];
SKTexture *punchF2 = [heroPunchAtlas textureNamed: @"heroPunchF2"];

NSArray *heroPunchTextures = @[punchF1, punchF2];

SKAction *heroPunch = [SKAction animateWithTextures: heroPunchTextures timePerFrame: 0.1];

// The trick is here, where you have the completion callback 
// which is fired once the animation is done. If you place the 
// [self setUserInteractionEnabled: YES]; as the last line, it will get called
// before the animation finishes (clock cycles run faster than animation).
[hero runAction: hulkPunch completion: ^(void){
    [self setUserInteractionEnabled: YES];
}];
person smb    schedule 18.02.2014