alxcyl
alxcyl

Reputation: 2722

Scale a CCSprite from the side and not from the center

I am trying to make a customized progress bar. What I want to do is to have "barMask.png" have it's X scale depending on a percentage of the number. I've tried to do it like this:

barBack = CCSprite::create( "barBack.png" );
this -> addChild( barBack );

barMask = CCSprite::create( "barMask.png" );
barMask -> setPosition( barBack -> getPosition( ) );
this -> addChild( barMask );

Then on the update method

// Scale the width of barMask depending on the percentage of the progress.
barMask -> setScaleX( CURRENT_AMOUNT / TOTAL_AMOUNT );

However, the sprite is scaled like this:

Frame 1: [ |||||||||| ]
Frame 2: [  ||||||||  ]
Frame 3: [   ||||||   ]

It shrinks down into the middle. How can I do so that it shrinks down to the left/right? Like this:

Frame 1: [ |||||||||| ]
Frame 2: [ |||||||||  ]
Frame 3: [ ||||||||   ]
Frame 4: [ |||||||    ]

I know about CCProgressTimer but I want to use purely sprites for the progress bar.

Upvotes: 2

Views: 1235

Answers (2)

Shogan
Shogan

Reputation: 1195

Another way this could potentially be achieved is by using the draw method and a bit of openGL. I used this for health bars for enemies in my space shootem up app, that scale according to the enemy HP remaining. It is adapted from one of Ray Wenderlich's tutorials. Anyway, here is my draw method, it iterates through each boss "monster" on screen and draws their health bars. This could be adapted, and the method used for a progress indicator bar...

- (void)draw {

for (CCSprite *target in _targets) {
    Monster *monster = (Monster *)target;

    if (monster.monsterisboss == YES) {

        static int lineBuffer = 5;
        int lineHeight = 7;
        int startY = monster.position.x - (monster.contentSize.width/2);
        int endY = monster.position.x + (monster.contentSize.width/2) - lineBuffer;
        int actualX = monster.position.y + (monster.contentSize.height/2) + lineHeight*2;

        static int maxColor = 200;
        static int colorBuffer = 55;
        float percentage = ((float) monster.hp) / ((float) monster.maxHp);
        int actualY = ((endY-startY) * percentage) + startY;
        int amtRed = ((1.0f-percentage)*maxColor)+colorBuffer;
        int amtGreen = (percentage*maxColor)+colorBuffer;

        glEnable(GL_LINE_SMOOTH);

        glLineWidth(lineHeight);        
        glColor4ub(amtRed,amtGreen,0,255);
        ccDrawLine(ccp(startY, actualX), ccp(actualY, actualX));
    }
}

[super draw];

}

edit Looks like my code block left out that last closing curly bracket - don't forget that if you want to try the above draw method!

Upvotes: 2

Morion
Morion

Reputation: 10860

Change spriet's anchorPoint property to (0.f, 0.5f). All transformations are made relatieve to the node's anchor point. By default anchor point of the sprite is (0.5f, 0.5f). Thats why your scaling is relatieve to the center of your sprite by default.

Upvotes: 3

Related Questions