Manually drawing sprites

Hi

I’m considering porting a large game over to cocos in order to obtain cross platform compatibility.

As the game is already written, i’m not too keen on using the built in layer system/etc.

Is there a way of manually drawing loaded sprites, so that the order i call “Draw” on them, is the order they display on the screen?

(I’ll manage all the performance/batching/etc at my end?

I have hundreds of sprites. The only way I could see it working with the “preferred” method is if i load in all my sprites, then at the start of each frame, make them all hidden, then unhide them on each draw call. However, then i’m not guaranteed as to the draw order!

I also need to manually alter the UVs/etc before each draw (for some special fx).

Im looking for the simplest solution, without having to refactor lots of my code…

At the moment i’m evaluating as to whether using cocos is viable for what im trying to do.

Any thoughts/suggestions/etc gratefully received, heck if you’re super helpful, and you live near me, i’d even buy you a drink or two! :smiley:

Hello,
to control the order of drawing in the sense what’s in front and what’s in the back you can use the Z order value of a CCNode (parent of CCSprite):
CCNode::setZOrder (int zOrder)
“Sets the Z order which stands for the drawing order, and reorder this node in its parent’s children array.”

Sprites with higher values appear in front of those with lower values.

Best regards
n-o-d

Thanks for your reply Mr Nod.

It’s a little more complex than that, as I may also want to draw the same sprite mutliple times, with different UV values (i wont know how many times or which UVs at start up).

I did some tests last night and by overloading the Node class and Sprite class (which i also need to do to get better control of UVs), i THINK i can do it…

Not too sure if it’s the most sensible way though:

code looks like this currently (NOT finished code - just experimenting)

class MyScene : public CCScene
{
public:
    static MyScene* create()
    {
        MyScene *pRet = new MyScene();
        if (pRet && pRet->init())
        {
            pRet->autorelease();
            return pRet;
        }
        else
        {
            CC_SAFE_DELETE(pRet);
            return NULL;
        }
    }
    void visit()
    {
        // Manually Draw sprite in order (no children to worry about)
            for ( int i = 0; i < NumSprites; i++ )
            {
        kmGLPushMatrix();
        Sprites[i]->pSprite->updatePosAndRot();
                Sprites[i]->pSprite->transform();
        CCRect UV(0,0,0.5,0.5);
        CCRect rect(0,0,100,100);
                // also overloaded this to be able to have seperate UV/rect
        Sprites[i]->pSprite->setTextureRect(UV, rect);
        Sprites[i]->pSprite->draw();
        kmGLPopMatrix();
             }
    }
};

pSprite can exist in the Sprite list multiple times, with different positions/rotations/uvs (eventually).

Hello Mr Clam,
you can try creating one texture

CCImage *image= new CCImage;
image->initWithImageFile("texture.png");
CCTexture2D *texture = new CCTexture2D;
texture->initWithImage(image);

which is then reused for several sprites with createWithTexture():

CCSprite *sprites[99];
for(i...)
{
        CCRect UVrect;
        set UVrect here...
    sprites[i] = CCSprite::createWithTexture(texture, UVrect);
        sprites[i]->retain();
        ...;
}

For optimization you might consider using a CCSpriteBatchNode. I’ve never used that class so far but it might be the right one for you.

Best regards
n-o-d