您的位置:首页 > Web前端 > Node.js

我对CCNode、CCSprite、CCLayer的理解

2014-06-23 10:01 302 查看
<1>

首先看CCNode的声明:

class CC_DLL CCNode : public CCObject{...};

其次看CCNode的初始化方法,CCNode有init函数,但是它只是简单的返回了true,也就是说每次都会初始化成功。因此它是在构造函数里面完成数据初始化的。构造函数如下:

CCNode::CCNode(void)
: m_fRotationX(0.0f)
, m_fRotationY(0.0f)
, m_fScaleX(1.0f)
, m_fScaleY(1.0f)
, m_fVertexZ(0.0f)
, m_obPosition(CCPointZero)
, m_fSkewX(0.0f)
, m_fSkewY(0.0f)
, m_obAnchorPointInPoints(CCPointZero)
, m_obAnchorPoint(CCPointZero)
, m_obContentSize(CCSizeZero)
, m_sAdditionalTransform(CCAffineTransformMakeIdentity())
, m_pCamera(NULL)
// children (lazy allocs)
// lazy alloc
, m_pGrid(NULL)
, m_nZOrder(0)
, m_pChildren(NULL)
, m_pParent(NULL)
// "whole screen" objects. like Scenes and Layers, should set m_bIgnoreAnchorPointForPosition to true
, m_nTag(kCCNodeTagInvalid)
// userData is always inited as nil
, m_pUserData(NULL)
, m_pUserObject(NULL)
, m_pShaderProgram(NULL)
, m_eGLServerState(ccGLServerState(0))
, m_uOrderOfArrival(0)
, m_bRunning(false)
, m_bTransformDirty(true)
, m_bInverseDirty(true)
, m_bAdditionalTransformDirty(false)
, m_bVisible(true)
, m_bIgnoreAnchorPointForPosition(false)
, m_bReorderChildDirty(false)
, m_nScriptHandler(0)
, m_nUpdateScriptHandler(0)
, m_pComponentContainer(NULL)
{
// set default scheduler and actionManager
CCDirector *director = CCDirector::sharedDirector();
m_pActionManager = director->getActionManager();
m_pActionManager->retain();
m_pScheduler = director->getScheduler();
m_pScheduler->retain();

CCScriptEngineProtocol* pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
m_eScriptType = pEngine != NULL ? pEngine->getScriptType() : kScriptTypeNone;
m_pComponentContainer = new CCComponentContainer(this);
}

可以看出:它的位置、锚点和大小均为

m_obPosition(CCPointZero),m_obAnchorPoint(CCPointZero)

, m_obContentSize(CCSizeZero),

因此继承于CCNode之后,往里面添加精灵便可完成一个完整可视对象的组装(如:骑着摩托车的警察等)。

<2>

其次看CCSprite的声明:

class CC_DLL CCSprite : public CCNodeRGBA, public CCTextureProtocol{...};

当然CCNodeRGBA是继承于CCNode的:

class CC_DLL CCNodeRGBA : public CCNode, public CCRGBAProtocol{...};

看CCSprite的init函数:

bool CCSprite::init(void)
{
return initWithTexture(NULL, CCRectZero);
}

可见init函数对CCSprite进行了纹理初始化为空和将图片大小裁减为0。

其中,initWithTexture函数实现如下:

bool CCSprite::initWithTexture(CCTexture2D *pTexture, const CCRect& rect, bool rotated)
{
if (CCNodeRGBA::init())
{
m_pobBatchNode = NULL;

m_bRecursiveDirty = false;
setDirty(false);

m_bOpacityModifyRGB = true;

m_sBlendFunc.src = CC_BLEND_SRC;
m_sBlendFunc.dst = CC_BLEND_DST;

m_bFlipX = m_bFlipY = false;

// default transform anchor: center
setAnchorPoint(ccp(0.5f, 0.5f));

// zwoptex default values
m_obOffsetPosition = CCPointZero;

m_bHasChildren = false;

// clean the Quad
memset(&m_sQuad, 0, sizeof(m_sQuad));

// Atlas: Color
ccColor4B tmpColor = { 255, 255, 255, 255 };
m_sQuad.bl.colors = tmpColor;
m_sQuad.br.colors = tmpColor;
m_sQuad.tl.colors = tmpColor;
m_sQuad.tr.colors = tmpColor;

// update texture (calls updateBlendFunc)
setTexture(pTexture);
setTextureRect(rect, rotated, rect.size);

// by default use "Self Render".
// if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
setBatchNode(NULL);

return true;
}
else
{
return false;
}
}

CCNodeRGBA的init函数实现如下:

bool CCNodeRGBA::init()
{
if (CCNode::init())
{
_displayedOpacity = _realOpacity = 255;
_displayedColor = _realColor = ccWHITE;
_cascadeOpacityEnabled = _cascadeColorEnabled = false;
return true;
}
return false;
}

因此最终还是调用了CCNode的init函数,但是因此也可以看出,继承于CCSprite的精灵,必须要进行调用CCSprite::init来进行许多的初始化,显得略微繁琐。当然根据面向对象的原则:子类对象完全可以当做父类对象来使用,继承于CCSprite的类完全可以实现继承于CCNode类的功能。

<3>

最后看CCLayer的声明:

class CC_DLL CCLayer : public CCNode, public CCTouchDelegate, public CCAccelerometerDelegate, public CCKeypadDelegate{...};

然后看CCLayer的构造如下:

CCLayer::CCLayer()
: m_bTouchEnabled(false)
, m_bAccelerometerEnabled(false)
, m_bKeypadEnabled(false)
, m_pScriptTouchHandlerEntry(NULL)
, m_pScriptKeypadHandlerEntry(NULL)
, m_pScriptAccelerateHandlerEntry(NULL)
, m_nTouchPriority(0)
, m_eTouchMode(kCCTouchesAllAtOnce)
{
m_bIgnoreAnchorPointForPosition = true;
setAnchorPoint(ccp(0.5f, 0.5f));
}

init函数如下:

bool CCLayer::init()
{
bool bRet = false;
do
{
CCDirector * pDirector;
CC_BREAK_IF(!(pDirector = CCDirector::sharedDirector()));
this->setContentSize(pDirector->getWinSize());
m_bTouchEnabled = false;
m_bAccelerometerEnabled = false;
// success
bRet = true;
} while(0);
return bRet;
}

可以看出,触摸和返回键默认是不可用的m_bTouchEnabled(false)、m_bKeypadEnabled(false),锚点是setAnchorPoint(ccp(0.5f, 0.5f));即ccp(0.5f, 0.5f)而不是CCPointZero,但是m_bIgnoreAnchorPointForPosition = true;忽略了锚点对层位置的影响,这个就比较有意思了。同时this->setContentSize(pDirector->getWinSize());设置了一个层的大小和屏幕大小一般大,所以要是需要使用CCScrollView的话,需要裁减层的大小到你想要显示的区域的大小才行。由于忽略了锚点的影响,因此,一个层添加到一个场景中,把这个场景显示出来后,这个层就位于CCPointZero的位置。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: