cocos2dx簡單實(shí)現(xiàn)自己的一套u(yù)i
來源:程序員人生 發(fā)布時(shí)間:2015-01-06 08:07:39 閱讀次數(shù):3880次
版本:2.x
目標(biāo):基于cocos2dx底層實(shí)現(xiàn)1個(gè)自己簡單的1套的ui,改屏幕坐標(biāo)原點(diǎn)為右上角。
首先我們通過繼承CCNodeRGBA來實(shí)現(xiàn)自己的基類,為何要繼承CCNodeRGBA而不是CCNode,由于CCNodeRGBA有對(duì)node的色彩與透明度的設(shè)置
#pragma once
#include "cocos2d.h"
class View:public cocos2d::CCNodeRGBA
{
public:
View(void);
~View(void);
void draw();
void setPosition(cocos2d::CCPoint & pos);
};
#include "View.h"
using namespace cocos2d;
View::View(void)
{
this->setAnchorPoint(ccp(0,1));
this->ignoreAnchorPointForPosition(true);//
setCascadeColorEnabled(true); //開啟ccnodergba的色彩設(shè)置
setCascadeOpacityEnabled(true); //開啟ccnodergba的透明度設(shè)置
}
View::~View(void)
{
}
void View::draw()
{
//ccDrawLine(ccp(0,0), ccp(200,200));
//CCNode::draw();
glLineWidth(2.0f);
ccDrawColor4B(0,255,0,255);
ccDrawRect(ccp(0,0),ccp(getContentSize().width, -getContentSize().height));
}
void View::setPosition(cocos2d::CCPoint & pos)
{
CCNodeRGBA::setPosition(ccp(pos.x, -pos.y));
}
說1下:ignoreAnchorPointForPosition
cocos2dx1個(gè)node有兩個(gè)點(diǎn),
1個(gè)是錨點(diǎn),與父級(jí)相干,父級(jí)會(huì)根據(jù)這個(gè)點(diǎn)設(shè)置該node的位置。
另外一個(gè)是原點(diǎn),與子級(jí)相干,子級(jí)設(shè)置位置會(huì)以這個(gè)點(diǎn)為標(biāo)準(zhǔn),這個(gè)默許為node的左下角。
所以你設(shè)置node的 錨點(diǎn)(setAnchorPoint(ccp(0,1));)其實(shí)不會(huì)修改到原點(diǎn),哪怎樣樣才能讓原點(diǎn)隨著錨點(diǎn)的位置變,就是ignoreAnchorPointForPosition(true),這句話。
例子:現(xiàn)在畫的框已相當(dāng)于view的子節(jié)點(diǎn)了
先看下創(chuàng)建代碼:(寫在helloworld.cpp里就能夠)
View *xx = new View;
xx->setContentSize(CCSize(150,150));
xx->CCNodeRGBA::setPosition(ccp(200,200));
this->addChild(xx, 0);
Image *img = new Image;
img->create("close2.png");
img->setPosition(ccp(0,10));
xx->addChild(img);
先看1下沒注釋view 沒注釋ignoreAnchorPointForPosition(true),的效果,很明顯是以左上角對(duì)齊的

看1下,注釋ignoreAnchorPointForPosition(true)的效果,由于我設(shè)置位置是200,200, 寬度是150,150,框是向下畫的,所以在屏幕上面露出50像素的高度,很明顯框是左下角對(duì)齊來畫的。

實(shí)現(xiàn)坐標(biāo)點(diǎn)為右上角的原理:首先我們先把view的錨點(diǎn)與原點(diǎn)設(shè)置為右上角,重寫draw方法,畫1個(gè)關(guān)于X翻轉(zhuǎn)過的框,-getContentSize.height,實(shí)際上view的位置是正的height的才對(duì)。然后我們重寫 setPosition方法,對(duì)Y的位置取反,然后再設(shè)置位置。這樣就給人1個(gè)坐標(biāo)原點(diǎn)是右上角的假象,
例如:我加入1個(gè)view設(shè)置大小為屏幕大小,位置設(shè)置為(0,getWin,hegiht),這樣我的view就會(huì)在屏幕上畫1個(gè)框,實(shí)際上他在屏幕上方的外面,我的錨點(diǎn)與原點(diǎn)設(shè)置在屏幕的左上角,這樣我view中加入1個(gè)子node,setposition(ccp(0,0)),就會(huì)以左上角對(duì)齊,設(shè)置為為0,100,通太重載的setposition,就是(0,⑴00),這樣就正好顯示在屏幕上了
然后我們看1下上的image類的實(shí)現(xiàn),
#pragma once
#include "View.h"
class Image:public View
{
public:
Image(void);
~Image(void);
cocos2d::CCSprite * create(char *pszFileName);
void draw();
/*void setViewPosition(cocos2d::CCPoint & pos);*/
cocos2d::CCSprite * sprite;
};
#include "Image.h"
using namespace cocos2d;
Image::Image(void)
{
sprite = NULL;
setAnchorPoint(ccp(0,1));
ignoreAnchorPointForPosition(true);
}
Image::~Image(void)
{
}
void Image::draw()
{
ccDrawRect(ccp(0,0),ccp(sprite->getContentSize().width, -sprite->getContentSize().height));
}
cocos2d::CCSprite * Image::create(char *pszFileName)
{
sprite = CCSprite::create(pszFileName);
sprite->setAnchorPoint(ccp(0,1));
//sprite->ignoreAnchorPointForPosition(true);
this->addChild(sprite);
return sprite;
}
image類我我們組合了1個(gè)CCSprite對(duì)象,創(chuàng)建的時(shí)候,并把它加入到Image的子節(jié)點(diǎn)下,然后通過管理imgae對(duì)象來管理下面的ccsprite
我們?cè)O(shè)置位置為0,10,看1下效果

完善啊。。。。
不好的地方,由于是簡單的實(shí)現(xiàn),
1 、上面那種內(nèi)存管理上會(huì)出現(xiàn)問題,要是時(shí)刻想著delete,否則會(huì)泄漏。
改進(jìn)方法:仿照cocos2dx的create方式來創(chuàng)建新ui的對(duì)象,利用援用計(jì)數(shù)與自動(dòng)釋放池來管理內(nèi)存,不要讓使用者來new這個(gè)對(duì)象,也可自己寫這些東西。
2、上面的基礎(chǔ)view對(duì)象,要調(diào)用之前的設(shè)置位置的函數(shù),這里看起來有點(diǎn)怪怪的,這里可以對(duì)他進(jìn)1步的封裝,封裝在1個(gè)類的內(nèi)部,這樣暴露出來的坐標(biāo)原點(diǎn)就會(huì)是屏幕的左上角了。
3、有了這樣的架構(gòu),我們就能夠?qū)?套自己的ui,使用在自己的游戲中了。如果有特殊需求,改起來也很方便,再寫1套解析xml的工具類,就能夠完全實(shí)現(xiàn)自己的ui了。
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)