一个简单实例理解cocos2d-x触摸事件中的坐标系

有关cocos2d-x的坐标系一直以来都是很复杂的概念,不容易理解,而坐标系用的最多的地方就是触摸事件的处理。 看人家写的代码经常用到
getLocationInView, convertToGL, 还有convertToNodeSpace 这一堆函数都头痛死了,这些函数是干马用的?到底怎么用呢?相信吓坏了一大批新手,网上查不是讲的不甚明了就是原理说的太过复杂不知要领,现在举个简单例子加以说明
首先要理解4个坐标系,这个是省不了的。

(1)OpenGL坐标系

Cocos2D-x以OpenGL和OpenGL ES为基础,所以自然用的是OpenGL坐标系。该坐标系原点在屏幕左下角,x轴向右,y轴向上。

(2)屏幕坐标系

屏幕坐标系使用的是不同的坐标系统,它是windows开发或者几何数学常用的坐标系统,可惜Cocos2d-x处理位置信息时不用这个坐标系。所以从实际问题转换到2dx中经常要碰到屏幕坐标转OpenGL坐标系的问题,屏幕坐标系的原点在屏幕左上角,x轴向右,y轴向下。iOS的屏幕触摸事件是个特例,它的CCTouch传入的位置信息使用的是该坐标系。因此在Cocos2D-x中对触摸事件做出响应前,需要首先把触摸点转化到OpenGL坐标系。这一点在后面的触屏信息中会详细介绍,可以使用CCDirector的convertToGL方法来完成这一转化。

①从触摸点获取到在屏幕坐标系中的坐标 
// returns the current touch location in screen coordinates
CCPoint CCTouch::getLocationInView() const 
{ 
    return m_point; 
}

②从触摸点获取到在OpenGL坐标系中的坐标
// returns the current touch location in OpenGL coordinates
CCPoint CCTouch::getLocation() const
{ 
    return CCDirector::sharedDirector()->convertToGL(m_point); 
}
(3)世界坐标系统

世界坐标系也叫作绝对坐标系,是游戏开发中建立的概念,因此,“世界”即是游戏世界。它建立了描述其他坐标系所需要的参考标准。我们能够用世界坐标系来描述其他坐标系的位置。它是Cocos2D-x中一个比较大的概念。

Cocos2D-x中的元素是有父子关系的层级结构。通过CCNode设置位置使用的是相对其父节点的本地坐标系,而非世界坐标系。最后在绘制屏幕的时候,Cocos2D-x会把这些元素的本地节点坐标映射成世界坐标系坐标。世界坐标系和OpenGL坐标系方向一致,原点在屏幕左下角,x轴向右,y轴向上。

(4)节点坐标系统

节点坐标系是和特定节点相关联的坐标系。每个节点都有独立的坐标系。当节点移动或改变方向时,和该节点关联的坐标系(它的子节点)将随之移动或改变方向。这一切都是相对的,相对于基准的,只有在节点坐标系中才有意义。

CCNode类的设置位置使用的就是父节点的节点坐标系。它和OpenGL坐标系的方向也是一致的,x轴向右,y轴向上,原点在父节点的左下角。如果父节点是场景树中的顶层节点,那么它使用的节点坐标系就和世界坐标系重合了

实例:
void MyLayer::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) {
    // 获取单点
    CCTouch *pTouch = (CCTouch*)(pTouches->anyObject());

    // 所有点
    for(CCSetIterator iterTouch = pTouches->begin(); iterTouch != pTouches->end(); iterTouch++) {
        CCTouch *pCurTouch =  (CCTouch*)(*iterTouch);
    }

    // 先获取点在视图中的屏幕坐标(左上角为原点)
    CCPoint touchLocation = pTouch->getLocationInView();
    // 再把点的坐标转换成OpenGL坐标(左下角为原点)
    touchLocation = CCDirector::sharedDirector()->convertToGL(touchLocation);
    // 把OpenGL的坐标转换成CCLayer的本地坐标系,原点为精灵锚点所在
    CCPoint local = convertToNodeSpace(touchLocation)
    // 大小为100x100,坐标为(0, 0)的矩形
    CCRect * rect = CCRectMake(0, 0, 100, 100);
    // 判断该触摸点是否在rect矩形内
    bool flag = rect.containsPoint(local)
    if(flag) {
        // 回调
    } else {
        // 不执行
    }
}
可看出最后那个rect几乎就是个常量,它的0,0就是本地坐标系原点,此rect很可能就是精灵的包围盒,把触摸点转换到本地坐标系后如此简单不用再计算它跟着精灵在世界坐标走的具体位置了,这就是坐标转换的妙用.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天马流星2719

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值