【问题标题】:Change Sprite Anchorpoint without moving it?更改 Sprite Anchorpoint 而不移动它?
【发布时间】:2011-01-06 13:16:01
【问题描述】:

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

问题是我无法更改锚点并相应地更改位置,因此它保持在同一位置,而对象似乎不会快速移动并重新定位到其原始点。

有没有一种方法可以一次设置我的 Sprite 的锚点和位置,而不需要它移动?谢谢。

-奥斯卡

【问题讨论】:

  • 你说的是什么精灵?
  • 对不起,我忘了包括那个。我说的是 iPhone Sprites 的 openGL 2.0。
  • 也许你的意思是cocos2d? OpenGL 没有“iPhone Sprite”。

标签: iphone objective-c cocos2d-iphone


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我需要这个几次,并决定为 CCNode 做一个扩展,测试了一下,似乎工作正常。对某些人来说真的很有用:)

    它在 1.x 中经过测试,但在 2.x 中也应该可以正常工作。支持转换节点和高清。

    只需将它添加到您的项目并在需要时导入 - 它将添加到从 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】:

      我在别处找到了一个 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;
      }
      

      【讨论】:

      【解决方案4】:

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

      您可能已经注意到,在不影响缩放和旋转的情况下无法更改锚点。

      对于缩放的精灵:

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

      对于旋转的精灵:

      直觉说您需要同时更改锚点、旋转和位置。 (我不知道如何计算。)

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-04
        • 1970-01-01
        • 2014-06-10
        相关资源
        最近更新 更多