简体   繁体   中英

How to run actions on previously generated SpriteNodes in SpriteKit

I am making an app, where objects fall from the top of the screen. These objects are spriteNodes and are generated with the method - (void)generateNodes . When you tap on the screen a touchPointer node is created and detects if you touch the spriteNode. This is done with a didBeginContact method. I have the detection of the touch, however, when I try to add a death animation to the objects, there is a problem. If I tap an object and it begins its death animation, then I tap another object that has been newly generated. The death animation from the previous continues with the newly generated object. So, instead of starting the newly generated object's own death animation – basically fading out, it will continue the death animation from the previous object as that object finishes.

Example:

firstObject alpha when tapped 0.5 -> 0

== second object is tapped whilst firstObject is still running the death animation ==

secondObject alpha when tapped 0.2 -> 0

This is because when I tap the secondObject it continues the animation of the first object. I want to it to be where the secondObject starts its own animation, where it should start from an alpha of 0.5

Code of didBeginContact

if([contact.bodyA.node.name isEqualToString:@"object"] && [contact.bodyB.node.name isEqualToString:@"touchPointer"]){
        //Object Death Animation Actions
        int randObjectMovement = (arc4random()%2) + 1;

        touchedObject = [objects objectAtIndex:0];

        touchedObject.alpha = 0.5;

        if(randObjectMovement == 1){
            touchedObject.physicsBody.velocity = CGVectorMake(0, 0);
            [touchedObject.physicsBody applyImpulse:CGVectorMake(-10, 18)];
            NSLog(@"Impluse completed");
        }else{
            touchedObject.physicsBody.velocity = CGVectorMake(0, 0);
            [touchedObject.physicsBody applyImpulse:CGVectorMake(10, 18)];
            NSLog(@"Impluse completed");

        }

        objectFadeOut = [SKAction fadeAlphaTo:0 duration:0.75];
        objectRemove = [SKAction removeFromParent];
        objectDeathRotation = [SKAction rotateByAngle:M_PI*2 duration:3];

        [touchedObject runAction:objectDeathRotation completion:^{
            NSLog(@"objectDeathRotation completed");
        }];
        [touchedObject runAction:objectFadeOut completion:^{
            NSLog(@"objectFadeOut and Removal completed");
            [touchedObject runAction:objectRemove];
        }];
    }

Code of generateObjects

- (void)generateObject{
    //Object Texture delcaration
    if ([self generateObjectType] <= 100 && [self generateObjectType] > 20){
        objectTexture = [SKTexture textureWithImageNamed:@"Object_N"];
    }else if([self generateObjectType] <= 20 && [self generateObjectType] > 5){
        objectTexture = [SKTexture textureWithImageNamed:@"Object_B"];
    }else{
        objectTexture = [SKTexture textureWithImageNamed:@"Object_G"];
    }
    objectTexture.filteringMode = SKTextureFilteringNearest;

    //Object Actions
    objectRotation = [SKAction rotateByAngle:M_PI*2 duration:1];

    //Object Sprite declaration
    objectSprite = [SKSpriteNode spriteNodeWithTexture:objectTexture];
    objectSprite.position = [self generateObjectPosition];
    objectSprite.zPosition = 3;
    objectSprite.size = CGSizeMake(30, 30);
    [objectSprite runAction:objectRotation];

    objectSprite.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:objectSprite.size];
    objectSprite.name = @"object";
    objectSprite.physicsBody.categoryBitMask = objectCategory;
    objectSprite.physicsBody.collisionBitMask = groundCategory;
    objectSprite.physicsBody.contactTestBitMask = groundCategory | touchCategory;

    [objects insertObject:objectSprite atIndex:0];
    [self addChild:objectSprite];

}

By the way, objects is an NSMutableArray.

Please help!

Why not just use the node from the contact:

SKSpriteNode *touchedObject = (SKSpriteNode*)contact.bodyA.node;

This gets the node involved in the collision and you can carry out the actions on it, no need for the array.

Update

Use local instances of the actions:

SKAction *objectFadeOutLocal = [SKAction fadeAlphaTo:0 duration:0.75];
SKAction *objectRemoveLocal = [SKAction removeFromParent];
SKAction *objectDeathRotationLocal = [SKAction rotateByAngle:M_PI*2 duration:3];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM