cocos2d-x快乐的做让人快乐的游戏2:坐标系大集合

    cocos2d中,涉及到4种坐标系:


  • GL坐标系Cocos2D以OpenglES为图形库,所以它使用OpenglES坐标系。GL坐标系原点在屏幕左下角,x轴向右,y轴向上

  • 屏幕坐标系苹果的Quarze2D使用的是不同的坐标系统,原点在屏幕左上角,x轴向右,y轴向下
    ios的屏幕触摸事件CCTouch传入的位置信息使用的是该坐标系。因此在cocos2d中对触摸事件做出响应前需要首先把触摸点转化到GL坐标系。可以使用CCDirector的convertToGL来完成这一转化。

  • 世界坐标系也叫做绝对坐标系。世界坐标系和GL坐标系一致,原点在屏幕左下角
    cocos2d中的元素是有父子关系的层级结构,我们通过CCNode的position设定元素的位置使用的是相对与其父节点的本地坐标系而非世界坐标系。最后在绘制屏幕的时候cocos2d会把这些元素的本地坐标映射成世界坐标系坐标。

  • 本地坐标系 相对于父对象的坐标。

[obj.parent convertToWorldSpace:[obj position]];  //获得obj的世界坐标
[obj.parent convertToNodeSpace:[obj position]];  //获得obj的本地坐标
[[CCDirector sharedDirector] convertToGL:*****(0,0)];  //获得GL坐标
[[CCDirector sharedDirector] convertToUI:*****(0,0)];  //获得屏幕坐标

     无论是搞2d还是3d开发,最需要搞清楚的就是坐标系,这部分混乱的话就没啥奔头了。所以玩cocos2d,一上来就先把各种与坐标有关的东西搞清楚。
  基本的两个坐标系:屏幕坐标系和GL坐标系。
  屏幕坐标系x轴朝右,y轴朝下。默认原点在左上角。
  GL坐标系x轴朝右,y轴朝上。默认原点在左下角。
  在调用任何需要设置位置的函数,或从函数获取位置信息前,必须要明确这个函数使用哪个坐标系。比如调用CCNode类的setPosition函数,它使用的就是GL坐标系。比如在处理触摸事件时CCTouch对象中的坐标就是屏幕坐标系。
  比较用的多的坐标系是和Node相关的本地坐标系。这个结构和一般做3D用的场景树的概念是一样的。所以从Node拿到的位置是该节点的本地坐标,需要通过特定的函数才能把本地坐标转换为世界坐标。而且这里的坐标都用的是GL坐标系。在CCNode对象中有几个方便的函数可以做坐标转换。convertToWorldSpace方法可以把基于当前node的本地坐标系下的坐标转换到世界坐标系中。convertToNodeSpace方法可以把世界坐标转换到当前node的本地坐标系中。
  另外顺便说下点击命中问题,这会涉及到一些坐标系的相互转换,同时这里也不得不稍微提下cocos2d里面各种对象的大小问题。因为在cocos2d里CCNode对象有缩放的方法setScaleX和setScaleY。所以在获取对象大小的时候就必须根据情况明确指定获取对象原始大小,还是缩放后的大小。当然cocos2d里提供了对应的函数来完成这些操作。
  getContentSize 函数用来获得节点原始的大小。
  boundingBox 函数用来获得经过缩放和旋转之后的外框盒大小。
  举个简单的例子:
  bool ret = CCRect::CCRectContainsPoint(
  this->boundingBox() , this->getParent()->convertTouchToNodeSpace( pTouch ));
  这个例子的功能是来判定当前的触摸操作是否发生在自己的node对象上。其中pTouch是CCTouch对象的指针,包含了当前触摸事件发生点的坐标。
  CCRectContainsPoint这个函数用来判断一个点是否在一个矩形范围内。我们就想用这个函数来判断当前触摸操作的这个点是否在当前node的范围内。
  this->boundingBox() 方法获得了当前节点对象在父节点对象下的缩放之后的本地坐标大小,并且是用GL坐标系表示的。
  pTouch对象中的坐标是屏幕坐标系,所以必须转换到GL坐标系,再转换到父节点的本地坐标下。好在convertTouchToNodeSpace这个函数一次完成了这两个转换,可以参考该库的源码,其中有具体的计算过程。
  所有数据都转换到同一个坐标系下了以后,就可以通过CCRectContainsPoint函数完成最终的判定操作。
  最后想说的一点是,尽可能用相对坐标。换句话说,程序中所有对象在设置大小和位置时,都应该以父对象的大小和位置为依据。 这样程序发布在以各种不同的分辨率发布时,只需要调整根对象的大小就可以了。


     结尾顺便说下cocos2dx判断点击命中的几种方法:

[cpp]  view plain copy
  1. //重载  
  2. virtual bool ccTouchBegan(CCTouch *touch, CCEvent *pEvent);  
  3. virtual void ccTouchMoved(CCTouch *touch, CCEvent *pEvent);  
  4. virtual void ccTouchEnded(CCTouch *touch, CCEvent *pEvent);  
  5. virtual void onEnter();  
  6. virtual void onExit();  
  7.   
  8. //添加支持触摸事件  
  9. void CTestLayer::onEnter()  
  10. {  
  11. CCLayer::onEnter();  
  12. this->setTouchEnabled(true);  
  13. CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);  
  14. }  
  15.   
  16. void CTestLayer::onExit()  
  17. {  
  18. CCLayer::onExit();  
  19.     CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);  
  20. }  
  21.   
  22. //用自己的坐标系相对于原点进行判断  
  23. bool checkTouchInSelf(CCTouch *touch);  
  24. //用自己的坐标系相对于锚点进行判断  
  25. bool checkTouchInSelf_AR(CCTouch *touch);  
  26. //用父元素坐标系及自己在父坐标中的位置进行判断  
  27. bool checkTouchInSelf_Parent(CCTouch *touch);  
  28.   
  29. //______________________________________________________________________________________________  
  30. //用自己的坐标系相对于原点进行判断  
  31. bool CTestLayer::checkTouchInSelf(CCTouch *touch)  
  32. {  
  33. //方案一  
  34. //将点击点转换成自己坐标系中的坐标,相对于0,0点  
  35. CCPoint pt = convertTouchToNodeSpace(touch);  
  36. printf("pt.x=%.1f pt.y=%.1f\n", pt.x, pt.y);  
  37. int nw = getContentSize().width;  
  38. int nh = getContentSize().height;  
  39. CCRect rc(0, 0, nw, nh);  
  40. if(rc.containsPoint(pt))  
  41. {  
  42. //获得点击的OpenGL的世界坐标值  
  43. CCPoint touchPoint = touch->getLocation();  
  44. printf("ccTouchBegan x=%.1f y=%.1f\n", touchPoint.x, touchPoint.y);  
  45. return true;  
  46. }  
  47. return false;  
  48. }  
  49. //______________________________________________________________________________________________  
  50. //用自己的坐标系相对于锚点进行判断  
  51. bool CTestLayer::checkTouchInSelf_AR(CCTouch *touch)  
  52. {  
  53. //方案二  
  54. //将点击点转换成自己坐标系中的坐标,相对于锚点  
  55. CCPoint ptAR = convertTouchToNodeSpaceAR(touch);  
  56. printf("ptAR.x=%.1f ptAR.y=%.1f\n", ptAR.x, ptAR.y);  
  57. CCPoint pp = this->getAnchorPoint();  
  58. int nw = getContentSize().width;  
  59. int nh = getContentSize().height;  
  60. int nx = -(nw * pp.x);  
  61. int ny = -(nh * pp.y);  
  62. CCRect rcar(nx, ny, nw, nh);  
  63. if(rcar.containsPoint(ptAR))  
  64. {  
  65. //获得点击的OpenGL的世界坐标值  
  66. CCPoint touchPoint = touch->getLocation();  
  67. printf("ccTouchBegan x=%.1f y=%.1f\n", touchPoint.x, touchPoint.y);  
  68. return true;  
  69. }  
  70. return false;  
  71. }  
  72. //______________________________________________________________________________________________  
  73. //用父元素坐标系及自己在父坐标中的位置进行判断  
  74. bool CTestLayer::checkTouchInSelf_Parent(CCTouch *touch)  
  75. {  
  76. //方案三  
  77. //获得点击的OpenGL的世界坐标值  
  78. CCPoint touchPoint = touch->getLocation();  
  79. //将点击的位置转换成父元素坐标系中的相对坐标  
  80. CCPoint pt=getParent()->convertToNodeSpace(touchPoint);  
  81. printf("pt.x=%.1f, pt.y=%.1f\n", pt.x, pt.y);  
  82. //得到自己在父元素坐标系中的位置范围  
  83. CCRect rect=boundingBox();  
  84. printf("rect.l=%.1f, rect.b=%.1f, rect.r=%.1f, rect.t=%.1f\n",\  
  85. rect.getMinX(), rect.getMinY(), rect.getMaxX(), rect.getMaxY());      
  86. //判断是否点击落在自己的范围当中, 以上判断全是在父元素坐标系中进行计算  
  87. if(rect.containsPoint(pt))  
  88. {  
  89. printf("ccTouchBegan x=%.1f y=%.1f\n", touchPoint.x, touchPoint.y);  
  90. return true;  
  91. }  
  92. return false;  
  93. }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: cocos2d-x是一款流行的开源游戏引擎,它可以用作开发本地移动游戏和桌面游戏。利用cocos2d-x游戏源码,开发人员可以快速构建流畅、高效、具有吸引力的游戏。该引擎使用C ++语言和脚本语言Lua来实现游戏开发,用户可以根据自己的需要进行选择。 cocos2d-x游戏源码包含许多强大的功能和工具,例如精灵、动画、场景管理、碰撞检测和音频控制等。通过这些功能,开发人员可以方便地创建各种类型的游戏,例如动作游戏、射击游戏、冒险游戏和益智游戏等。 此外,cocos2d-x游戏源码还具有高度定制化的特性,允许开发人员根据他们的需求自定义游戏元素。这种定制化可以通过改进游戏画面,添加新的模式和关卡,甚至整个新的游戏玩法来完成。 总之,cocos2d-x游戏源码是一款功能强大、易于使用和高度定制的游戏引擎,它可以帮助开发人员快速开发各种类型的游戏。无论你是专业开发人员还是无经验的游戏制作者,cocos2d-x都是一个极好的选择。 ### 回答2: Cocos2d-x游戏源码是使用Cocos2d-x引擎进行开发游戏程序代码。Cocos2d-x引擎是一个开源的跨平台游戏引擎,可以支持iOS、Android、Windows Phone、Windows、MacOS和Linux等多个平台,并且提供了丰富的游戏开发API和工具集。Cocos2d-x游戏源码包含了游戏的核心逻辑、UI设计、动画效果、音频效果等各方面的代码,可以作为开发者学习和借鉴的重要资料。 由于Cocos2d-x引擎支持多种编程语言(如C++、Lua等),因此Cocos2d-x游戏源码也会有对应的编程语言版本。开发者可以通过阅读Cocos2d-x游戏源码,了解游戏开发过程中的技术细节,学习如何使用Cocos2d-x引擎进行游戏开发。同时,开发者也可以通过对Cocos2d-x游戏源码进行修改和优化,来满足游戏的特定需求,提升游戏的性能和用户体验。 总之,Cocos2d-x游戏源码是游戏开发者必备的重要资源,可以帮助开发者更好地了解游戏开发技术,提升游戏开发水平。 ### 回答3: cocos2d-x是一款优秀的游戏开发引擎,其源码包含了许多功能强大的游戏开发工具和API。使用cocos2d-x可以帮助开发者更快速更高效地开发出优秀的游戏作品。 cocos2d-x游戏源码非常丰富,其包含了许多不同类型的游戏示例和模板,如平面射击、塔防、解谜等,这些示例可以帮助开发者更好地了解cocos2d-x的使用方法和原理。 cocos2d-x的源码还包含了许多强大的API和工具,例如场景管理、动画控制、音频引擎等,这些工具和API能够帮助开发者更好地完成游戏开发和调试。 此外,cocos2d-x的源码还提供了完整的游戏开发框架,包括资源管理、内存管理、事件机制等,这些框架可以帮助开发者更好地组织代码和提高代码的可维护性。 总的来说,cocos2d-x游戏源码提供了丰富的工具和API,可以帮助开发者更高效地进行游戏开发,大大降低了开发难度和成本,是一款非常适合游戏开发者使用的引擎。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值