Shalin Shah
Shalin Shah

Reputation: 8183

Scrolling background image cut in half - cocos2d

I'm making a game that has a background image that was too big for the iphone's to render. So I had to cut it in half. Since my background is scrolling horizontally (like in JetPack Joyride), I want to make it so that the halves come together to make it look like one image. So what I tried to do was, position the first half of the image on the far left of the screen, and then I tried to position the second one on the edge of the 1st one. This is what I tried so far.

in the init:

        numStripes = 1;

        for (NSUInteger i = 0; i < numStripes; i++)
        {
        CCSprite *sprite = [CCSprite spriteWithFile:@"bg0.png"];
        CCSprite *sprite2 = [CCSprite spriteWithFile:@"bg1.png"];

        sprite.anchorPoint = CGPointMake(0, 0.5f);
        sprite.position = CGPointMake(0, screenSize.height / 2);

        sprite2.anchorPoint = CGPointMake(0, 0.5f);
        sprite2.position = CGPointMake(sprite.position.x + sprite.contentSize.width, screenSize.height / 2);

        [backgroundNode addChild:sprite z:i tag:i];
        [backgroundNode addChild:sprite2 z:i tag:i];
        }

        // endless scrolling
        for (NSUInteger i = 0; i < numStripes; i++)
        {
        CCSprite *sprite = [CCSprite spriteWithFile:@"bg0.png"];
        CCSprite *sprite2 = [CCSprite spriteWithFile:@"bg1.png"];
        sprite.anchorPoint = CGPointMake(0, 0.5f);
        sprite2.anchorPoint = CGPointMake(0, 0.5f);
        sprite.position = CGPointMake(sprite.contentSize.width + sprite2.contentSize.width - 1, screenSize.height / 2);
        sprite2.position = CGPointMake(sprite.contentSize.width * 2.0f + sprite2.contentSize.width - 1.0f, screenSize.height / 2);

        [backgroundNode addChild:sprite z:i tag:i + 2];
        [backgroundNode addChild:sprite2 z:i tag:i + 2];
        }

        speedFactors = [[CCArray alloc] initWithCapacity:numStripes];
        [speedFactors addObject:[NSNumber numberWithFloat:1.0f]];
        NSAssert([speedFactors count] == numStripes, @"speedFactors count does not match numStripes!");

This could be the problem:

-(void) dealloc
{
#ifndef KK_ARC_ENABLED
    [speedFactors release];
    [super dealloc];
#endif // KK_ARC_ENABLED
}

-(void) update:(ccTime)delta
{
    if (([[GameMechanics sharedGameMechanics] gameState] == GameStateRunning) || [[GameMechanics sharedGameMechanics] gameState] == GameStateMenu)
    {
        [self updateRunning:delta];
    }
}

- (void) updateRunning:(ccTime)delta
{
    // read current scroll Speed
    scrollSpeed = [[GameMechanics sharedGameMechanics] backGroundScrollSpeedX];

    CCSprite* sprite;
    // we use a c-array since it is faster on iteration
    CCARRAY_FOREACH([backgroundNode children], sprite)
    {
        // retrieve the scrollspeed factor for the current sprite
        NSNumber* factor = [speedFactors objectAtIndex:sprite.zOrder];

        // move the background layer
        CGPoint pos = sprite.position;
        pos.x -= scrollSpeed * [factor floatValue] * delta;

        // when a layer is off screen on the left side, move it to the right end of the screen
        if (pos.x < -sprite.contentSize.width)
        {
            pos.x += (sprite.contentSize.width * 4) - 1;
        }

        sprite.position = pos;
    }
}

This doesn't seem to work and I'm getting weird results... Any help is appreciated. Thanks!

Upvotes: 0

Views: 481

Answers (1)

Joseph Chen
Joseph Chen

Reputation: 1530

Could it be this:

sprite.position = CGPointMake(0, screenSize.height / 2);
sprite2.position = CGPointMake(sprite.position.x*1.5, screenSize.height / 2);

sprite2's initial x value is getting set to 0. What you probably want is:

sprite2.position = CGPointMake(sprite.position.x + sprite.contentSize.width, screenSize.height / 2);

There's another problem here:

sprite.position = CGPointMake(sprite.contentSize.width - 1)*2, screenSize.height / 2);
                sprite2.anchorPoint = CGPointMake(0, 0.5f);
sprite2.position = CGPointMake((sprite2.contentSize.width - 1)*2, screenSize.height / 2);

It should probably be:

sprite.position = CGPointMake(sprite.contentSize.width + sprite2.contentSize.width - 1, screenSize.height / 2);
sprite2.position = CGPointMake(sprite.contentSize.width * 2.0f + sprite2.contentSize.width - 1.0f, screenSize.height / 2);

You probably also have an issue setting the same tag to two different sprites. You're setting tags for both sprite and its copy to 0, and tags for both sprite2 and its copy to 1. You should set the tag for sprite to 0, sprite2 to 1, sprite (copy) to 2, and sprite2 (copy) to 3.

In the second for loop:

[backgroundNode addChild:sprite z:i tag:i + 2];
[backgroundNode addChild:sprite2 z:i tag:i + 2];

Updated:

In your -updateRunning: method change this:

pos.x += (sprite.contentSize.width * 2) - 2;

to this:

pos.x += (sprite.contentSize.width * 4) - 1;

Because you have four sprites like this:

[1][2][3][4]

when [1] moves offscreen you need to move [1] all the way behind [4] so that they're like this

[2][3][4][1]

which is why you need the move [1] four lengths to the right and not two lengths to the right.

Updated:

It doesn't look like you have enough speedFactors. It looks like you are adding one value to the speedFactors array, but later trying to get two of them. You don't need different speed factors until you add parallax scrolling, so for now change:

NSNumber* factor = [speedFactors objectAtIndex:sprite.zOrder];

to

NSNumber* factor = [NSNumber numberWithFloat:1.0f];

Upvotes: 1

Related Questions