How do I get the animation to finish without interruption by repeated touches? (sprite kit Atlas)

StackOverflow https://stackoverflow.com//questions/20009548

  •  20-12-2019
  •  | 
  •  

Вопрос

I am using IOS sprite kit to create an animation(in an .atlas file ) driven by touch. How do I get the animation to finish without interruption by repeated touches? I know I am overlooking something very simple.

-(void) setUpActions {

SKTextureAtlas *atlas = [SKTextureAtlas atlasNamed:@"Wheel"];

SKTexture *Wheel1 = [atlas textureNamed:@"Wheel1.png"];
SKTexture *Wheel2 = [atlas textureNamed:@"Wheel2.png"];
SKTexture *Wheel3 = [atlas textureNamed:@"Wheel3.png"];
SKTexture *Wheel4 = [atlas textureNamed:@"Wheel4.png"];
SKTexture *Wheel5 = [atlas textureNamed:@"Wheel5.png"];
SKTexture *Wheel6 = [atlas textureNamed:@"Wheel6.png"];
SKTexture *Wheel7 = [atlas textureNamed:@"Wheel7.png"];
SKTexture *Wheel8 = [atlas textureNamed:@"Wheel8.png"];
SKTexture *Wheel9 = [atlas textureNamed:@"Wheel9.png"];

NSArray *atlasTexture = @[Wheel1, Wheel2, Wheel3, Wheel4, Wheel5, Wheel6, Wheel7, Wheel8, Wheel9];

SKAction* atlasAnimation = [SKAction animateWithTextures:atlasTexture timePerFrame:0.1];

   SKAction *resetTexture = [SKAction setTexture:[SKTexture textureWithImageNamed:@"Wheel1.png"] ];

runAnimation = [SKAction sequence:@[atlasAnimation,resetTexture]];

}

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

    SKSpriteNode* Wheel = (SKSpriteNode*)[self childNodeWithName:@"Wheel"];
    [Wheel runAction:runAnimation];

   if (_tapCount < 1) {

      //How do I cancel the touches until the animation is complete?
       NSLog(@"STOP touches???");
   }
}
Это было полезно?

Решение

You can do it by adding two more actions to your sequence:

-(void) setUpActions {

    SKTextureAtlas *atlas = [SKTextureAtlas atlasNamed:@"Wheel"];

    // build atlasTexture array dynamically

    NSMutableArray *atlasTexture = [NSMutableArray array];

    int totalWheelImages = atlas.textureNames.count;

    for (int i=1; i <=totalWheelImages; i++) {
        NSString *textureName = [NSString stringWithFormat:@"Wheel%d", i];

        SKTexture *temp = [atlas textureNamed:textureName];

        [atlasTexture addObject:temp];

    }

    // SKAction to stop user interaction

    SKAction *start = [SKAction runBlock:^{

        [self setUserInteractionEnabled:FALSE];

        }];

    SKAction* atlasAnimation = [SKAction animateWithTextures:atlasTexture timePerFrame:0.1];

    SKAction *resetTexture = [SKAction setTexture:[SKTexture textureWithImageNamed:@"Wheel1.png"] ];

    // SKAction to restart user interaction

    SKAction *end = [SKAction runBlock:^{

        [self setUserInteractionEnabled:TRUE];

        }];

    runAnimation = [SKAction sequence:@[start, atlasAnimation, resetTexture, end]];

}

Другие советы

First there is an easier way to add textures:

    NSMutableArray *animations = [[NSMutableArray alloc] init];

    for (int i = 0; i < [atlas.textureNames count]; i++) {
    NSString *temp = [NSString stringWithFormat:@"Wheel%d.png", i + 1]; // name your animations from zero to avoid adding 1 here
    SKTexture *texture = [atlas textureNamed:temp];
    [animations addObject:texture];
}

Regarding your question:

Change your animation method to this:

SKAction* atlasAnimation = [SKAction animateWithTextures:atlasTexture timePerFrame:0.1 withKey:"wheelAnimation"];

You should probably call animation start from some other method. Then in touch method you can check

 if ([Wheel actionForKey:@"wheelAnimation"]) {
    return;
    }

This will drop out from touches method without executing code after return statement.

Or in your code:

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

     SKSpriteNode* Wheel = (SKSpriteNode*)[self childNodeWithName:@"Wheel"];

    if (![Wheel actionForKey:@"wheelAnimation"]) { // everything in this block will not trigger if it finds animation
        [Wheel runAction:runAnimation];

       if (_tapCount < 1) {

          //How do I cancel the touches until the animation is complete?
           NSLog(@"STOP touches???");
       }
     }
   }

Also note that touches actually start in touchesBegin method, so you are better of putting that code in there.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top