Bazinga-Productions Life of an Java/iOS-Developer

16Sep/110

Scaling a CCNode centered

While working on my current Project (I will propably release it soon) I encountered  a Problem I didn't really expect:

When using the CCScaleTo-Action in cocos2d the CCNode is actually not being centered while scaling.
So for example if you have an CCSprite that is centered and you use  [CCScaleTo actionWithDuration:1 scale:2]; the result is actually not centered as I would have expected.

After reading a little bit about this on the cocos2d-forum I read that some other people had the same problem and I wasn't doing anything wrong, but this is just the way it works.

You could try to change the anchorPoint, since scaling seems to be relative to the anchorPoint,  but this didn't quite work out for me, so I just decided to write a new Action based on the existing CCScaleTo-Action.

Here is the Result:

CCScaleToCentered.h:

1
2
3
4
#import "cocos2d.h"
 
@interface CCScaleToCentered :CCScaleTo
@end

CCScaleToCentered.m:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#import "CCScaleToCentered.h"
 
@implementation CCScaleToCentered
+(id) actionWithDuration: (ccTime) t scale:(float) s
{
    return [[[self alloc] initWithDuration: t scale:s] autorelease];
}
 
-(id) initWithDuration: (ccTime) t scale:(float) s
{
    if( (self=[super initWithDuration:t]) ) {
        endScaleX_ = s;
        endScaleY_ = s;
    }
 
    return self;
}
 
+(id) actionWithDuration: (ccTime) t scaleX:(float)sx scaleY:(float)sy
{
    return [[[self alloc] initWithDuration: t scaleX:sx scaleY:sy] autorelease];
}
 
-(id) initWithDuration: (ccTime) t scaleX:(float)sx scaleY:(float)sy
{
    if( (self=[super initWithDuration: t]) ) {
        endScaleX_ = sx;
        endScaleY_ = sy;
    }
    return self;
}
 
-(void) update: (ccTime) t {
    [super update:t];
 
    CGSize winSize = [[CCDirector sharedDirector] winSize];
    float orgWidth = [target_ contentSize].width;
    float yScale = startScaleX_ + deltaX_ * t;
    [target_ setPosition:ccp(winSize.width/2 + ((orgWidth*yScale) - orgWidth)/4,
    winSize.height/2)];
}
 
@end

Here is an example of how to use it:

1
2
3
4
5
6
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCLabelTTF* label = [CCLabelTTF labelWithString:@"Test" fontName:@"Helvetica" fontSize:24];
// Center it
[label setPosition:ccp(winSize.width/2, winSize.height/2)];
// Run the Action
[label runAction:[CCScaleToCentered actionWithDuration:1 scale:2]];

I didn't do any extensive testing, so you might have to change some stuff if it doesn't work for you, but in my project it works good and the CCNode stays in the center while scaling.

It shouldn't be too hard to change this to be working with CCScaleBy.

Comments (0) Trackbacks (0)

No comments yet.


Leave a comment

No trackbacks yet.