How to make a screen auto scroll just like in various games like flappy bird

I have a image 1536*2048 as background .png.I want to continuosly scroll it.My game is in landscape mode
my code

    bool HelloWorld::init()
    {
    //////////////////////////////
    // 1. super init first
    if ( !CCLayer::init() )
    {
        return false;
    }

    addBackground();

    return true;
    }


    void HelloWorld::addBackground()
    {
    background = CCSprite::create("background.png");
    // background->setAnchorPoint(ccp(.3, 0));
    background->setPosition(ccp(winSize.width/2,winSize.height/2));
    background->addComponent(new MoveLoop());
    this->addChild(background);
    
   }

And the moveloop.cpp

    void MoveLoop::onEnter()
    {
    actionMove();
    }

    void MoveLoop::actionMove() 
    {
    CCNode* parent = (CCNode*)getOwner();
    if (parent == NULL) return;
    
 
    float w = parent->boundingBox().size.width / 15;
    CCMoveTo* moveleft = CCMoveTo::create(kMoveLeftDura, ccp(-w, 0));
    CCMoveTo* moveright = CCMoveTo::create(0, ccp(w, 0));
    CCRepeatForever* repeat =CCRepeatForever::create(CCSequence::create(moveleft,moveright, 
    NULL));
    parent->runAction(repeat);
    
}

My problem is that i can’t fix a smooth scrolling.each time it feels like that i have shifted the image towards right very fast and then again moving left.Can anyone here help me to just continuosly scroll the background smoothly so that it feels like we are moving forward

Ray and his team have a vast amount of knowledge, try this tutorial from his Web site / Blogg. It helped me a lot :slight_smile:

@StainzE I have seen this one but unable to scroll a background what i mentioned perfectly.The link you mentioned consists of various children who are moving.But I just have to move my background image only forever.

use ccparallaxscrollnode https://github.com/stnguyen/CCParallaxScrollNode

it will help you to move the background permananetly.

Why not just use : background->runAction(MoveForever) ?

you cant because once the x becomes < 0 you have to reset the image to the right again…

@siddharthshekar yes thats my point what siddharth has written.The image will move to right and again there will be a slight jerk and thus no perfection in the game.But how the screen continously moves in games like flappy bird with perfection.There must be some solutions…

@shuai i have already user repeatforever.

I made this quite a few times.

I simply:

  • create two different CCSprite (which have to be circular of course, so that the right hand side of one is the left hand side of the other).

  • I place them side by side (one has anchor point in 0,0 and is placed in 0,0)

    closeParallax1 = CCSprite::create("Backgrounds/parallax_davanti.png");
    closeParallax1->setAnchorPoint(ccp(0, 0));
    closeParallax1->setPosition(ccp(visibleSize.width*0.0, visibleSize.height*0));
    addChild(closeParallax1);
    closeParallax2 = CCSprite::create("Backgrounds/parallax_davanti.png");
    closeParallax2->setAnchorPoint(ccp(0, 0));
    closeParallax2->setPosition(ccp(0 - closeParallax2->getContentSize().width, visibleSize.height*0));
    addChild(closeParallax2);
  • I then schedule the update in the Scene
    schedule(schedule_selector(HomeScene::update));
  • And in each update I move them, taking care of moving them back in the right spot when they cross the screen
// update backgrounds
void HomeScene::update(float dt)
{
    closeParallax1->setPositionX(closeParallax1->getPositionX() + 1.7);
    closeParallax2->setPositionX(closeParallax2->getPositionX() + 1.7);

    if(closeParallax1->getPositionX() > visibleSize.width)
    {
        closeParallax1->setPositionX(closeParallax2->getPositionX() - closeParallax1->getContentSize().width);
    }
    if(closeParallax2->getPositionX() > visibleSize.width)
    {
        closeParallax2->setPositionX(closeParallax1->getPositionX() - closeParallax2->getContentSize().width);
    }
}

This might not be the best solution, but it’s working. I also had this work in another project casting a sequence on the CCSprite telling first to move to a certain point, and then calling a callback that reset the position of the CCSprite to the original position.

Both ways work :slight_smile:

Let me know if you have problems, I can help you through this with precision!

1 Like

This is the way to do it. Altho I created a custom sprite class which scrolls and resets the position of the sprites. And then add as many to a layer. Then add layer to game layer.

Sorry I didn’t get your point at first. Basically my solution is the same as @davidejones88 . But I just make the two sprites run action like this:
runAction(CCRepeatForever::create(CCSequence::create(CCMoveTo::create(..), CCPlace::create(...), NULL)));