我对CCNode、CCSprite、CCLayer的理解
2014-06-23 10:01
302 查看
<1>
首先看CCNode的声明:
其次看CCNode的初始化方法,CCNode有init函数,但是它只是简单的返回了true,也就是说每次都会初始化成功。因此它是在构造函数里面完成数据初始化的。构造函数如下:
可以看出:它的位置、锚点和大小均为
m_obPosition(CCPointZero),m_obAnchorPoint(CCPointZero)
, m_obContentSize(CCSizeZero),
因此继承于CCNode之后,往里面添加精灵便可完成一个完整可视对象的组装(如:骑着摩托车的警察等)。
<2>
其次看CCSprite的声明:
当然CCNodeRGBA是继承于CCNode的:
看CCSprite的init函数:
可见init函数对CCSprite进行了纹理初始化为空和将图片大小裁减为0。
其中,initWithTexture函数实现如下:
CCNodeRGBA的init函数实现如下:
因此最终还是调用了CCNode的init函数,但是因此也可以看出,继承于CCSprite的精灵,必须要进行调用CCSprite::init来进行许多的初始化,显得略微繁琐。当然根据面向对象的原则:子类对象完全可以当做父类对象来使用,继承于CCSprite的类完全可以实现继承于CCNode类的功能。
<3>
最后看CCLayer的声明:
然后看CCLayer的构造如下:
init函数如下:
可以看出,触摸和返回键默认是不可用的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的位置。
首先看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的位置。
相关文章推荐
- CCSpriteBatchNode中存放元素的一点理解
- CCSpriteBatchNode中存放元素的一点理解
- CCSpriteBatchNode中存放元素的一点理解
- Cocos2d-x学习笔记之CCScene、CCLayer、CCSprite的默认坐标和默认锚点实验
- CCNode,CCSprite是如何实现绘制的?
- Cocos2d-x学习笔记之CCScene、CCLayer、CCSprite的默认坐标和默认锚点实验
- IOS cocos2d学习笔记-<二>CCScene、CCLayer、CCSprite的关系
- 对oracle执行计划相关概念的理解
- 有点理解WPF中的DependencyProperty(关联属性)了~
- 理解Javascript_08_函数对象
- 对ToString("X2 ")的理解
- 如何理解复杂的C/C++声明
- 对摩尔定律的理解
- 对list_entry(ptr, type, member)的理解
- 理解Qt的线程类
- 关于进程的一点理解
- 快速理解Docker - 容器级虚拟化解决方案
- 理解矩阵(二)
- 对Java类加载、实例化执行过程的理解
- 有关ScrollView的contentOffset的理解