nosmirck
nosmirck

Reputation: 666

How to duplicate sprite of sprites in cocos2d-x 2.1.4

Well, my question is simple, I'm starting with cocos2d-x programming and I'm trying to make a tiled infinite background, lets say I have a png of an image I want to repeat infinitely as a background, What I did was that I created a Sprite as a container, then I added sprites with the same image, one aside the next, covering about 110% the screen, then, following the Space game tutorial I created the same sprite of sprites once again as a second background and I use it as two large identical images to scroll infinite... it works perfect... but I'm wondering if it is possible to create the second sprite by just copying the frist. Some code maybe will clear my situation:

this goes in the init():

acum = 0.0;
city1 = CCSprite::create();
for(int i = 0; i < 12; ++i) {
    CCSprite *city = CCSprite::createWithSpriteFrameName("env_buildings_background2.png");
    city->setPosition(ccp(acum, 0));
    city1->addChild(city);
    acum+= city->getContentSize().width*0.99;
}
city1->setContentSize(ccp(acum, 0));
city2 = CCSprite::create();
acum = 0.0;
for(int i = 0; i < 12; ++i) {
    CCSprite *city = CCSprite::createWithSpriteFrameName("env_buildings_background2.png");
    city->setPosition(ccp(acum, 0));
    city2->addChild(city);
    acum+= city->getContentSize().width*0.99;
}
city2->setContentSize(ccp(acum, 0));
_backgroundNode->addChild(city1, -1 , buildingspeed, ccp(0, winSize.height * 0.6));

_backgroundNode->addChild(city2, -1 , buildingspeed, ccp(city1->getContentSize().width, winSize.height * 0.6));
printf("%f - %f\n", city1->getContentSize().width, city2->getContentSize().width);

The main problem is here, where I need to create city2 from city1 and not just repeat code... is there a way to do this? I don't see a constructor in CCSprite that allows me to do so...

this goes in the update():

CCArray *cities = CCArray::createWithCapacity(2);
cities->addObject(city1);
cities->addObject(city2);
for ( int ii = 0; ii <cities->count(); ii++ ) {
    CCSprite * city = (CCSprite *)(cities->objectAtIndex(ii));
    float xPosition = _backgroundNode->convertToWorldSpace(city->getPosition()).x;
    float size = city->getContentSize().width;
    if ( xPosition < -size ) {
        _backgroundNode->incrementOffset(ccp(city->getContentSize().width*2,0),city);
    }
}

I will appreciate any help, thanks in advance.

Upvotes: 1

Views: 4551

Answers (1)

Souandios
Souandios

Reputation: 544

This code will create the exact snapshot of your citySprite. And as this is a snapshot, you'll be having no access to the sprites that it contains. Cause they are now embedded in the image or sprite itself.

float citySpriteWidth = 480;
float citySpriteHeight = 320;

//Set position in order to make it fit inside CCRenderTexture (You can change this later)
citySprite->setPosition(ccp(citySpriteWidth/2, citySpriteHeight/2));

CCRenderTexture *render = CCRenderTexture::renderTextureWithWidthAndHeight(citySpriteWidth, citySpriteWidth);
render->beginWithClear(0, 0, 0, 0);
citySprite->visit();
render->end();

CCTexture2D *tex = render->getSprite()->getTexture();
CCSprite *newCitySprite = CCSprite::spriteWithTexture(tex);
newCitySprite->setFlipY(true);  //Texture might be upside down

Hope this helps your requirements.

Else if your problem is just code repetition. Then you can write a function which would give you your city sprite containing other sprites like this one. And call it number of times you want it.

CCSprite* creteCitySprite()
{
     float acum = 0.0;
     CCSprite *city1 = CCSprite::create();

     for(int i = 0; i < 12; ++i)
     {
          CCSprite *city = CCSprite::createWithSpriteFrameName("env_buildings_background2.png");
          city->setPosition(ccp(acum, 0));
          city1->addChild(city);
          acum+= city->getContentSize().width*0.99;
     }

     city1->setContentSize(CCSizeMake(acum, 0));

     return city1;
}

EDITED: This gives you what you want. But what I wanted to say is, the sub sprites which you added to your city1 will remain static.

 CCSptire *getSpriteFromSprite(CCSprite *citySprite, float citySpriteWidth, float citySpriteHeight)
{
    CCPoint prevPosition = citySprite->getPosition();

    //Set position in order to make it fit inside CCRenderTexture (You can change this later)
    citySprite->setPosition(ccp(citySpriteWidth/2, citySpriteHeight/2));

    CCRenderTexture *render = CCRenderTexture::renderTextureWithWidthAndHeight(citySpriteWidth, citySpriteWidth);
    render->beginWithClear(0, 0, 0, 0);
    citySprite->visit();
    render->end();

    citySprite->setPosition(prevPosition);

    CCTexture2D *tex = render->getSprite()->getTexture();
    CCSprite *newCitySprite = CCSprite::spriteWithTexture(tex);
    newCitySprite->setFlipY(true);  //Texture might be upside down

}

Upvotes: 1

Related Questions