Question

I want cocos2d to use the nodes' position as a normalized factor when coordinates are less than 1, and otherwise when coordinates are greater than 1, I want cocos2d to treat coordinates as it would normaly do

For instace position (1,1) would locate the node at the top-right corner of the screen, while (.5,.5) would locate the node on the center of the screen.

I was thinking on rewriting the code just where cocos2d pass on the coordinates to the vertex buffer like the following pseudo code

if (Position.x <= 1)
    BufferPosition.x = Screen.Width * Position.x;
else
    BufferPosition.x = Position.x;

if (Position.y <= 1)
    BufferPosition.y = Screen.Height * Position.y;
else
    BufferPosition.y = Position.y;

So my question is where would you put this code so that cocos2d works that way with no problem, or what approach would you take istead if it's different from the shown above

Update

I changed every single call/assignment of positionInPixels_ in the entire cocos2d library for positionInPixels

This means that each time, the corresponding getter and setter is caled instead of the CCNode's positionInPixels_ member variable.

Then I changed setPosition, and setPositionInPixels in CCNode.m like this

setPosition

-(void) setPosition: (CGPoint)newPosition
{
CGSize winSize = [[CCDirector sharedDirector] winSize];

position_ = newPosition;

if (position_.x <= 1.0) {
    positionInPixels_.x = position_.x * winSize.width;
}
else
{
    if( CC_CONTENT_SCALE_FACTOR() == 1 )
        positionInPixels_.x = position_.x;
    else
    positionInPixels_.x = newPosition.x * CC_CONTENT_SCALE_FACTOR();
}

if (position_.y <= 1.0) {
    positionInPixels_.y = position_.y * winSize.height;
}
else
{
    if( CC_CONTENT_SCALE_FACTOR() == 1 )
    positionInPixels_.y = position_.y;
    else
    positionInPixels_.y = newPosition.y * CC_CONTENT_SCALE_FACTOR();
}

isTransformDirty_ = isInverseDirty_ = YES;
#if CC_NODE_TRANSFORM_USING_AFFINE_MATRIX
isTransformGLDirty_ = YES;
#endif
}

setPositionInPixels

-(void) setPositionInPixels:(CGPoint)newPosition
{
CGSize winSize = [[CCDirector sharedDirector] winSize];

positionInPixels_ = newPosition;

if (position_.x <= 1.0) {
    position_.x = positionInPixels_.x / winSize.width;
}
else
{
    if( CC_CONTENT_SCALE_FACTOR() == 1 )
    position_.x = positionInPixels_.x;
    else
    position_.x = newPosition.x * 1/CC_CONTENT_SCALE_FACTOR() / winSize.width;
}

if (position_.y <= 1.0) {
    position_.y = positionInPixels_.y / winSize.height;
}
else
{
    if( CC_CONTENT_SCALE_FACTOR() == 1 )
    position_.y = positionInPixels_.y;
    else
    position_.y = newPosition.y * 1/CC_CONTENT_SCALE_FACTOR() / winSize.height;
}

isTransformDirty_ = isInverseDirty_ = YES;
#if CC_NODE_TRANSFORM_USING_AFFINE_MATRIX
isTransformGLDirty_ = YES;
#endif
}

This is working so far, even when using normalized coordinates with CCActionInterval

Was it helpful?

Solution

So you really think that this variant is the right one? To change the whole framework instead of just adding one method to the CCNode's extension? I think you will see a lot of problem with positioning very soon.

Also it is not good, that (1.f, 1.f) is always have coordinates (screenWidth, screenHeight). You will have a lot of troubles with small nodes. IMHO if you need such positioning, it is much more appropriate to connect this "factor" coordinates to the node's parent size. Just do restore cocos2d framework and add your own extension to your project. For example,

@interface CCNode(FactorPositioning)
- (void) setPositionFactor:(CGFloat) factor;
@end

@implementation CCNode(FactorPositioning)
- (void) setPositionFactor:(CGFloat) factor
{
    assert(self.parent != nil);

    // do your calculations relatieve to the parent's content size
}
@end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top