removeFromParent after SKAction - ios

I'm trying to remove my shootA SKSpriteNode after the SKAction has been present, but if I do that it seem to trigger before the action.
How can I remove it after it has been presented one time?
This is my code:
SKTexture* shootTexture1 = [SKTexture textureWithImageNamed:#"shoot-b"];
shootTexture1.filteringMode = SKTextureFilteringNearest;
SKTexture* shootTexture2 = [SKTexture textureWithImageNamed:#"shoot-a"];
shootTexture2.filteringMode = SKTextureFilteringNearest;
SKAction* flap = [SKAction repeatAction:[SKAction animateWithTextures:#[shootTexture1, shootTexture2, ] timePerFrame:0.1] count:1];
SKSpriteNode *shootA = [SKSpriteNode spriteNodeWithTexture:shootTexture1];
[shootA setScale:1.0];
shootA.position = CGPointMake(dragon.position.x+40, dragon.position.y-10);
shootA.size = CGSizeMake(shootA.size.width/8, shootA.size.height/8);
[shootA runAction:flap withKey:#"shootGo"];
[self addChild: shootA];

You can change your SKAction to a sequence and then add the removeFromParent to the end -
SKAction* flap = [SKAction sequence:#[
[SKAction repeatAction:[SKAction animateWithTextures:#[shootTexture1, shootTexture2, ] timePerFrame:0.1] count:1],
[SKAction removeFromParent]
]];

Related

SKAction Follow path change start point

In my game i move many skspritenode along the same cgpath by :
[SKAction followPath:APath asOffset:NO orientToPath:YES duration:68]
If i add in scene all my skpritenodes at the same time they overlapping during followpath animation, so i have to add each sprite with some delay... In this way the sprites can't overlap but during the game i have "jittering" every time i had one of this sprite. I use something like this:
SKAction *InsertSpriteAction=[SKAction repeatActionForever:[SKAction sequence:#[[SKAction performSelector:#selector(AddSprite) onTarget:self],[SKAction waitForDuration:0.5]]]];
and to add the sprite:
-(void)AddSprite{
if (NumberofSprite<50) {
SKSpriteNode *Sprite=[SKSpriteNode spriteNodeWithImageNamed:#"sprite.png"];
Sprite.size=CGSizeMake(8, 8);
Sprite.position=CGPointMake(1320, 570);
[_worldNode addChild:Sprite];
NSMutableArray *textures = [NSMutableArray arrayWithCapacity:10];
for (int i = 1; i < 10; i++) {
NSString *textureName =
[NSString stringWithFormat:#"sprite%i", i];
SKTexture *texture =[SKTexture textureWithImageNamed:textureName];
[textures addObject:texture];
}
SKAction *spriteAnimation = [SKAction animateWithTextures:textures timePerFrame:0.2];
SKAction *repeat = [SKAction repeatActionForever:spriteAnimation];
[Sprite runAction:repeat];
[Sprite runAction: [SKAction repeatActionForever:[SKAction followPath:APath asOffset:NO orientToPath:YES duration:68]]];
NumberofSprite++;
}
else{
[self removeActionForKey:#"addingsprites"];
}
}
How i can start my sprites at different point along the path? With many startpoint in the same path i can add all my sprite at once during level loading and start a follow path without overlappings...

SKAction not working properly

I have a sequence of SKActions that I would like to play but they do not play properly. The eye only closes and never opens again. I have no clue why this is occurring but maybe you do! Help is appreciated, thank you.
-(void)blink {
SKAction *delay = [SKAction waitForDuration:3];
SKAction *blinkEye = [SKAction resizeToHeight:1 duration:.2];
SKAction *delay2 = [SKAction waitForDuration:.5];
SKAction *openEye = [SKAction resizeToHeight:3 duration:.2];
SKAction *group1 = [SKAction group:#[delay,blinkEye]];
SKAction *group2 = [SKAction group:#[delay2,openEye]];
SKAction *all = [SKAction sequence:#[group1,group2]];
SKAction *repeat = [SKAction repeatActionForever:all];
[self runAction:repeat];
}
In MyScene.m
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
Player *player = (Player *)[self childNodeWithName:#"player"];
Player *lefteye = (Player *)[player childNodeWithName:#"leye"];
Player *righteye = (Player *)[player childNodeWithName:#"reye"];
[lefteye blink];
[righteye blink];
}
There's no need for grouping, it's causing the problem.
SKAction *delay = [SKAction waitForDuration:3];
SKAction *blinkEye = [SKAction resizeToHeight:1 duration:.2];
SKAction *delay2 = [SKAction waitForDuration:.5];
SKAction *openEye = [SKAction resizeToHeight:3 duration:.2];
SKAction *all = [SKAction sequence:#[delay,blinkEye, delay2,openEye]]];
And letting blink the eye on every frame update can't work. This function is called up to 60 times a second.
Instead do it like this on creation of the eye object:
SKAction *delay = [SKAction waitForDuration:3];
SKAction *blinkEye = [SKAction resizeToHeight:1 duration:.2];
SKAction *delay2 = [SKAction waitForDuration:.5];
SKAction *openEye = [SKAction resizeToHeight:3 duration:.2];
SKAction *all = [SKAction sequence:#[delay,blinkEye, delay2,openEye]]];
//create the lefteye object
lefteye = [[Eye alloc] init...];
//create the righteye object
righteye = [[Eye alloc] init...];
[lefteye repeatActionForever:all];

Implement my enemy class to the Game Scene

I'm still fairly new to programming and what I tried to do is the following: So I separated my Enemies from my game scene to a different class.
In the Enemy class.m file I declared 6 methods. Every method represents a new level, which will get called from the game scene.
So in the methods I declare the sprite's image, path, shooting particle type, etc..
Here's an example of the level 1 method in the EnemyClass.m file:
+(void)enemiesLevel1
{
EnemyName = #"enemy1";
SKSpriteNode* enemy = [SKSpriteNode spriteNodeWithImageNamed:EnemyName];
pathSpeed = 3;
CGPathRef path = CGPathCreateWithEllipseInRect(CGRectMake(0,0,400,400), NULL);
SKAction *followTrack = [SKAction followPath:path
asOffset:NO
orientToPath:YES
duration:pathSpeed];
SKAction *forever = [SKAction repeatActionForever:followTrack];
SKAction *addEnemy = [SKAction runBlock:^{
[GameScene addChild: enemy];
}];
SKAction *enemySequence = [SKAction sequence:#[addEnemy, forever]];
[GameScene runAction: enemySequence];
}
However, Xcode is states two issues:
No known class method for selector "addChild"
and
No known class method for selector "runAction"
I'm calling the method from GameScene.m with:
[EnemyClass enemiesLevel1]
It may seem like a dumb question, but I am still new and I would greatly appreciate any help!
The problem is, you should create instance of EnemyClasss in your GameScene and then use it; your code should look like this;
In EnemyClass.m:
-(void)enemiesLevel1
{
EnemyName = #"enemy1";
SKSpriteNode* enemy = [SKSpriteNode spriteNodeWithImageNamed:EnemyName];
pathSpeed = 3;
CGPathRef path = CGPathCreateWithEllipseInRect(CGRectMake(0,0,400,400), NULL);
SKAction *followTrack = [SKAction followPath:path
asOffset:NO
orientToPath:YES
duration:pathSpeed];
SKAction *forever = [SKAction repeatActionForever:followTrack];
SKAction *addEnemy = [SKAction runBlock:^{
[self addChild: enemy];
}];
SKAction *enemySequence = [SKAction sequence:#[addEnemy, forever]];
[self runAction: enemySequence];
}
In GameScene.m:
EnemyClass *enemy= [[EnemyClass alloc] initWithSize:self.size];
and then you can use:
[self addChild: [enemy enemiesLevel1]];

Pause or end and SKAction

I have an SKSpriteNode which is running an actionForever. This SKSpriteNode is changing the object on a collision the problem is that because the other action is running forever it will change back to that. Is there a way to stop an action?
SKTexture* groundOverlay = [SKTexture textureWithImageNamed:#"layer-5"];
groundOverlay.filteringMode = SKTextureFilteringNearest;
SKAction* moveOverlaySprite = [SKAction moveByX:-groundOverlay.size.width*2 y:0 duration:0.01 * groundOverlay.size.width*2];
SKAction* resetOverlaySprite = [SKAction moveByX:groundOverlay.size.width*2 y:0 duration:0];
moveOverlaySpritesForever = [SKAction repeatActionForever:[SKAction sequence:#[moveOverlaySprite, resetOverlaySprite]]];
for( int i = 0; i < 2 + self.frame.size.width; ++i ) {
// Create the sprite
sprite1 = [SKSpriteNode spriteNodeWithTexture:groundOverlay];
[sprite1 setScale:1.0];
sprite1.position = CGPointMake(i * sprite1.size.width, sprite1.size.height / 2);
[sprite1 runAction:moveOverlaySpritesForever withKey:#"bg2"];
[self addChild:sprite1];
}

removeAllActions sprite kit moving background

I've created this SKSpriteNode which is the moving background in the background. What i would like to is being able to stop all actions which i've done by
[self removeAllAction]
Which works, but not on the moving background why? and how can i obtain this
SKTexture* groundTexture = [SKTexture textureWithImageNamed:#"layer-1"];
groundTexture.filteringMode = SKTextureFilteringNearest;
SKAction* moveGroundSprite = [SKAction moveByX:-groundTexture.size.width*2 y:0 duration:0.02 * groundTexture.size.width*2];
SKAction* resetGroundSprite = [SKAction moveByX:groundTexture.size.width*2 y:0 duration:0];
moveGroundSpritesForever = [SKAction repeatActionForever:[SKAction sequence:#[moveGroundSprite, resetGroundSprite]]];
for( int i = 0; i < 2 + self.frame.size.width; ++i ) {
// Create the sprite
sprite = [SKSpriteNode spriteNodeWithTexture:groundTexture];
[sprite setScale:1.0];
sprite.position = CGPointMake(i * sprite.size.width, sprite.size.height / 2);
[sprite runAction:moveGroundSpritesForever withKey:#"bg"];
[self addChild:sprite];
}

Resources