更改Sprite Anchor Point而不移动它?

时间:2010-01-18 21:17:17

标签: iphone objective-c cocos2d-iphone

我正在尝试更改我的Sprite锚点,以便我可以在0.0f,0.0f锚点上旋转。起初我的对象是默认锚点(0.5f,0.5f)处的旋转。但是后来我需要它在0.0,0.0 AnchorPoint上旋转。

问题是我不能改变锚点并相应地改变位置,所以它保持在同一位置,没有对象看起来快速移动并重新定位到其原始点。

有没有办法可以立刻设置锚点和我的精灵的位置,而根本不移动它?谢谢。

-Oscar

4 个答案:

答案 0 :(得分:3)

我在其他地方找到了一个UIView的解决方案,并为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;
}

答案 1 :(得分:2)

这是一个很好的问题,我还不知道完整的答案。

您可能已经注意到,无法在不影响比例和旋转的情况下更改anchorPoint。

对于缩放的精灵:

您必须同时更改您的精灵的anchorPoint和位置。见this question for a hint

对于旋转的精灵:

Intuition说你需要同时改变anchorPoint,旋转和位置。 (我不知道如何计算它。)

注意:我还在学习图形编程,所以我还没有100%能够计算这些东西。

答案 2 :(得分:2)

我需要这几次,并决定对CCNode进行扩展,测试它的abit并且似乎工作正常。对某些人来说真的很有用:)

它是用1.x测试的,但它也应该在2.x中正常工作。支持转换节点和HD。

只需将其添加到您的项目并在需要时导入 - 它将添加到从CCNode派生的所有类中。 (CCSprite,CCLayer)

<强>接口

#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

<强>实施

#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

答案 3 :(得分:0)

Cocos2d-x +固定比例

<强> 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;
}