Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Build a Game with Sprite Kit Particle Systems and Keeping Score Extra Credit - Rock Blaster

How do you animate the background, i tried with textures but it lags a lot.

I used 10 textures and the game became lag

Chris Tapia
Chris Tapia
1,684 Points

/Users/Ctaps33/Desktop/Screen Shot 2014-12-27 at 4.57.26 PM.png

So i implemented the code and i got this error in the update method on the line with scroll background: no visible @interface for Background node(the class like SPBackgroundNode) declares the sector scroll background.

additionally, how do i add the asset catalog of backgrounds for the method to scroll through?

Stone Preston
Stone Preston
42,016 Points

you need to make sure you include the scrollBackground method in the .h file of BackgroundNode so that its exposed to other classes. you can add the following line in the interface file:

- (void)scrollBackground ;

as for importing the assets you can just drag them into the catalog. the BackgroundNode class uses the default names and loops over them. you can look at the for loop and see how it accesses the image files:

for (int i = 0; i < 3; i++) {


        NSString *imageName = [NSString stringWithFormat:@"bg-stars_%02d",i];

        SKSpriteNode *bg = [SKSpriteNode spriteNodeWithImageNamed:imageName];
        bg.name = @"bg";

        bg.position = CGPointMake(position.x, i * bg.size.height);

        [background addChild:bg];


    }

the loop above just uses the first 3 images. you can play around with the numbers a bit. the reason I just used the first 3 is because there are breaks in the animation sheet if you use all of them

Chris Tapia
Chris Tapia
1,684 Points

ok. I still got the same error for some reason even after importing to scroll background to header file of gameplay scene. which asset catalog do I put the images in, do I just drag the images to the project?

5 Answers

If you are trying to animate a background those images are pretty big. It takes a lot of RAM up to store an animation like that. What people do is take pieces of the background and animate it but keep the overall background static.

Example could be a shooting start in the background of static space. The shooting start piece is small, so animating it does not take up too much RAM.

The tricky part is tracking all the things you want to animate and when. But that can be done with objects.

Thanks

Stone Preston
Stone Preston
42,016 Points

Can you post your code? I basically just created a sprite node for each image and added each one to a node. then I moved the node down using an action and once one of the background sprites scrolled off the screen I added it back to the top of the background node making a continuous scrolling background. if you are using the background provided in the downloaded assets you may notice a few of them dont actually match up so they dont actually look smooth when run (there are a few spots where you can see where 2 images meet. to get around this I just used the first 3 images in my scrolling background.

Here is my class

//
//  SPBackgroundNode.m
//  Rock Blaster
//
//  Created by Stone  Preston on 7/8/14.
//  Copyright (c) 2014 Stone  Preston. All rights reserved.
//

#import "SPBackgroundNode.h"

@interface SPBackgroundNode ()
@property (nonatomic) NSInteger backgroundCount;
@end

@implementation SPBackgroundNode

+ (instancetype)backgroundNodeAtPosition:(CGPoint)position {

    SPBackgroundNode *background = [self node];
    background.name = @"Background";

    for (int i = 0; i < 3; i++) {


        NSString *imageName = [NSString stringWithFormat:@"bg-stars_%02d",i];

        SKSpriteNode *bg = [SKSpriteNode spriteNodeWithImageNamed:imageName];
        bg.name = @"bg";

        bg.position = CGPointMake(position.x, i * bg.size.height);

        [background addChild:bg];


    }

    background.backgroundCount = background.children.count;


    return  background;
}

- (void)scrollBackground {


    [self enumerateChildNodesWithName:@"bg" usingBlock:^(SKNode *node, BOOL *stop) {

        SKSpriteNode *bg = (SKSpriteNode *)node;
        [bg runAction:[SKAction moveBy:CGVectorMake(0, -15) duration:0]];

        //Checks if bg node is completely scrolled of the screen, if yes then put it at the end of the other node

        if (bg.position.y <= -bg.size.height) {

            bg.position = CGPointMake(bg.position.x , bg.position.y + bg.size.height * self.backgroundCount);

        }
    }];

}

@end
Matthew Dobson
Matthew Dobson
663 Points

This worked great for me. Thanks a bunch Stone!

can you share your rock blaster project with me? i would like to study ur code. thanks

Chris Tapia
Chris Tapia
1,684 Points

Hey preston, what was the subclass of this file?

Chris Tapia
Chris Tapia
1,684 Points

Hey preston, what was the subclass of this file?

Chris Tapia
Chris Tapia
1,684 Points

Ok thanks. I have one more question: how do Implement this into my id(initWithSize) method in my title scene? And is this set to cycle through the backgrounds or do I have to create an array? If so how would i implement that?

Stone Preston
Stone Preston
42,016 Points

Call the backgroundAtPosition class method in your init with size method. As long as you have the images in your project it should work. You don't need to create an area

Chris Tapia
Chris Tapia
1,684 Points

Ok thanks. One more question(this might seem idiotic) but how do I initiate the method? to what object do I link it to?

Stone Preston
Stone Preston
42,016 Points

It's a class method so you don't need an instance to call the method, just use the class name

[SPBackgroundNode backgroundNodeAtPosition...
Chris Tapia
Chris Tapia
1,684 Points

First of all, thank you for helping me cause Im so confused. Still, I don't know how to initiate that. It doesn't make sense :(. I do that and as an example, how would I trigger the star sequence using that

Stone Preston
Stone Preston
42,016 Points

in your initWithSize method you need to have:

-(id)initWithSize:(CGSize)size {

    if (self = [super initWithSize:size]) {

       // ...

        SPBackgroundNode *background = [SPBackgroundNode backgroundNodeAtPosition:CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))];
        [self addChild:background];


        // ...

    }

    return self;
}

then to scroll the background you call the scrollBackground method on your background instance in the update method:

- (void)update:(NSTimeInterval)currentTime {


    SPBackgroundNode *background = (SPBackgroundNode *)[self childNodeWithName:@"Background"];
    [background scrollBackground];
}
Chris Tapia
Chris Tapia
1,684 Points

Ok thanks. So which file do i put the update method in and is the scrollBackground method implemented in the code above?

Chris Tapia
Chris Tapia
1,684 Points

Ok thanks. So which file do i put the update method in and is the scrollBackground method implemented in the code above?

Stone Preston
Stone Preston
42,016 Points

scroll background is an instance method that is implemented in the class thats in my initial post. the update method goes in your games's scene class.

Thanks Stone, i will try the scrollBackground. I just create a simple texture but i'll try that

Chris Tapia
Chris Tapia
1,684 Points

OK Thanks. For my scene class, should it be my title scene or my gameplay scene?

Shaun Kelly
Shaun Kelly
5,648 Points

how do I get the assets ?