节点 Node
文章目录
- 节点 Node
-
- 前言
- 变量初始化
- 创建一个节点对象
- 获取节点依赖的计数器
- 获取节点的描述(获取节点的Tag)
- 节点的局部层顺序值(LocalZOrder)
- 节点的全局层顺序值(GlobalZOrder)
- 节点的缩放(scale)
- 节点位置(pisition)
- 节点倾斜(Skew)
- 节点锚点(AnchorPoint)
- 节点的原始大小(ContentSize)
- 节点可见性(Visible)
- 节点的3d旋转(Rotation3D)
- 节点的四元数(Quat)
- 节点的旋转倾斜(RotationSkew)
- 子节点(Child)
- 移除(remove)
- 数据和用户标签
- OPenGL
- isRunning()
- onEnter()
- onExit()
- cleanup()
前言
建议看完后面章节的知识后,多多回顾节点的代码,有助于加深理解。
节点是场景图中的基本元素。
最常见的节点对象有:场景、图层、精灵、菜单、标签、按钮等。
节点的主要特征是:
-它们可以包含其他节点对象(’ addChild ‘、’ removeChild ‘等)
-他们可以安排定期回调(’ schedule ', ’ unschedule ‘等)
-他们可以执行动作(’ runAction ', ’ stopAction '等)
子类化一个节点通常意味着(一个/所有):
-覆盖init来初始化资源和调度回调
-创建回调函数来处理时间的推移
-覆盖“绘制”以呈现节点
节点的属性:
-位置(默认:x=0, y=0)
-缩放(默认值:x=1, y=1)
-旋转(角度,顺时针方向)(默认为0)
-锚点(默认:x=0, y=0)
-contentSize(默认:宽度=0,高度=0)
-可见性(默认为真)
变量初始化
static const int INVALID_TAG = -1; //设置标签初始值
enum {
FLAGS_TRANSFORM_DIRTY = (1 << 0), // 1
FLAGS_CONTENT_SIZE_DIRTY = (1 << 1), // 2
FLAGS_RENDER_AS_3D = (1 << 3), // 8
FLAGS_DIRTY_MASK = (FLAGS_TRANSFORM_DIRTY | FLAGS_CONTENT_SIZE_DIRTY), // 或运算
};
static Node * create(); //初始化节点,并返回一个加入到自动内存释放池中的节点
static int getAttachedNodeCount(); //获取附加在节点上的节点个数,(统计父节点上的子节点个数)
创建一个节点对象
Node * Node::create()
{
Node * ret = new (std::nothrow) Node(); //创建一个名为ret的Node类型的对象
if (ret && ret->init()) //判断ret是否创建成功并初始化对象ret
{
ret->autorelease(); //将对象ret加入内存自动回收池
}
else
{
CC_SAFE_DELETE(ret); //如果创建对象失败,删除这个对象
}
return ret; //返回创建成功的节点对象ret
}
获取节点依赖的计数器
int Node::getAttachedNodeCount()
{
return __attachedNodeCount; //返回被依赖的计数
}
获取节点的描述(获取节点的Tag)
std::string Node::getDescription() const
{
return StringUtils::format("<Node | Tag = %d", _tag); //返回节点的Tag
// _tag(Node::INVALID_TAG) 实际返回的就是INVALID_TAG
}
初始化器结束
节点的局部层顺序值(LocalZOrder)
LocalZOrder是用于对节点相对于其兄弟节点进行排序的“键”。
节点的父节点将根据LocalZOrder值对所有子节点排序。
如果两个节点具有相同的LocalZOrder,那么首先添加到子数组中的节点将位于数组中另一个节点的前面。
此外,场景图使用中序遍历,先遍历左子树,然后根节点,最后是右子树。
LocalZOrder值< 0的节点是左子树
而LocalZOrder >=0的节点是右子树。
设置节点的LocalZOrder的值
void Node::setLocalZOrder(std::int32_t z)
{
if (getLocalZOrder() == z) //如果设置前后值相等,不做操作直接返回
return;
_setLocalZOrder(z); //否则初始化_setLocalZOrder变量
if (_parent) //如果存在父节点
{
_parent->reorderChild(this, z); //对父节点的子节点顺序重新排序
}
_eventDispatcher->setDirtyForNode(this); //将这个节点加入到事件调度中(加入节点监听器中,并将子节点也做相同操作)
}
//兼容旧版本
CC_DEPRECATED_ATTRIBUTE virtual void setZOrder(std::int32_t localZOrder) {
setLocalZOrder(localZOrder); }
获取节点的LocalZOrder的值
virtual std::int32_t getLocalZOrder() const {
return _localZOrder; }
//兼容旧版本
CC_DEPRECATED_ATTRIBUTE virtual std::int32_t getZOrder() const {
return getLocalZOrder(); }
相同等级子节点具有相同ZOrder时设置绘制顺序
void updateOrderOfArrival();
节点的全局层顺序值(GlobalZOrder)
设置节点的GlobalZOrder值
定义节点渲染的顺序。
globalZOrder较低的节点首先渲染。
如果两个或多个节点具有相同的globalZOrder,则不保证渲染顺序。
当节点的globalZOrder == 0时。在这种情况下,使用场景图顺序。
默认情况下,所有节点的globalZOrder为0。这意味着默认情况下,一定会使用场景图顺序用于呈现节点。
当需要以 与场景图顺序不同的顺序 呈现节点时,GlobalZOrder非常有用。
void Node::setGlobalZOrder(float globalZOrder)
{
if (_globalZOrder != globalZOrder) //如果设置前后不相等
{
_globalZOrder = globalZOrder; //给_globalZOrder赋值
_eventDispatcher->setDirtyForNode(this); //将这个节点加入到事件调度中(加入节点监听器中,并将子节点也做相同操作)
}
}
获取节点的GlobalZOrder值
virtual float getGlobalZOrder() const {
return _globalZOrder; }
节点的缩放(scale)
设置缩放大小
//设置一个比例因子,用于乘以节点及其 子节点 的宽度。
void Node::setScaleX(float scaleX)
{
if (_scaleX == scaleX)
return;
_scaleX = scaleX;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
//设置一个比例因子,用于乘以节点及其 子节点 的高度。
void Node::setScaleY(float scaleY)
{
if (_scaleY == scaleY)
return;
_scaleY = scaleY;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
//设置一个比例因子,用于乘以节点及其 子节点 的高度。
void Node::setScaleZ(float scaleZ)
{
if (_scaleZ == scaleZ)
return;
_scaleZ = scaleZ;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
//设置一个比例因子,用于乘以节点及其 子节点 的宽度、高度、深度。
void Node::setScale(float scale)
{
if (_scaleX == scale && _scaleY == scale && _scaleZ == scale)
return;
_scaleX = _scaleY = _scaleZ = scale;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
//它是一个比例因子,乘以节点及其子节点的宽度和高度。
void Node::setScale(float scaleX,float scaleY)
{
if (_scaleX == scaleX && _scaleY == scaleY)
return;
_scaleX = scaleX;
_scaleY = scaleY;
_transformUpdated = _transformDirty = _inverseDirty = true; //标记脏数据
}
获取缩放大小
float Node::getScaleX() const
{
return _scaleX;
}
float Node::getScaleY() const
{
return _scaleY;
}
float Node::getScaleZ() const
{
return _scaleZ;
}
//获取节点的缩放因子,当X和Y具有相同的缩放因子时
float Node::getScale(void) const
{
CCASSERT( _scaleX == _scaleY, "CCNode#scale. ScaleX != ScaleY. Don't know which one to return"); // ?
return _scaleX;
}
节点位置(pisition)
设置节点在父坐标系中的位置
//设置x,y轴的位置
void Node::setPosition(const Vec2& position)
{
setPosition(position.x, position.y); //(x, y)
}
//使用0-1设置x,y轴的位置
void Node::setPositionNormalized(const Vec2& position)
{
if (_normalizedPosition.equals(position)) //修改前后相等,不做修改直接返回
return;
_normalizedPosition = position; //给_normalizedPosition赋值
_usingNormalizedPosition = true; //标记 使用规范化位置
_normalizedPositionDirty = true; //标记 使用规范化位置的Dirty // ? 标记脏数据
_transformUpdated = _transformDirty = _inverseDirty = true; // ? 标记脏数据重新计算渲染坐标矩阵 //在上面的修改之后,渲染用的坐标系矩阵未经计算,造成值的不对应,在当调用getNodeToParentTransform() 重新计算渲染用的坐标系矩阵之后会使用修改之后的值渲染,渲染之后的值对应了,不存在脏数据了,会将_transformDirty再设为false
}
//直接使用x、y设置位置
virtual void setPosition(float x, float y);
virtual void getPosition(float* x, float* y) const;
virtual void setPositionX(float x);
virtual float getPositionX(void) const;
virtual void setPositionY(float y);
virtual float getPositionY(void) const;
//设置节点的三维属性
void Node::setPosition3D(const Vec3& position)
{
setPositionZ(position.z);
setPosition(position.x, position.y);
}
//设置三维的z坐标
virtual void setPositionZ(float positionZ)
{
if (_positionZ == positionZ)
return;
_transformUpdated = _transformDirty = _inverseDirty = true;
_positionZ = positionZ;
}
获取节点在父坐标系中的位置
//_position
const Vec2& Node::getPosition() const
{
return _position;
}
//获取节点的规范化位置 0-1
const Vec2& Node::getPositionNormalized() const
{
return _normalizedPosition;
}
//获取节点的三维属性
Vec3 Node::getPosition3D() const
{
return Vec3(_position.x, _position.y, _positionZ);
}
//获取节点的z坐标
float Node