2.cocos2d-x坐标体系(UI坐标系,GL坐标系,本地坐标,世界坐标,节点坐标)-阿里云开发者社区

开发者社区> 涂作权> 正文

2.cocos2d-x坐标体系(UI坐标系,GL坐标系,本地坐标,世界坐标,节点坐标)

简介:  openGL & UI坐标体系 OpenGL坐标系:该坐标原点在屏幕左下角,x轴向右,y轴向上。这也就是cocos2dx中用到的坐标系。     屏幕坐标系:该坐标系的原点在屏幕左上角,x轴向右,y轴向下,其实和OpenGL坐标系的差别也就是y轴的方向。假设游戏场景的分辨率为(500,500),其中一个点坐标为(200,200),那么它在Open
+关注继续查看

  1. openGL & UI坐标体系

OpenGL坐标系:该坐标原点在屏幕左下角,x轴向右,y轴向上。这也就是cocos2dx中用到的坐标系。

    屏幕坐标系:该坐标系的原点在屏幕左上角,x轴向右,y轴向下,其实和OpenGL坐标系的差别也就是y轴的方向。假设游戏场景的分辨率为(500500),其中一个点坐标为(200,200),那么它在OpenGL坐标系中的坐标还是(200,200),在屏幕坐标系中则倒过来,则为(200500-200)。其实也就是69的差别。

图: UI坐标系

图: GL坐标系

 

2 转化函数

CCDirector::sharedDirector()->convertToUI();

CCDirector::sharedDirector()->convertToGL();

节点坐标系:又名相对坐标系,本地坐标,和OpenGL坐标系方向一致,不同的是原点的父节点左下角。

世界坐标系:又名绝对坐标系,世界即指游戏世界,我们只要知道世界坐标系和OpenGL坐标系方向一致,原点在屏幕左下角,x轴向右,y轴向上。

 

节点坐标与世界坐标转化

 

几乎所有的游戏引擎都会使用本地坐标系而非世界坐标系来指定元素

的位置,这样做的好处是当计算物体运动的时候使用同一本地坐标系的元素

可以作为一个子系统独立计算,最后再加上坐标系的运动即可,这是物理研

究中常用的思路。例如一个在行驶的车厢内上下跳动的人,我们只需要在每

帧绘制的时候计算他在车厢坐标系中的位置,然后加上车的位置就可以计算

出人在世界坐标系中的位置,如果使用单一的世界坐标系,人的运动轨迹就

变复杂了。

 

3 关于坐标体系的案例:

Coordinate.h

#ifndef __COORDINATE_H__

#define __COORDINATE_H__

 

#include "cocos2d.h"

USING_NS_CC;

 

//坐标体系

class Coordinate :public CCLayer

{

public:

    static CCScene * scene();

    CREATE_FUNC(Coordinate);

    bool init();

 

    //触摸事件开始的一个事件,第二个参数只是为了做苹果的兼容才保留的

    virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);

};

 

#endif

Coordinate.cpp

#include "Coordinate.h"

#include "AppMacros.h"

 

CCScene * Coordinate::scene() {

    CCScene * scene = CCScene::create();

    Coordinate * layer = Coordinate::create();

    scene->addChild(layer);

    return scene;

}

 

bool Coordinate::init()

{

    CCLayer::init();

    //打开触摸开关

    setTouchEnabled(true);

   

    //下面的kCCTouchesOneByOne是一个枚举:

    //typedef enum {

    //  kCCTouchesAllAtOnce,

    //  kCCTouchesOneByOne,

    //} ccTouchesMode;

    setTouchMode(kCCTouchesOneByOne);

 

    //创建一个精灵

    CCSprite *big = CCSprite::create();

    big->setColor(ccRED);

    //设置锚点

    big->setAnchorPoint(ccp(0, 0));

    //表示的是一个矩形,CCRectMake是一个宏

    big->setTextureRect(CCRectMake(0,0,150,150));

    big->setPosition(ccp(100,100));

    addChild(big);

 

    CCSprite *little = CCSprite::create();

    little->setColor(ccYELLOW);

    little->setAnchorPoint(ccp(0,0));

    little->setTextureRect(CCRectMake(0, 0, 50, 50));

    little->setPosition(ccp(100,100));

    //从下面可以知道一个精灵中可以添加另外一个精灵

    big->addChild(little);

 

    CCLog("little x = %f,y = %f", little->getPositionX(), little->getPositionY());

    CCPoint toWorld = big->convertToWorldSpace(little->getPosition());

    CCLog("toWorld x = %f,y=%f", toWorld.x, toWorld.y);

 

    CCSprite *little2 = CCSprite::create();

    little2->setColor(ccGREEN);

    little2->setAnchorPoint(ccp(0, 0));

    little2->setTextureRect(CCRectMake(0,0,50,50));

    little2->setPosition(ccp(0,0));

    addChild(little2);

 

    CCPoint toNode = big->convertToNodeSpace(little2->getPosition());

    CCLog("little2 x = %f,y = %f", little2->getPositionX(), little2->getPositionY());

    CCLog("toNode x = %f,y = %f", toNode.x, toNode.y);

 

    CCMoveBy *by = CCMoveBy::create(2,ccp(200,0));

    CCMoveBy *by2 = (CCMoveBy *)by->reverse();

    //最后一个NULL是一个哨兵

    CCSequence *seq = CCSequence::create(by, by2, NULL);

    big->runAction(CCRepeatForever::create(seq));

   

    //第一个参数是:duration

    //第二个参数是:移动位置.表示上下移动

    CCMoveBy *lby = CCMoveBy::create(2, ccp(0, -100));

    CCMoveBy *lby2 = (CCMoveBy *)lby->reverse();

    CCSequence *lseq = CCSequence::create(lby, lby2, NULL);

 

    little->runAction(CCRepeatForever::create(lseq));

 

    return true;

}

 

//触摸事件开始

bool Coordinate::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)

{

    CCLog("ccTouchBegan");

    //基于OpenGL的世界坐标

    CCPoint pGl = pTouch->getLocation();

    CCLog("GL:x = %f,y = %f", pGl.x, pGl);

 

    //基于UI屏幕的坐标

    CCPoint pUi = pTouch->getLocationInView();

    CCLog("UI:x = %f,y = %f", pUi.x, pUi.y);

 

    //将基于GL的坐标转换成为UI的屏幕坐标

    CCPoint toUi = CCDirector::sharedDirector()->convertToUI(pGl);

    CCLog("ToUix = %f ,y = %f", toUi.x, toUi.y);

 

    //将屏幕坐标的转换成为本地坐标

    CCPoint toGL = CCDirector::sharedDirector()->convertToGL(pUi);

    CCLog("ToGLx = %f,y=%f", toGL.x, toGL.y);

 

    //转换成节点坐标

    CCPoint node = this->convertToNodeSpace(pGl);

    CCLog("Node:x = %f,y = %f", node.x, node.y);

 

    return false;

}

运行结果:

 

 

 

 

 

 

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
8495 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
10318 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
12172 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
11395 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
4553 0
Silverlight & Blend动画设计系列十:Silverlight中的坐标系统(Coordinate System)与向量(Vector)运动
原文:Silverlight & Blend动画设计系列十:Silverlight中的坐标系统(Coordinate System)与向量(Vector)运动   如果我们习惯于数学坐标系,那么对于Silverlight中的坐标系可能会有些不习惯。
925 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
6566 0
+关注
涂作权
java,架构,编程语言相关专家
1234
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载