Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Endless Scrolling Background in SpriteKit

I am attempting to make a side scrolling game using Apple's SpriteKit. When wanting to make a endless scrolling background I came across this answer.

After implementing the solution it does appear to work although it drops my FPS significantly. This is probably due to the fact that the images positions are being recalculated on every frame.

I feel like it would be much better if I could use one or more SKAction calls to take care of this animation for me but I'm not certain how to implement it.

Thoughts?

The code I have so far in my scene class (this only animates the background across the screen once though)

- (void)addBackgroundTileAtPoint:(CGPoint)point {

    SKSpriteNode *bg = [SKSpriteNode spriteNodeWithImageNamed:@"background"];
    bg.anchorPoint = CGPointZero;
    bg.position = point;
    bg.name = @"background";
    bg.zPosition = -99;
    [self addChild:bg];

    SKAction *sequence = [SKAction sequence:@[
        [SKAction moveByX:-(bg.size.width * 2) y:0 duration:10],
        [SKAction removeFromParent]
    ]];
    [bg runAction: sequence];
}
like image 310
Kyle Decot Avatar asked Feb 11 '14 13:02

Kyle Decot


2 Answers

I did a small component called SKScrollingNode for that particular need in my last open source project : SprityBird.

FPS was not an issue even with 3 or 4 layers (for parallax), but you may need to try it yourself.

To use it you just have to add it like any other node and giving it a scrollingSpeed likeso :

back = [SKScrollingNode scrollingNodeWithImageNamed:@"back" inContainerWidth:WIDTH(self)];
[back setScrollingSpeed:BACK_SCROLLING_SPEED];
[self addChild:back];

SKScrollingNode.h

@interface SKScrollingNode : SKSpriteNode

@property (nonatomic) CGFloat scrollingSpeed;

+ (id) scrollingNodeWithImageNamed:(NSString *)name inContainerWidth:(float) width;
- (void) update:(NSTimeInterval)currentTime;

@end

SKScrollingNode.m

@implementation SKScrollingNode

+ (id) scrollingNodeWithImageNamed:(NSString *)name inContainerWidth:(float) width
{
    UIImage * image = [UIImage imageNamed:name];

    SKScrollingNode * realNode = [SKScrollingNode spriteNodeWithColor:[UIColor clearColor] size:CGSizeMake(width, image.size.height)];
    realNode.scrollingSpeed = 1;

    float total = 0;
    while(total<(width + image.size.width)){
        SKSpriteNode * child = [SKSpriteNode spriteNodeWithImageNamed:name ];
        [child setAnchorPoint:CGPointZero];
        [child setPosition:CGPointMake(total, 0)];
        [realNode addChild:child];
        total+=child.size.width;
    }

    return realNode;
}

- (void) update:(NSTimeInterval)currentTime
{
    [self.children enumerateObjectsUsingBlock:^(SKSpriteNode * child, NSUInteger idx, BOOL *stop) {
        child.position = CGPointMake(child.position.x-self.scrollingSpeed, child.position.y);
        if (child.position.x <= -child.size.width){
            float delta = child.position.x+child.size.width;
            child.position = CGPointMake(child.size.width*(self.children.count-1)+delta, child.position.y);
        }
    }];
}   
@end
like image 105
Kirualex Avatar answered Oct 31 '22 14:10

Kirualex


I've been working on a library for an infinite tile scroller, you can easily use it to create a scrolling background. Take a look at it:

RPTileScroller

I made an effort to make it the most efficient possible, but I am not a game developer. I tried it with my iPhone 5 with random colors tiles of 10x10 pixels, and is running on a solid 60 fps.

like image 1
JP Illanes Avatar answered Oct 31 '22 14:10

JP Illanes