本节的学习目标:
(1)了解结点系统,学会自行构建结点系统。
(2)了结场景,层,精灵的组织关系与各自功能
2.1 结点系统原理入门
2.1.1 结点启蒙:
在介绍Cocos2d-x的结点系统之前,我们需要首先做一些启蒙,什么是树?
定义:
一棵树(tree)是由n(n>0)个元素组成的有限集合,其中:
(1)每个元素称为结点(node);
(2)有一个特定的结点,称为根结点或根(root);
(3)除根结点外,其余结点被分成m(m>=0)个互不相交的有限集合,而每个子集又都是一棵树(称为原树的子树)
如图A:
对于树结构有几个概念要记一下:
度:树的度——也即是宽度,简单地说,就是结点的分支数。以组成该树各结点中最大的度作为该树的度,如上图的树,其度为3;树中度为零的结点称为叶结点或终端结点。树中度不为零的结点称为分枝结点或非终端结点。除根结点外的分枝结点统称为内部结点。
@L_502_1@
深度:树的深度——组成该树各结点的最大层次,如上图,其深度为3;
层次:根结点的层次为1,其他结点的层次等于它的父结点的层次数加1.
请仔细观察上图这棵树,这里A是根结点,其余结点均是属于A的不同层级的子结点。我们由此图进一步进行想像,人的身体其实也是一棵树。
如图B:
上图详细表现了人体树结构的组织结构,左边是人形的结构,右边是层级关系展开。它作为骨骼动画的基础理论被广泛的应用于各类游戏动画中。
我们看一下这张图,首先有一个根骨(脊椎),这个根骨即是树结构中的根结点。根骨下有三根子骨骼(左胯,右胯,颈背),这三根子骨骼也各自有属于自已的子骨骼树结构,同时它们由父骨骼牵引并牵引着子骨骼,与父骨骼和第一层子骨骼保持着固定的距离。
试想一下:
当我们想把这个人移动到一个位置点时,只需要把根骨移动到相应位置,即这个人的所有骨骼都会被这种牵引关系移动到这个世界位置的相对骨骼位置。但如果我们把左胯这根骨骼去掉的话,则在移动根骨后,左胯仍停留在原地,它已经不再属于当前骨骼树了,而成了一棵独立的骨骼树。
看完这张图,已经比较接近我们所要讲述的内容了,对于骨骼结构的理解将有助于我们掌握远大于骨骼动画本身的结构模式,因为由此理论基础我们将学会一切基于结点树结构的系统。
下面我们来用C++的代码构建这样一套系统。
首先,我们创建一个基类,称之为结点。
- //结点类
- classCNode
- {
- public:
- //构造
- CNode();
- //析构
- virtual~CNode();
- public:
- //更新
- virtualinlinevoidUpdate();
- //渲染
- virtualinlinevoidDraw();
- public:
- //设置当前结点名称
- voidSetName(constchar*szName);
- //取得当前结点名称
- conststring&GetName();
- //加入一个子结点类
- voidAddChild(CNode*pChildNode);
- //取得子结点
- CNode*GetFirstChild();
- //加入一个兄弟结点类
- voidAddBorther(CNode*pBortherNode);
- //取得兄弟结点
- CNode*GetFirstBorther();
- //删除一个结点
- boolDelNode(CNode*pNode);
- //清空所有子结点
- voidDelAllChild();
- //清空所有兄弟结点
- voidDelAllBorther();
- //查询某个子结点--纵向查询
- CNode*QueryChild(constchar*szName);
- //查询某个兄弟结点--横向查询
- CNode*QueryBorther(constchar*szName);
- //为了方便检测结点树系统的创建结果,这里增加了一个保存结点树到XML文件的函数。
- boolSaveNodeToXML(constchar*szXMLFile);
- protected:
- //设置父结点
- voidSetParent(CNode*pParentNode);
- //取得父结点
- CNode*GetParent();
- //保存结点树到XML文件,这个函数是只生成本结点的信息。
- boolSaveNodeToXML(FILE*hFile);
- private:
- //当前结点名称
- stringm_strNodeName;
- //父结点
- CNode*m_pParentNode;
- //第一个子结点
- CNode*m_pFirstChild;
- //第一个兄弟结点
- CNode*m_pFirstBorther;
- }
- ;