cocos2d-x坐标系和锚点整理

原文链接:http://blog.csdn.net/wen294299195/article/details/7867595

在cocos2d-x中一共有四种坐标:

(1)屏幕坐标系

        在windows系统中,默认的原点在屏幕的左上角,X轴向右,Y轴向下。

      

(2)GL坐标系

        原点在左下角,X轴向右,Y轴向上。由于cocos2d-x使用的是open gl渲染引擎,而不是directx 3d引擎,那么GL坐标系就不和屏幕坐标系重合,这是要注意的一点。因此,当我们调用了一个屏幕响应事件时,如ccTouchEnded(CCTouch* touch, CCEvent* event);

此时我们CCPoint location = touch->locationInView(touch->View)返回点击处在屏幕坐标系的位置,而不是GL坐标系。因此就有将屏幕坐标系转换成GL坐标系的函数。

CCPoint convertedLocation = CCDirector::sharedDirector()->convertToGL(location);

 

(3)本地坐标系

         游戏中,每一个对象都有一个自己的坐标系,这些坐标系就叫做本地坐标系。

         相对于父对象的坐标系,原点在左下角,X轴向右,Y轴向上。举个例子,以我自己作为坐标原点,那么在我附近(在我这个坐标系内)的对象就是子对象,而我就是父对象,这些子对象的位置都是本地坐标系,是相对于我(父对象)来说的。下面我举一个代码来做说明:

      ..........

      CCLayer* layer = new CCLayer();

      CCSprite* player = CCSprite::spriteWithFile("player.png");

     layer->addChild(player, 1);

     ................

在这里,player对象就是子对象,layer就是父对象,那么player相对于layer的位置就是在本地坐标系中的位置。如果,layer(父对象)发生移动,就是我们说的背景移动,那么,player(子对象)也会跟着移动,但子对象在本地坐标系中的位置不变,改变的是子对象在世界坐标系中的位置。

(4)世界坐标系

         世界坐标就是所谓的绝对坐标,所有的对象虽然都有自己的本地坐标系,但这些对象同样的在世界坐标系中也有一个坐标。例如,整个地球就是一个世界坐标系,在地球上的每一个人都有一个唯一的坐标。


Cocos2d-x里面的锚点作用机理跟我以前使用的LimeJS不同,这一点让我一直很奇怪为什么效果实现不了,直到找到了这篇文章。

原文链接:

http://cutesung2.blogspot.com/2011/12/cocos2d-x-anchorchild.html

什麼是 Anchor?

CCNode 的錨點(AnchorPoint)是用來指定對於內容物(ContentSize)的偏移率,
其值範圍為0~1,ccp(0,0)為左下,ccp(1,1)為右上,ccp(0.5,0.5)為中央,
CCLayer元件預設為ccp(0,0),而CCSprite元件預設為ccp(0.5,0.5),
簡單來說可以理解成決定"內容物的中心點",但不完全是。

想在中心點加入 child,位置卻不對?

通常以為,父元件的中心點,就是子元件的原點,
假設我有兩個方塊:

紅色方塊 red.png ( 100 x 100 pixcels )
黃色方塊 yellow.png ( 50 x 50 pixcels )

皆以方塊的中央作為中心點 anchor (0.5, 0.5 ),
並且將紅色方塊放在 position ( 200, 200 ) 的位置,
黃色方塊是紅色方塊的子元件,位在紅色方塊中央 position ( 0, 0 ) 的位置,

像是這樣:

(預期的結果)
於是我這樣寫:

//產生紅色方塊 sprite 元件
CCSprite* pRed = CCSprite::spriteWithFile("red.png");

pRed->setAnchorPoint(ccp(0.5, 0.5));//中心點在中央
pRed->setPosition(ccp(200, 200));//放在(200,200)的位置
addChild(pRed); //紅色加入根節點

//產生黃色方塊 sprite 元件
CCSprite* pYellow = CCSprite::spriteWithFile("yellow.png");
pYellow->setAnchorPoint(ccp(0.5, 0.5)); //中心點在中央
pYellow->setPosition(ccp(0, 0)); //放在(0,0)的位置
pRed->addChild(pYellow); //黃色加入紅色

結果看起來卻是:
(實際的結果)
子元件並沒有連在父元件的中心點上。

"錨點中心點"不是子元件的原點

其實錨點不完全算是中心點,因為父元件的錨點中心點並不是子元件原點,
子節點並不會參考父節點的錨點,而是永遠把父節點的最左下當作原點

任何元件都會以自己 錨點(AnchorPoint) 做為自己的中心點,
attach 到以父節點左下為原點的 相對 座標(Position)

使中心點也是原點的辦法

要解決 CCSprite 中心點不是子元件原點的問題,
我更傾向使用 texture 的 offset,而非 node 的 anchor:

1. 因為 AnchorPoint 無法影響 child 節點的參考原點,
如果中心點必須也是子元件的原點,使用 AnchorPoint 是做不到的,
我更喜歡的是將 AnchorPoint 保持在 ccp(0, 0),而改用 texture offset,

也就不會發生上面那張圖的問題了。


2. 而且,一個 CCSprite 只能有一個 AnchorPoint,
如果用 CCSprite 播放 CCSpriteFrame,每 frame 又都擁有不同的中心點,

用 AnchorPoint 就非常頭大了。


ps:尝试了下设置锚点,发觉sprite完全没问题,但是加入一个layer以后,无论怎么设置layer的锚点都不起作用,非常奇怪,查找和测试了一会儿,终于发觉是因为layer默认设置不参考锚点,而sprite默认是开启了锚点。要使layer的anchorPoint有效,只需要调用setIsRelativeAnchorPoint(true);至此,终于明白了锚点相关问题。以前看到过说要设置setIsRelativeAnchorPoint,可是当时没有仔细看,没有调用过,sprite也能使用锚点,时间一长也就忘记了,后来问题不断,终于理清楚了这个问题。多希望能有一个完整详细的教程,可以不用在些很小细节的地方纠缠。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值