opengl & ui坐标體系
opengl坐标系:該坐标原點在螢幕左下角,x軸向右,y軸向上。這也就是cocos2dx中用到的坐标系。
螢幕坐标系:該坐标系的原點在螢幕左上角,x軸向右,y軸向下,其實和opengl坐标系的差别也就是y軸的方向。假設遊戲場景的分辨率為(500,500),其中一個點坐标為(200,200),那麼它在opengl坐标系中的坐标還是(200,200),在螢幕坐标系中則倒過來,則為(200,500-200)。其實也就是6和9的差别。
圖: ui坐标系
圖: gl坐标系
2
轉化函數
ccdirector::shareddirector()->converttoui();
ccdirector::shareddirector()->converttogl();
節點坐标系:又名相對坐标系,本地坐标,和opengl坐标系方向一緻,不同的是原點的父節點左下角。
世界坐标系:又名絕對坐标系,世界即指遊戲世界,我們隻要知道世界坐标系和opengl坐标系方向一緻,原點在螢幕左下角,x軸向右,y軸向上。
節點坐标與世界坐标轉化
幾乎所有的遊戲引擎都會使用本地坐标系而非世界坐标系來指定元素
的位置,這樣做的好處是當計算物體運動的時候使用同一本地坐标系的元素
可以作為一個子系統獨立計算,最後再加上坐标系的運動即可,這是實體研
究中常用的思路。例如一個在行駛的車廂内上下跳動的人,我們隻需要在每
幀繪制的時候計算他在車廂坐标系中的位置,然後加上車的位置就可以計算
出人在世界坐标系中的位置,如果使用單一的世界坐标系,人的運動軌迹就
變複雜了。
3
關于坐标體系的案例:
coordinate.h
#ifndef
__coordinate_h__
#define
#include
"cocos2d.h"
using_ns_cc;
//坐标體系
class
coordinate :public
cclayer
{
public:
static
ccscene *
scene();
create_func(coordinate);
bool
init();
//觸摸事件開始的一個事件,第二個參數隻是為了做蘋果的相容才保留的
virtual
cctouchbegan(cctouch
*ptouch,
ccevent *pevent);
};
#endif
coordinate.cpp
"coordinate.h"
"appmacros.h"
coordinate::scene()
scene =
ccscene::create();
coordinate *
layer =
coordinate::create();
scene->addchild(layer);
return
scene;
}
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
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
little2->setcolor(ccgreen);
little2->setanchorpoint(ccp(0,
little2->settexturerect(ccrectmake(0,0,50,50));
little2->setposition(ccp(0,0));
addchild(little2);
tonode =
big->converttonodespace(little2->getposition());
cclog("little2
little2->getpositionx(),
little2->getpositiony());
cclog("tonode
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,
little->runaction(ccrepeatforever::create(lseq));
true;
//觸摸事件開始
coordinate::cctouchbegan(cctouch
ccevent *pevent)
cclog("cctouchbegan");
//基于opengl的世界坐标
pgl =
ptouch->getlocation();
cclog("gl:x
= %f,y = %f",
pgl.x,
pgl);
//基于ui螢幕的坐标
pui =
ptouch->getlocationinview();
cclog("ui:x
pui.x,
pui.y);
//将基于gl的坐标轉換成為ui的螢幕坐标
toui =
ccdirector::shareddirector()->converttoui(pgl);
cclog("touix
= %f ,y = %f",
toui.x,
toui.y);
//将螢幕坐标的轉換成為本地坐标
togl =
ccdirector::shareddirector()->converttogl(pui);
cclog("toglx
= %f,y=%f",
togl.x,
togl.y);
//轉換成節點坐标
node =
this->converttonodespace(pgl);
cclog("node:x
node.x,
node.y);
false;
運作結果: