How to draw a sprite without adding its as a child?

I’m porting a game (platformer) to Cocos2d-x. I need to draw something like this:

for ( unsigned int i = 0; i < 100; i++ ) {
    draw( sprite, i * 10, 100 );
}

How it can be done with Cococ2d-x? I need to create array of 100 same sprites? And then I need to add those sprites as a child? And in the next frame I need to remove some childs and add other childs? :)) It’s very inefficiently! How it can be done with Cocos more effectively than in my explanation?

What you want to do is not clear.

First, for most usages, you aren’t going to draw anything: cocos2d takes care of that for you. What you do is create a hierarchy of objects and animate sprites (makes them move, scale, rotate) during the update loop.

I don’t think you are at that stage yet, but if you want 100 same sprites, you want to use a CCSpriteFrame for performance reasons. Don’t do it before you can actually see a performance drop (“early optimization is the root of evil”).

François Dupayrat wrote:

“early optimization is the root of evil”
:slight_smile:

Yeah, I’m new to Cocos2d. Now I don’t understand how I can display a sprite two (or more times) at the screen (in different place). The only one solution which I’ve found it’s:

// displaying one sprite 100 times in a row

CCSprite *spriteArr[ 100 ];

for ( unsigned int i = 0; i < 100; i++ ) {

    spriteArr[ i ] = new cocos2d::CCSprite();
    spriteArr[ i ]->initWithFile( "sprite.png" );
    spriteArr[ i ]->setPosition( cocos2d::CCPoint( i * 10, 100 ) );

    this->addChild( spriteArr[ i ] );

}

How can I optimize it if i need to draw one sprite 100 times in a row? :slight_smile:

Airex Rest wrote:

Now I don’t understand how I can display a sprite two (or more times) at the screen (in different place).
The problem is your reasonning : that’s just not how cocos2d work. How it works is : you add a sprite to your current scene, and it will be displayed all the time on that scene. If you want to change its position, you just change the sprite position (or use a CCMoveTo/CCMoveBy animation) when you want. For that, you’ll probably need to suscribe to update using the CCNode::scheduleUpdate() method.

The code you wrote will indeed display 100 sprite (though they may not all be visible because of your screen resolution), though there will probably be a memory leak because you used new instead of create.

As for the optimization, look at CCSpriteFrame, there should be an eample in TestCpp.

François Dupayrat wrote:

Airex Rest wrote:
> Now I don’t understand how I can display a sprite two (or more times) at the screen (in different place).
The problem is your reasonning : that’s just not how cocos2d work. How it works is : you add a sprite to your current scene, and it will be displayed all the time on that scene.

:slight_smile: I understand that. You mean Cocos2d allows to write games where I can load a sprite and display it just for one time on the screen? :)) What if I wanna display one sprite two or more times? How can I do it? There I wrote one solution which I came up with. I can’t imagine more solutions that’s why I’m asking for it :))

Ok, to do the things more clear let’s imagine that we’re creating a simple game - three in a row! :)) There are 4 types of jewels (for example). We load 4 sprites and what…? :slight_smile: How can we display one sprite in a different places? I need 4 arrays of Sprites of each type, right? :))

Airex Rest wrote:

:slight_smile: I understand that. You mean Cocos2d allows to write games where I can load a sprite and display it just for one time on the screen? :slight_smile: What if I wanna display one sprite two or more times? How can I do it? There I wrote one solution which I came up with. I can’t imagine more solutions that’s why I’m asking for it :slight_smile:

First, what do you call a “time” ? Do you refer to a frame, a second, a scene, or something else ? You can do anything you want, more or less. But it’s not wise to display a sprite for just one frame because it would blink. It’s also bad practice to count in number of frames because the target device fps can vary.

I still don’t quite understand what you really want to do and what’s your question.

Airex Rest wrote:

Ok, to do the things more clear let’s imagine that we’re creating a simple game - three in a row! :slight_smile: There are 4 types of jewels (for example). We load 4 sprites and what…? :slight_smile: How can we display one sprite in a different places? :slight_smile:

Oh, you simply create several sprites with the same texture (cocos2d will do that automatically for you when you specify the image file) and place them at different places. If performance becomes an issue, use CCSpriteFrame.

You need to use CCSpriteBatchNode if you are going to draw many sprites to the screen. The sprite batch will send a group of textured quads to the framebuffer in one operation instead of N operations. This is far more efficient than using single CCSprite instances to draw the 3000 sprites that you’ll likely draw on the screen.

François Dupayrat wrote:

Oh, you simply create several sprites with the same texture
But how to do it correctly? Like so: CCSprite *spriteArray[100]; or I need to use something another? :))

Jacob Anderson wrote:

You need to use CCSpriteBatchNode if you are going to draw many sprites to the screen. The sprite batch will send a group of textured quads to the framebuffer in one operation instead of N operations. This is far more efficient than using single CCSprite instances to draw the 3000 sprites that you’ll likely draw on the screen.

Wow. I think that’s much better than adding many sprites directly to CCLayer :)) I don’t know yet what CCSpriteBatchNode is but I think that using of CCSpriteBatchNode is similar to adding my sprites directly to CCLayer but now I need to add my sprites into CCSpriteBatchNode, right?

I have another interesting task for CCSpriteBatchNode :)) How to draw tilemap with Cocos2d? If we’re talking about platformer-games we need a different number of tiles at every moment of game. I don’t understand how to manage (and how to draw) sprites when I need different number of sprites at every moment of game so we can add to CCLayer or to CCSpriteBatchNode just fixed number of sprites… and then we need to remove and add child-sprites so annoying to manage it when in other frameworks we can draw something like this:

for ( int i = 0; i < tilesArraySize; i++ ) {
    draw( sprite, tilesArray[ i ].x, tilesArray[ i ].y );
}

I think I need to google some info about drawing tiles with Cocos2d it promises be intresting :))

Oh my gosh, there’s a big article on that subject :smiley: http://www.cocos2d-x.org/projects/cocos2d-x/wiki/TileMap

By the way, I have another question about optimization. If I use something like this: CCSprite *spriteArray[100] for generating a tile map I need to allocate amount of memory for each of 100 sprites, right? But I wanna allocate memory just for one needed sprite for generating a tile map (a very simple map :)) ). I need just one sprite, why I need to allocate a memory for 100 sprites when I need to tile a background with just one sprite? :slight_smile:

By “tile” I mean:
_


A tile engine is a computer graphics technique which generates a larger graphic from re-using a number of smaller graphics to save RAM and increase real-time rendering performance._

Is there a way to optimize it in Cocos2d? In the LibGDX (java framework) I can load just one sprite and draw that sprite 100 times on the frame (using array of x and y) so I can generate very easy tile map with one sprite. I can’t find a technique in Cocos2d which allows me to do something like that… In Cocos2d with above solution I need to spend 100 times more memory :))