SKAction not working properly - ios

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];

Related

I want to move my SKLabelNode object down to up and up to down alternatively

I have designed a SKLabelNode object. I wanna to let it move start from down to up and then up to down whenever I touch the SKLabelNode object. First it will move from down to up and then it is required to move from up to down. Here is the code.. Anyone can help !
- (void)touchesBegan:(NSSet *) touches withEvent:(UIEvent *)event
{
SKNode * helloNode=[self childNodeWithName:#"helloNode"];
if ([helloNode.name isEqualToString:#"helloNode"])
{
helloNode.name = #"";
SKAction *moveUp = [SKAction moveByX: 0 y: 100.0 duration: 0.5];
SKAction *pause = [SKAction waitForDuration: 0.5];
SKAction *fadeAway = [SKAction fadeOutWithDuration: 0.25];
SKAction *fadeIn = [SKAction fadeInWithDuration:0.25];
SKAction *moveSequence = [SKAction sequence:#[moveUp, pause, fadeAway,fadeIn]];
[helloNode runAction: moveSequence];
}
else
{
helloNode.name=#"helloNode";
SKAction *moveUp = [SKAction moveByX: 0 y: 50.0 duration: 0.5];
SKAction *pause = [SKAction waitForDuration: 0.5];
SKAction *fadeAway = [SKAction fadeOutWithDuration: 0.25];
SKAction *fadeIn = [SKAction fadeInWithDuration:0.25];
SKAction *moveSequence = [SKAction sequence:#[moveUp, pause, fadeAway,fadeIn]];
[helloNode runAction: moveSequence];
}
}

Spawning sprites not working

Ok I'm fairly new to coding with sprite kit so I don't know too much. I'm trying to make 5 bricks spawn above the scene and then slide down into the scene every 5 seconds. I thought this code would work but it does absolutely nothing to my scene.
I have another method that has bricks already loaded into the scene and that works so I don't think that would affect this much but not really sure.
-(void) spawnMoreBricks:(CGSize)size {
for (int i = 0; i < 5; i++) {
SKSpriteNode *brick = [SKSpriteNode spriteNodeWithImageNamed:#"brick"];
//resize bricks
brick.size = CGSizeMake(60, 30);
//position it
brick.position = CGPointMake(self.size.width/2, self.size.height);
SKAction *wait = [SKAction waitForDuration:5];
SKAction *spawn = [SKAction scaleTo:1 duration:0];
SKAction *move = [SKAction moveByX:0 y:-80 duration:3];
SKAction *spawnSequence = [SKAction sequence:#[wait, spawn, move]];
[self runAction:spawnSequence];
}
}
SKAction *wait = [SKAction waitForDuration:5];
SKAction *spawn = [SKAction runBlock:^{[self addChild: brick];
SKAction *move = [SKAction moveByX:0 y:-80 duration:3];
[brick runAction: move];
}];
SKAction *spawnSequence = [SKAction sequence:#[wait, spawn]];
[self runAction:spawnSequence];
Here is a modified set of actions to use. The problem was that you were running all the actions on the scene itself. The code provided runs a sequence on the scene that waits 5 seconds (acting as the delay), and then runs a spawn action. runBlock allows us to add the brick to the scene, create the move action, and apply that action to the brick (not the scene)

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]];

How can I tell an SKTextureAtlas to stop animating and remove the object?

How can I tell the walk cycle to continue animating until an NSNumber with bool flag stops it?
And also remove the SKSpriteNode with the SKTexture from the stage?
SKSpriteNode *walk = [SKSpriteNode spriteNodeWithTexture:[_walkTextures objectAtIndex:0]];
walk.zPosition = 100;
walk.scale = spliffScale;
walk.position = location;
[self addChild:walk];
SKAction *walkAction = [SKAction animateWithTextures:_walkTextures timePerFrame:0.03];
SKAction *remove = [SKAction removeFromParent];
[walk runAction:[SKAction sequence:#[walkAction, walkAction, remove]]];

How to create custom SKActions?

Hello all I want to do is create a SKAction which does something similar to wheelRight.physicsBody.velocity = CGVectorMake(0, 1000); to a physics object.
Use SKAction runBlock: method:
SKAction *changeVelocity = [SKAction runBlock:^{
wheelRight.physicsBody.velocity = CGVectorMake(0, 1000);
}];
SKAction sequence = [SKAction sequence:#[..., changeVelocity, ..., ...]];
[wheelRight runAction:sequence];

Resources