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];
}
Related
I am making a game with sprite kit and objective c. Currently I am trying to make my background scroll infinitely. I cannot seem to make this work. Here is my code:
SKAction method
-(void) setUpActions {
SKAction* move = [SKAction moveByX:-landscape.frame.size.width * 2 y:0 duration:2.0];
SKAction* reset = [SKAction moveByX:landscape.frame.size.width * 2 y:0 duration:0.0];
SKAction* moveInfinitely = [SKAction sequence:#[move, reset]];
//background and log Moving Actions
moveOver = [SKAction repeatActionForever:moveInfinitely];
}
SKAction calling method
-(void) runTheAction {
[landscape runAction:moveOver];
}
When I run the app nothing shows up on my screen.
Create two background sprites.
// create 2 background sprites
bg1 = [SKSpriteNode spriteNodeWithImageNamed:#"bg1"];
bg1.anchorPoint = CGPointZero;
bg1.position = CGPointMake(0, 0);
[self addChild:bg1];
bg2 = [SKSpriteNode spriteNodeWithImageNamed:#"bg2"];
bg2.anchorPoint = CGPointZero;
bg2.position = CGPointMake(bg1.size.width-1, 0);
[self addChild:bg2];
Then in update method:
bg1.position = CGPointMake(bg1.position.x-4, bg1.position.y);
bg2.position = CGPointMake(bg2.position.x-4, bg2.position.y);
if (bg1.position.x < -bg1.size.width){
bg1.position = CGPointMake(bg2.position.x + bg2.size.width, bg1.position.y);
}
if (bg2.position.x < -bg2.size.width) {
bg2.position = CGPointMake(bg1.position.x + bg1.size.width, bg2.position.y);
}
This should be pretty straightforward
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 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];
}
I have this code as my background as a moving background:
SKTexture* bgTexture = [SKTexture textureWithImageNamed:#"nightbackground"];
bgTexture.filteringMode = SKTextureFilteringNearest;
SKAction* movebgSprite = [SKAction moveByX:-bgTexture.size.width*2 y:0 duration:0.1 * bgTexture.size.width*2];
SKAction* resetbgSprite = [SKAction moveByX:bgTexture.size.width*2 y:0 duration:0];
SKAction* movebgSpritesForever = [SKAction repeatActionForever:[SKAction sequence:#[movebgSprite, resetbgSprite]]];
for( int i = 0; i < 2 + self.frame.size.width / ( bgTexture.size.width * 2 ); ++i ) {
SKSpriteNode* sprite = [SKSpriteNode spriteNodeWithTexture:bgTexture];
sprite.position = CGPointMake(self.size.width/2, self.size.height/2);
[sprite runAction:movebgSpritesForever];
[self addChild:sprite];
And I add this code to have to respawning pipes:
SKTexture* _pipeTexture1 = [SKTexture textureWithImageNamed:#"Pipe1"];
_pipeTexture1.filteringMode = SKTextureFilteringNearest;
SKTexture* _pipeTexture2 = [SKTexture textureWithImageNamed:#"Pipe2"];
_pipeTexture2.filteringMode = SKTextureFilteringNearest;
SKNode* pipePair = [SKNode node];
pipePair.position = CGPointMake( self.frame.size.width + _pipeTexture1.size.width * 2, 0 );
pipePair.zPosition = -10;
CGFloat y = arc4random() % (NSInteger)( self.frame.size.height / 3 );
SKSpriteNode* pipe1 = [SKSpriteNode spriteNodeWithTexture:_pipeTexture1];
[pipe1 setScale:2];
pipe1.position = CGPointMake( 0, y );
pipe1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:pipe1.size];
pipe1.physicsBody.dynamic = NO; [pipePair addChild:pipe1];
SKSpriteNode* pipe2 = [SKSpriteNode spriteNodeWithTexture:_pipeTexture2];
[pipe2 setScale:2];
pipe2.position = CGPointMake( 0, y + pipe1.size.height + kVerticalPipeGap );
pipe2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:pipe2.size];
pipe2.physicsBody.dynamic = NO; [pipePair addChild:pipe2];
SKAction* movePipes = [SKAction repeatActionForever:[SKAction moveByX:-1 y:0 duration:0.02]];
[pipePair runAction:movePipes];
[self addChild:pipePair];
For some reason when I add this code the two pipes dont appear but something does push my character back. It just does not show up. If I remove the background code, the pipes appear and it works again? What is the problem.
It's probably this:
pipePair.zPosition = -10;
When adding your background sprites you don't specify any zPosition meaning they'll get the default 0.0 which is visible in front of anything at -10. Your character is pushed back because the physics-bodies are still interacting with each other even if the sprite is covered visually.
pipePair.zPosition = 10; // (or any other positive value)
ought to fix your problem.
This is my code to make my background repeat, just one background and it should be repeating forever:
SKTexture* bgTexture = [SKTexture textureWithImageNamed:#"nightbackground"];
bgTexture.filteringMode = SKTextureFilteringNearest;
SKAction* movebgSprite = [SKAction moveByX:-bgTexture.size.width*2 y:0 duration:0.1 * bgTexture.size.width*2];
SKAction* resetbgSprite = [SKAction moveByX:bgTexture.size.width*2 y:0 duration:0];
SKAction* movebgSpritesForever = [SKAction repeatActionForever:[SKAction sequence:#[movebgSprite, resetbgSprite]]];
for( int i = 0; i < 2 + self.frame.size.width / ( bgTexture.size.width * 2 ); ++i ) {
SKSpriteNode* sprite = [SKSpriteNode spriteNodeWithTexture:bgTexture];
[sprite setScale:1.0];
sprite.zPosition = -20;
sprite.position = CGPointMake(self.size.width/2, self.size.height/2);
[sprite runAction:movebgSpritesForever];
[self addChild:sprite];
But it does not repeat forever, it stops after a while. What might be wrong with it?
This case will work in landscape orientation and have the view repeat scrolling infinitely to the left (-x direction). You create two instances of the background SKSPriteNode and place them next to each other. When the first one scrolls completely off the left side of the screen, it is placed to the right of the second background sprite node.
in didMoveToView:
for (int i = 0; i < 2; i++) {
SKSpriteNode *bg = [SKSpriteNode spriteNodeWithImageNamed:#"background"];
bg.anchorPoint = CGPointZero;
bg.position = CGPointMake(i * bg.size.width, 0);
bg.name = #"starBackground";
[self addChild:bg];
}
in the update: loop
[self enumerateChildNodesWithName:#"background" usingBlock:^(SKNode *node, BOOL *stop) {
SKSpriteNode *bg = (SKSpriteNode *)node;
bg.position = CGPointMake(bg.position.x - 1.5, bg.position.y);
if (bg.position.x <= -bg.size.width) {
bg.position = CGPointMake(bg.position.x + bg.size.width * 2, bg.position.y);
}
}];