Cocos2dx开发之锚点

来源:互联网 发布:电脑桌面软件突然不见 编辑:程序博客网 时间:2024/06/10 16:27


Cocos2dx开发之锚点实例讲解

[ http://blog.sina.com.cn/s/blog_ad1675150101ffre.html ]

 

锚点概念

         由于我们在使用Cocos2dx进行开发时,一般都是在场景中加载精灵来实现的,而精灵上挂载的往往都不是一个点而是一张图片资源,那么我们在场景中设置这个精灵的位置时,对这张资源图片来说是应该把这张图片资源中的哪个点与我们设置的点对齐呢?这里就引出了锚点这个概念,我们通过设置锚点来确定资源图片上哪个点与我们设置位置点对齐。简而言之,锚点确定精灵自己在父节点的加载位置。

 

几何图形说明

上面的文字描述可能不太容易理解,下面作者发扬严谨的科研风格,绘图做以下说明:

假设我们要把一个精灵加载到场景中去,这个精灵上使用的图片资源是一张四边形图片,如下图所示

【Cocos2dx开发之锚点实例讲解】

 1

OK,当我们使用Cocos2dx下对应的API要给这个精灵设置一个特定的位置时,设置的结果是什么样的呢?这就与我们给定这个精灵的锚点有关,设置不同的锚点,加载结果也会不同。锚点的设置可以根据你的喜好随意设置,但是一般来说常用的锚点有哪些呢?如下图红色圈所表示的——左下角、左上角、右上角、右下角,在Cocos2dx中默认使用的锚点坐标是四边形的几何中心点。

【Cocos2dx开发之锚点实例讲解】

 2

 

Cocos2dx中,我们可以使用setAnchorPoint这个接口来设置锚点,参数是一个cocos2d::CCPoint类型,这个点是(0.0f,0.0f~1.0f1.0f)之间的一个值。

 

锚点Demo演示

我们在下面这个场景中来做测试,首先如下图所示,我们在这个场景中添加一个精灵A作为背景精灵:

加载代码:

                   // 添加背景资源

                   cocos2d::CCSprite* pBg = cocos2d::CCSprite::create("wndbg.png");

                   CC_BREAK_IF( !pBg );

                   pBg->setPosition(ccp(300.0f,300.0f));

                   this->addChild(pBg);

 

【Cocos2dx开发之锚点实例讲解】

 3

然后我们在这个精灵上开始增加另外一个精灵B作为测试精灵。

好,我们把测试精灵B的锚点设置为左下角(0.0f0.0f),然后加载到精灵A之上,如下图所示:

加载代码:

                   // 加载测试精灵

                   cocos2d::CCSprite* pTestSprite = cocos2d::CCSprite::create("bubble.png");

                   CC_BREAK_IF( !pTestSprite );

                   pTestSprite->setAnchorPoint(ccp(0.0f,0.0f));

                   pTestSprite->setPosition(ccp(0.0f,0.0f));

                   pBg->addChild(pTestSprite);

 

结果展示:

【Cocos2dx开发之锚点实例讲解】

 4

 

再看下面,我们把测试精灵B的锚点设置为中间(Cocos2dx中默认锚点也是如此),加载结果:

 

加载代码:

                   // 加载测试精灵

                   cocos2d::CCSprite* pTestSprite = cocos2d::CCSprite::create("bubble.png");

                   CC_BREAK_IF( !pTestSprite );

                   pTestSprite->setAnchorPoint(ccp(0.5f,0.5f));

                   pTestSprite->setPosition(ccp(0.0f,0.0f));

                   pBg->addChild(pTestSprite);

 

加载结果如下

【Cocos2dx开发之锚点实例讲解】

 5

 

下来呢,再把测试精灵B的锚点设置为右上角(1.0f1.0f),加载结果如下:

 

加载代码:

 

                   // 加载测试精灵

                   cocos2d::CCSprite* pTestSprite = cocos2d::CCSprite::create("bubble.png");

                   CC_BREAK_IF( !pTestSprite );

                   pTestSprite->setAnchorPoint(ccp(1.0f,1.0f));

                   pTestSprite->setPosition(ccp(0.0f,0.0f));

                   pBg->addChild(pTestSprite);

 

加载结果展示:

【Cocos2dx开发之锚点实例讲解】

 6

 

NICE,至此,我们可以看到,测试精灵B锚点设置不会影响它在背景精灵上的位置(这个位置只是根据setPosition接口来改变),只会影响测试精灵B本身的资源图片上的哪一点来与这个位置对齐。




=====================================

图层的旋转失败的案例

【http://blog.csdn.net/davidsu33/article/details/9849945】

cocos2dx中经常会用到节点的旋转,一旦涉及到物体的旋转则会涉及到旋转所相对的中心点的位置,对于CCNode而言,其提供了设置锚点的接口,用来设置锚点的相对位置。

见CCNode源代码中CCNode.cpp

[cpp] view plaincopy
  1. /// anchorPoint getter  
  2. const CCPoint& CCNode::getAnchorPoint()  
  3. {  
  4.     return m_obAnchorPoint;  
  5. }  
  6.   
  7. void CCNode::setAnchorPoint(const CCPoint& point)  
  8. {  
  9.     if( ! point.equals(m_obAnchorPoint))  
  10.     {  
  11.         m_obAnchorPoint = point;  
  12.         m_obAnchorPointInPoints = ccp(m_obContentSize.width * m_obAnchorPoint.x, m_obContentSize.height * m_obAnchorPoint.y );  
  13.         m_bTransformDirty = m_bInverseDirty = true;  
  14.     }  
  15. }  

其锚点的坐标值是一个相对值0~1,其中m_obAnchorPoint表示的是相对锚点坐标,m_obAnchorPointInPoints表示的是锚点在屏幕中的像素坐标,所以对于CCNode的坐标系转换会涉及到多种转换方式。

我们也可以通过设置ignoreAnchorPointForPosition来忽略锚点的作用。

对于图层而言其ignoreAnchorPointForPosition的默认值为false,CCSprite默认值为true,但是有时候大家会发现,即便咱们设置了图层的ignoreAnchorPointForPosition为false,但是图层的旋转仍然没有按照预定的结果来进行,原因是因为默认CCLayer的图层的大小为CCSize(0,0),所以不管你怎么设置图层的大小始终为(0,0),经过锚点比例进行计算之后其锚点的坐标仍然是(0,0),如下图所示:


但是设置了CCLayer的大小之后,就会发现,咱们设置的锚点就能起到作用了

[cpp] view plaincopy
  1. void LayerIgnoreAnchorPointPos::onEnter()  
  2. {  
  3.     LayerTest::onEnter();  
  4.       
  5.     bool ignore = this->isIgnoreAnchorPointForPosition();  
  6.     //this->ignoreAnchorPointForPosition(false);  
  7.     //CCSize layerSize = this->getContentSize();  
  8.     setContentSize(CCDirector::sharedDirector()->getWinSize());  
  9.     setAnchorPoint(ccp(0.5, 1));  
  10.     //CCSize layerSize2 = this->getContentSize();  
  11.     //CCPoint pt = this->getPosition();  
  12.     //setPosition(ccp(layerSize2.width/2, layerSize2.height/2));  
  13.   
  14.     CCSize s = CCDirector::sharedDirector()->getWinSize();  
  15.   
  16.     CCLayerColor *l = CCLayerColor::create(ccc4(255, 0, 0, 255), 150, 150);  
  17.   
  18.     l->setAnchorPoint(ccp(0.5f, 0.5f));  
  19.     l->setPosition(ccp( s.width/2, s.height/2));  
  20.   
  21.     CCMoveBy *move = CCMoveBy::create(2, ccp(100,2));  
  22.     CCMoveBy * back = (CCMoveBy *)move->reverse();  
  23.     CCSequence *seq = CCSequence::create(move, back, NULL);  
  24.     l->runAction(CCRepeatForever::create(seq));  
  25.     this->addChild(l, 0, kLayerIgnoreAnchorPoint);  
  26.   
  27.     CCSprite *child = CCSprite::create("Images/grossini.png");  
  28.     l->addChild(child);  
  29.     CCSize lsize = l->getContentSize();  
  30.     child->setPosition(ccp(lsize.width/2, lsize.height/2));  
  31.   
  32.     CCMenuItemFont *item = CCMenuItemFont::create("Toggle ignore anchor point"this, menu_selector(LayerIgnoreAnchorPointPos::onToggle));  
  33.   
  34.     CCMenu *menu = CCMenu::create(item, NULL);  
  35.     this->addChild(menu);  
  36.   
  37.     menu->setPosition(ccp(s.width/2, s.height/2));  
  38.   
  39.       
  40.     //this->setAnchorPoint(ccp(0.5, 0.5));  
  41.     CCDirector::sharedDirector()->getActionManager()->addAction(  
  42.                                                                             CCRepeatForever::create(  
  43.                                                                             CCSequence::create(CCRotateBy::create(2, 360),  
  44.                                                                             CCRotateBy::create(2, -360),  
  45.                                                                             0)  
  46.                                                                             ),  
  47.                                                                             this,  
  48.                                                                             false);  
  49. }  

0 0