Cocos2dx开发之锚点实例讲解

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

锚点概念

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

几何图形说明

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

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

图 1

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

图 2

在Cocos2dx中,我们可以使用setAnchorPoint这个接口来设置锚点,参数是一个cocos2d::CCPoint类型,这个点是(0.0f,0.0f)~(1.0f,1.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);

图 3

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

好,我们把测试精灵B的锚点设置为左下角(0.0f,0.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);

结果展示:

图 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);

加载结果如下

图 5

下来呢,再把测试精灵B的锚点设置为右上角(1.0f,1.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);

加载结果展示:

图 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. void CCNode::setAnchorPoint(const CCPoint& point)
  7. {
  8. if( ! point.equals(m_obAnchorPoint))
  9. {
  10. m_obAnchorPoint = point;
  11. m_obAnchorPointInPoints = ccp(m_obContentSize.width * m_obAnchorPoint.x, m_obContentSize.height * m_obAnchorPoint.y );
  12. m_bTransformDirty = m_bInverseDirty = true;
  13. }
  14. }

其锚点的坐标值是一个相对值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. bool ignore = this->isIgnoreAnchorPointForPosition();
  5. //this->ignoreAnchorPointForPosition(false);
  6. //CCSize layerSize = this->getContentSize();
  7. setContentSize(CCDirector::sharedDirector()->getWinSize());
  8. setAnchorPoint(ccp(0.5, 1));
  9. //CCSize layerSize2 = this->getContentSize();
  10. //CCPoint pt = this->getPosition();
  11. //setPosition(ccp(layerSize2.width/2, layerSize2.height/2));
  12. CCSize s = CCDirector::sharedDirector()->getWinSize();
  13. CCLayerColor *l = CCLayerColor::create(ccc4(255, 0, 0, 255), 150, 150);
  14. l->setAnchorPoint(ccp(0.5f, 0.5f));
  15. l->setPosition(ccp( s.width/2, s.height/2));
  16. CCMoveBy *move = CCMoveBy::create(2, ccp(100,2));
  17. CCMoveBy * back = (CCMoveBy *)move->reverse();
  18. CCSequence *seq = CCSequence::create(move, back, NULL);
  19. l->runAction(CCRepeatForever::create(seq));
  20. this->addChild(l, 0, kLayerIgnoreAnchorPoint);
  21. CCSprite *child = CCSprite::create("Images/grossini.png");
  22. l->addChild(child);
  23. CCSize lsize = l->getContentSize();
  24. child->setPosition(ccp(lsize.width/2, lsize.height/2));
  25. CCMenuItemFont *item = CCMenuItemFont::create("Toggle ignore anchor point", this, menu_selector(LayerIgnoreAnchorPointPos::onToggle));
  26. CCMenu *menu = CCMenu::create(item, NULL);
  27. this->addChild(menu);
  28. menu->setPosition(ccp(s.width/2, s.height/2));
  29. //this->setAnchorPoint(ccp(0.5, 0.5));
  30. CCDirector::sharedDirector()->getActionManager()->addAction(
  31. CCRepeatForever::create(
  32. CCSequence::create(CCRotateBy::create(2, 360),
  33. CCRotateBy::create(2, -360),
  34. 0)
  35. ),
  36. this,
  37. false);
  38. }

Cocos2dx开发之锚点相关推荐

  1. 【Cocos2dx开发】精灵

    [Cocos2dx开发]精灵 写在前面--有不对的地方,烦请大家批评指正,我也会继续努力提高自己.如果转载请注明出处,谢谢大家支持--Forward.                         ...

  2. Cocos2d-X开发教程-捕鱼达人-欧阳坚-专题视频课程

    Cocos2d-X开发教程-捕鱼达人-24521人已学习 课程介绍         本次视频全程以捕鱼达人为项目案例讲述如何使用Cocos2d-X来开发这样一款游戏.本次视频使用了主流的C++开发语言 ...

  3. cocos2d-x开发中wstring和string的转换

    cocos2d-x开发中汉字操作技术是必须要面对的,其中可能要用到wstring和string的相互转换.我在网络上搜索到的能够应用于android 和WIN32(其他的平台没有试)环境下的汉字的可选 ...

  4. 用Cocos2dx开发棋牌游戏的观点解析

    众所周知,目前棋牌游戏特别的火.很多游戏公司都想在这一块赚钱,可是却不知用什么软件比较好的去开发棋牌游戏,对此,我列出了两款比较靠谱的软件去开发棋牌游戏,希望对大家有帮助! 第一款软件是cocos2d ...

  5. [cocos2dx开发技巧4]工具CocosBuilder的使用--复杂动画

    转发,请保持地址:http://blog.csdn.net/stalendp/article/details/8760957 一个网友推荐过一款制作动画的工具,叫做 Spriter: 其中有个Demo ...

  6. 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第九节:卡通渲染

    <使用Cocos2d-x 开发3D游戏>系列在线课程 第九节:卡通渲染 视频地址:http://edu.csdn.net/course/detail/1330/20809?auto_sta ...

  7. 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第十九节:雾

    <使用Cocos2d-x 开发3D游戏>系列在线课程 第十九节:雾 视频地址:http://edu.csdn.net/course/detail/1330/20819?auto_start ...

  8. 锯齿数独 cocos2d-x 开发 (一)

    先放一张游戏截图: 实现功能: 1.两种模式,普通数独和锯齿数独 2.不使用题库,数字及锯齿均纯随机生成,有且仅有唯一解. 3.难度控制. 4.生成时间控制在1s内(ipad mini2) 一.生成普 ...

  9. 锯齿数独 cocos2d-x 开发 (二)

    锯齿数独 cocos2d-x 开发 (一) 二.锯齿的生成 1.9*9的格子划分成9个随机形状的连通块. 这里采用了bfs + 并查集的算法. 在bfs生成连通块的同时,检测整个图所有的联通分量, 一 ...

最新文章

  1. 两篇大而全的SLAM综述
  2. 我做SAP CRM One Order redesign的一些心得体会
  3. 【ArcGIS风暴】ArcGIS获取一个省各个地区界内的河流的总长度--以甘肃省为例
  4. https证书/即SSL数字证书申请途径和流程
  5. Leetcode--289. 生命游戏
  6. PHP读取某站点的链接的函数
  7. set up BU Printer on ubuntu
  8. html网页字段序号的样式,[网页设计]局部自定义li序号CSS样式的方法
  9. 阿里云对象存储OSS访问控制
  10. 3.基于Golang协程实现流量统计系统-快速构建一个示例网站
  11. 浅谈大数据里的Kafka (9)Kafka的消费方式和消费策略
  12. 深度学习之图像分类(九)--ResNeXt 网络结构
  13. 2019年大学生智能车大赛室外光电组+在ROS下搭建仿真模拟环境,编程控制小车完成定位导航仿真
  14. Android传感器、语音识别、定位系统、Google Map API、快捷方式、widget编程总结及示例...
  15. 50天计算机考研数学,50天数学冲刺:那些hold住高分的诀窍
  16. 软考有什么用?最全软考详解
  17. C++解决猴子吃桃问题(详细)
  18. QT图片处理+文字处理
  19. GitOps 与 ChatOps 的落地实践
  20. 艾赛克科技《RFID智能仓库管理系统》

热门文章

  1. 如何在Windows、Linux中获取主机的网络信息和公网地址
  2. [C#基础]c#中的BeginInvoke和EndEndInvoke
  3. Oracle命令(二):Oracle数据库几种启动和关闭方式
  4. 快速排序算法的简短描述
  5. 一次网站性能排查的经历
  6. java 日期及别的小技巧
  7. 请求页式存储管理中页面置换算法的模拟设计_操作系统-存储管理与文件管理-笔记...
  8. cp文件服务器,docker容器与物理机的文件传输—docker cp命令
  9. gitchat 会员值得买么_小米雷军亲自站台,599元的星特朗天文望远镜值得买么?...
  10. jdba怎么连接mysql_一、JAVA通过JDBC连接mysql数据库(连接)