开发者

Change Sprite Anchorpoint without moving it?

I am trying to change my Sprite anchor point so that I can rotate over a 0.0f,0.0f anchorpoint. At first my object is rotation at the default anchor point (0.5f,0.5f). However later on I need it to rotate over a 0.0,0.0 AnchorPoint.

The problem is I cannot change the anchor point and change the position accordin开发者_如何学Pythongly, so it stays on the same position, without the object appearing to quickly move and reposition to its original point.

Is there a way I can set the anchor point and the position of my Sprite at once, without it moving at all?. Thank you.

-Oscar


I found a solution to this with a UIView elsewhere, and rewrote it for cocos2d:

- (void)setAnchorPoint:(CGPoint)anchorPoint forSprite:(CCSprite *)sprite
{
    CGPoint newPoint = CGPointMake(sprite.contentSize.width * anchorPoint.x, sprite.contentSize.height * anchorPoint.y);
    CGPoint oldPoint = CGPointMake(sprite.contentSize.width * sprite.anchorPoint.x, sprite.contentSize.height * sprite.anchorPoint.y);

    newPoint = CGPointApplyAffineTransform(newPoint, [sprite nodeToWorldTransform]);
    oldPoint = CGPointApplyAffineTransform(oldPoint, [sprite nodeToWorldTransform]);

    CGPoint position = sprite.position;

    position.x -= oldPoint.x;
    position.x += newPoint.x;

    position.y -= oldPoint.y;
    position.y += newPoint.y;

    sprite.position = position;
    sprite.anchorPoint = anchorPoint;
}


This is a good question, and I don't know the full answer yet.

As you may have noticed, the anchorPoint cannot be changed without affecting scale and rotation.

For scaled sprites:

You have to simultaneously change the anchorPoint and position of your sprite. See this question for a hint

For rotated sprites:

Intuition says you would need to simultaneously change anchorPoint, rotation, and position. (I have no idea how to compute this.)

NOTE: I'm still learning graphics programming, so I'm not 100% able to compute this stuff yet.


I've needed this a couple of times and decided to make a extension for CCNode, tested it abit and seems to work fine. Can be really useful to some :)

It's tested with 1.x but It should work fine in 2.x too. Supports transformed nodes and HD.

Just add this to your project and import whenever you need it - It will be added to all classes deriving from CCNode. (CCSprite, CCLayer)

Interface

#import "cocos2d.h"

@interface CCNode (Extensions)

// Returns the parent coordinate for an anchorpoint. Useful for aligning nodes with different anchorpoints for instance
-(CGPoint)positionOfAnchorPoint:(CGPoint)anchor;

// As above but using anchorpoint in points rather than percentage
-(CGPoint)positionOfAnchorPointInPoints:(CGPoint)anchor;

//Sets the anchorpoint, to not move the node set lockPosition to `YES`. Setting it to `NO` is equal to setAnchorPoint, I thought this would be good for readability so you always know what you do when you move the anchorpoint
-(void)setAnchorPoint:(CGPoint)a lockPosition:(BOOL)lockPosition;

@end

Implementation

#import "CCNode+AnchorPos.h"

@implementation CCNode (Extensions)

-(CGPoint)positionOfAnchorPoint:(CGPoint)anchor
{
    float x = anchor.x * self.contentSizeInPixels.width;
    float y = anchor.y * self.contentSizeInPixels.height;

    CGPoint pos = ccp(x,y);

    pos = CGPointApplyAffineTransform(pos, [self nodeToParentTransform]);

    return ccpMult(pos, 1/CC_CONTENT_SCALE_FACTOR());
}

-(CGPoint)positionOfAnchorPointInPoints:(CGPoint)anchor;
{
    CGPoint anchorPointInPercent = ccp(anchor.x/self.contentSize.width, anchor.y/self.contentSize.height);
    return [self positionOfAnchorPoint:anchorPointInPercent];
}

-(void)setAnchorPoint:(CGPoint)a lockPosition:(BOOL)lockPosition
{
    CGPoint tempPos = [self positionOfAnchorPoint:a];
    self.anchorPoint = a;

    if(lockPosition)
    {
        self.position = tempPos;
    }
}

@end


Cocos2d-x + Fixed scale

YourClass.h

virtual cocos2d::Vec2 positionFromSprite(cocos2d::Vec2 newAnchorPoint, cocos2d::Sprite *sprite);

YourClass.m

Vec2 YourClass::positionFromSprite(Vec2 newAnchorPoint, cocos2d::Sprite *sprite) {
    Rect rect = sprite->getSpriteFrame()->getRect();
    Vec2 oldAnchorPoint = sprite->getAnchorPoint();
    float scaleX = sprite->getScaleX();
    float scaleY = sprite->getScaleY();

    Vec2 newPoint = Vec2(rect.size.width * newAnchorPoint.x * scaleX, rect.size.height * newAnchorPoint.y * scaleY);
    Vec2 oldPoint = Vec2(rect.size.width * oldAnchorPoint.x * scaleX, rect.size.height * oldAnchorPoint.y * scaleY);

    Vec2 position = sprite->getPosition();

    position.x -= oldPoint.x;
    position.x += newPoint.x;

    position.y -= oldPoint.y;
    position.y += newPoint.y;

    return position;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜