在Cocos2d-x中坐标能够分成四种:
1、GL坐标体系:GL坐标体系左下角为坐标原点,X轴向右,Y轴向上
2、UI坐标体系:UI坐标体系左上角为坐标原点,X轴向右,Y轴向上。
3、世界坐标体系:是窗体的坐标体系,它是GL坐标体系,它是左下角为坐标原点,X轴向右,Y轴向上。
4、 结点坐标体系:是Node的坐标体系,它是GL坐标体系,和世界坐标体系不同的是,它的原点是结点的左下角,
当一个结点调用SetPosition时,使用的參数是它的父结点(渲染树)的坐标体系
CCLayer默认大小和窗体一样,所以他的坐标体系和世界坐标体系重合
CCScene默认大小和窗体一样,所以他的坐标体系和世界坐标
创建一个精灵,在不设置精灵的坐标时,精灵的默认坐标为(0,0),使用的是Node的父类坐标体系
由于 CCLayer默认大小和窗体一样,所以他的坐标体系和世界坐标体系重合,所以以下代码的精灵位于左下角
//初始化精灵 bool Coord::init() { //先调用父类的init函数 CCLayer::init(); //创建一个精灵 CCSprite* sprite = CCSprite::create("CloseNormal.png"); addChild(sprite); return true; }
运行结果:
创建一个精灵,设置精灵的坐标为(100,100),精灵的默认坐标为(0,0),使用的是父结点坐标体系,原因和上面的一样
//初始化精灵 bool Coord::init() { //先调用父类的init函数 CCLayer::init(); //创建一个精灵 CCSprite* sprite = CCSprite::create("CloseNormal.png"); addChild(sprite); //设置精灵的坐标为(100,100),结点坐标 sprite->setPosition(ccp(100, 100)); return true; }
运行结果:
在场景中创建一个红色的背景,并在背景上创建一个精灵
//初始化精灵 bool Coord::init() { //先调用父类的init函数 CCLayer::init(); //得到窗体的尺寸 CCSize winSize = CCDirector::sharedDirector()->getWinSize(); //创建一个背景颜色为红色的背景 CCLayerColor* layerColor = CCLayerColor::create(ccc4(255, 0, 0, 255), winSize.width/2, winSize.height/2); addChild(layerColor); //创建一个精灵 CCSprite* sprite = CCSprite::create("CloseNormal.png"); //将精灵加到红色背景上 layerColor->addChild(sprite); //设置精灵的坐标为(100,100)(是结点坐标体系) sprite->setPosition(ccp(100, 100)); return true; }
运行结果
程序解析:上面的代码实现了首先创建一个红色背景,然后在红色背景上添加一个精灵,再将精灵的坐标设置为(100,100),对于精灵,红色背景相当于精灵的父结点,所欲坐标原点位于红色背景的左下角,由于红色背景的坐标原点和窗体的坐标原点同和,所以精灵的位置没有发生变化
设置红色背景的坐标为(100,100)后的代码:
bool Coord::init() { //先调用父类的init函数 CCLayer::init(); //得到窗体的尺寸 CCSize winSize = CCDirector::sharedDirector()->getWinSize(); //创建一个背景颜色为红色的背景 CCLayerColor* layerColor = CCLayerColor::create(ccc4(255, 0, 0, 255), winSize.width/2, winSize.height/2); addChild(layerColor); //创建一个精灵 CCSprite* sprite = CCSprite::create("CloseNormal.png"); //将精灵加到红色背景上 layerColor->addChild(sprite); //设置精灵的坐标为(100,100)(是结点坐标体系) sprite->setPosition(ccp(100, 100)); //设置红色背景的坐标为(100,100) layerColor->setPosition(ccp(100, 100)); return true; }
运行结果:
程序解析:代码中设置了红色背景和精灵的坐标都为(100,100),由于红色背景是精灵的父类,所以红色背景的左下角为精灵的坐标原点
程序中的坐标转换:
1、UI坐标和世界坐标之间的转换
CCDirector::sharedDirector()->convertToUI();
CCDirector::sharedDirector()->convertToGL();
2、 世界坐标和节点坐标之间的转换
CCNode::convertToNodeSpace(CCPoint ptInWorld);
CCNode::convertToWorldSpace(CCPoint ptInNode);
3、依照锚点为原点来进行转换的方法
CCNode::convertToNodeSpaceAR(CCPoint ptInWorld); 这个函数返回的node坐标,是以锚点为原点
CCNode::convertToWorldSpaceAR(CCPoint ptInNode);
4、 用touch作为參数转换
CCNode::convertTouchToNodeSpace,直接将触摸转换成节点坐标系的坐标
实例:将精灵的结点坐标转换成世界坐标
程序代码:
bool Coord::init() { //先调用父类的init函数 CCLayer::init(); //得到窗体的尺寸 CCSize winSize = CCDirector::sharedDirector()->getWinSize(); //创建一个背景颜色为红色的背景 CCLayerColor* layerColor = CCLayerColor::create(ccc4(255, 0, 0, 255), winSize.width/2, winSize.height/2); //将红色背景添加到层上 addChild(layerColor); //创建一个精灵 CCSprite* sprite = CCSprite::create("CloseNormal.png"); //将精灵加到红色背景上 layerColor->addChild(sprite); //设置精灵的坐标为(100,100)(是结点坐标体系) sprite->setPosition(ccp(100, 100)); //设置红色背景的坐标为(100,100) layerColor->setPosition(ccp(100, 100)); //将精灵的坐标转为世界坐标用ptSpriteInWorld保存转换后的坐标 CCPoint ptSpriteInWorld = layerColor->convertToWorldSpace(sprite->getPosition()); //打印精灵转换后的世界坐标 CCLog("ptSpriteInWorld(%f,%f)", ptSpriteInWorld.x, ptSpriteInWorld.y); return true; }
运行结果:编译成功红在输出中会看到转换后的坐标为(200,200)
处理触摸事件,而且显示UI坐标
程序代码:
首先在Coord.h中加入以下的代码(Coord为创建的一个场景)
#ifndef _Coord_H_ #define _Coord_H_ //防止代码重包括 #include "cocos2d.h" USING_NS_CC; class Coord : public CCLayer { public: //创建一个场景 static CCScene* scene(); //初始化场景 bool init(); //菜单回调函数 void menuCloseCallback(CCObject* pSender); //响应触摸处理事件 bool ccTouchBegan(CCTouch*, CCEvent*); CCSprite* _sprite; //用于创建创建、精灵、或者层(同create()) CREATE_FUNC(Coord); }; #endif
然后在Coord.cpp中加入以下的代码
#include "Coord.h" #include "HelloWorldScene.h" CCScene* Coord::scene() { CCScene *scene = CCScene::create(); CCLayer *layer = Coord::create(); scene->addChild(layer); return scene; } bool Coord::init() { //先调用父类的init函数 CCLayer::init(); //得到窗体的尺寸 CCSize winSize = CCDirector::sharedDirector()->getWinSize(); //创建一个背景颜色为红色的背景 CCLayerColor* layerColor = CCLayerColor::create(ccc4(255, 0, 0, 255), winSize.width/2, winSize.height/2); //将红色背景添加到层上 addChild(layerColor); //创建一个精灵 CCSprite* sprite = CCSprite::create("CloseNormal.png"); //将精灵赋值给全局变量 _sprite = sprite; //将精灵加到红色背景上 layerColor->addChild(sprite); //设置精灵的坐标为(100,100)(是结点坐标体系) sprite->setPosition(ccp(100, 100)); //设置红色背景的坐标为(100,100) layerColor->setPosition(ccp(100, 100)); //将精灵的坐标转为世界坐标用ptSpriteInWorld保存转换后的坐标 CCPoint ptSpriteInWorld = layerColor->convertToWorldSpace(sprite->getPosition()); //打印精灵转换后的世界坐标 CCLog("ptSpriteInWorld(%f,%f)", ptSpriteInWorld.x, ptSpriteInWorld.y); // 加一个触摸处理,来演示UI坐标和GL坐标的转换 setTouchEnabled(true); setTouchMode(kCCTouchesOneByOne); return true; } //响应触摸处理事件 bool Coord::ccTouchBegan(CCTouch* touch, CCEvent*) { //得到触摸点的UI坐标 CCPoint ptInUI = touch->getLocationInView(); //得到触摸点的世界坐标 CCPoint ptInGL = touch->getLocation(); //将UI坐标转换为GL坐标 CCPoint ptUIConvert = CCDirector::sharedDirector()->convertToGL(ptInUI); //打印触摸点的UI坐标 CCLog("ptInUI(%f, %f)", ptInUI.x, ptInUI.y); //打印触摸点的GL坐标 CCLog("ptInGL(%f, %f), ptConvert(%f, %f)", ptInGL.x, ptInGL.y, ptUIConvert.x, ptUIConvert.y); //获取精灵所在的矩形 CCRect rc = _sprite->boundingBox(); // _sprite->getParent()->convertToNodeSpace(touchPoint) 将touch转换成精灵的父节点的坐标体系内的坐标点 //if (rc.containsPoint(_sprite->getParent()->convertToNodeSpace(touchPoint))) if (rc.containsPoint(_sprite->getParent()->convertTouchToNodeSpace(touch))) { CCLog("Oh I am touched"); } return true; }
运行结果:
1、当鼠标点击红色矩形框中的精灵时(提示触摸到了精灵)
2、当鼠标没有点击精灵时