3
votes

I´ve seen tons of people having this problem but I can´t seem to find a solution for my case. Like the title explains I have a scrolling background, using two sprites containing the same image. I´ve set the height to 321 (321x480) believing that would fix the problem, boy, it did not.

Well, this is my setup in the init:

 background = [CCSprite spriteWithFile:@"level1BG.png"];
        background.position = ccp(background.contentSize.width/2, background.contentSize.height/2);
        [self addChild:background];

        background2 = [CCSprite spriteWithFile:@"level1BG.png"];
        background2.position = ccp(background2.contentSize.width/2, -background2.contentSize.height/2);
        [self addChild:background2];

Nothing fancy here, just an setup.

And this is my schedule scroll(with has a ccTime parameter of course): Oh, the background scrolls upwards, increasing the y-value.

-(void)scroll:(ccTime)dt{
    background.position = ccp(background.position.x, background.position.y + GAME_SPEED*dt);
    background2.position = ccp(background2.position.x, background2.position.y + GAME_SPEED*dt);

    if(background.position.y >= background.contentSize.width){
        background.position = ccp(background.position.x, -background.contentSize.height/2 + 1);
    }else if(background2.position.y >= background2.contentSize.width){
        background2.position = ccp(background2.position.x, -background2.contentSize.height/2 + 1);

    }
}

GAME_SPEED is defined to 50.0. I´ve added the "+ 1" believing THAT would fix the problem, wrong again though!

So, to the question, does anyone know a way to remove the gap in this case? Would be forever grateful!

Regards

2
Did you try with actions? I do something similar with move actions and works without problems. - Sebastián Castro
as @Setrio, i have no issues with this. Did you stop the scroll with the seam mid-screen to see if it exists in the absence of motion ? - YvesLeBorg
@Setrio Hmm, I not that good with actions actually, could you paste some sample code? It is the same principle? - Alouette
I've had this problem before and never managed to fix it. I moved my sprites using both actions and position updating - none worked. - Voldemort

2 Answers

2
votes

Here is some old code that i use to make clouds appears over an scene

Clouds.h

#import <Foundation/Foundation.h>
#import "cocos2d.h"

@interface Clouds : CCLayer {
    CCSprite *first;
    CCSprite *second;
    float firstX0;
    float secondX0;
    float firstXf;
    float secondXf;
    float height;
    float firstWidth;
    float secondWidth;
    float Yvalue;
    float duration;
    id moveFirstDone;
    id moveSecondDone;  
}

@end

Clouds.m

#import "Clouds.h"

@implementation Clouds
-(id) init{
    if( (self=[super init] )) {
        first = [CCSprite spriteWithFile:@"clouds_1.png"];
        firstWidth = first.contentSize.width;
        height = first.contentSize.height;
        second = [CCSprite spriteWithFile:@"clouds_2.png"];
        secondWidth = second.contentSize.width;
        Yvalue = 220.0f;
        duration = 200.0f;
        CGSize size = [[CCDirector sharedDirector] winSize];
        firstXf = -1 * (secondWidth - size.width + firstWidth/2);
        secondXf = -1 * (firstWidth + secondWidth/2);
        firstX0 = size.width + firstWidth/2;
        secondX0 = size.width + secondWidth/2;

        moveFirstDone = [CCCallFuncN actionWithTarget:self selector:@selector(callFirstDone:)];
        moveSecondDone = [CCCallFuncN actionWithTarget:self selector:@selector(callSecondDone:)];

        first.position = ccp(firstX0 + -1*firstX0,Yvalue);
        second.position = ccp(secondX0,Yvalue);
        [self addChild:first];
        [self addChild:second];
        [first runAction:[CCSequence actions:[CCMoveTo actionWithDuration:duration position:ccp(firstXf,Yvalue)],moveFirstDone,nil]];
        [second runAction:[CCSequence actions:[CCMoveTo actionWithDuration:duration*2 position:ccp(secondXf,Yvalue)],moveSecondDone,nil]];
    }
    return self;
}

-(void)callSecondDone:(id)sender{
    second.position = ccp(secondX0,Yvalue);
    [second runAction:[CCSequence actions:[CCMoveTo actionWithDuration:duration*2 position:ccp(secondXf,Yvalue)],moveSecondDone,nil]];
}

-(void)callFirstDone:(id)sender{
    first.position = ccp(firstX0,Yvalue);
    [first runAction:[CCSequence actions:[CCMoveTo actionWithDuration:duration*2 position:ccp(firstXf,Yvalue)],moveFirstDone,nil]];
}
@end

Using

    Clouds *clouds = [Clouds node];
    [self addChild: clouds z:0];

you add the node to your main layer/scene

I don't know if this is exactly what you need but maybe it helps. See a video of the effect that i get using this approach https://rapidshare.com/files/3478655240/2012-02-14_1458.swf

0
votes

Just for clarification, when you set height to 321 pixels, do you adjust position?

background.position = ccp(background.contentSize.width/2, (background.contentSize.height - 1)/2);
background2.position = ccp(background2.contentSize.width/2, -(background2.contentSize.height - 1)/2);

(Updated)

For clouds case I would propose alternative: use one sprite with tiled in horizontal direction cloud texture (texture must be with power-of-two size). Then scroll texture coordinates instead of moving sprite. But looks like this functionality is not present in official cocos2d sources, so you need to get it from here and merge with CCTextureNode class. Then:

  • set GL_TEXTURE_WRAP_S texture parameter for cloud texture via [cloudTexture setTexParameters: ...]
  • scroll texture with TextureMoveBy action, or by adjusting cloudTexture.texPosition in update method