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]];
Related
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)
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...
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];
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]]];
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];