cocos2dx[3.2](7) ——节点类Node
【唠叨】
与2.x相比,节点类Node的属性和功能做了大幅度的修改与增加。
【Node】
Node类是绝大部分类的父类(并不是所有的类,例如Director类是直接继承Ref类的),如Scene、Layer、Sprite以及精灵集合SpriteBatchNode等等等等的父类都是Node。
Node类包含了一些基本的属性、节点相关、Action动作的执行、以及定时器等相关的操作。
当然Node也有父类,其父类为Ref。
继承关系如下:
一个节点的主要特点:
>他们可以包含其他的节点对象(addChild, getChildByTag, removeChild, etc)
>他们可以安排定期的回调(schedule, unschedule, etc)
>他们可以执行一些动作(runAction, stopAction, etc)
>子类节点通常意味着(单一的/所有的):
>重写初始化资源并且可以安排回调
>创建回调来操作进行的时间
>重写“draw”来渲染节点
>节点的属性有:位置、缩放、旋转、倾斜、锚点、内容大小、可见性
下面将介绍一下节点主要常用的一些操作函数,以及新的功能特性。
(1)节点的属性
(2)节点的操作
(3)动作相关Action
(4)定时器相关schedule
(5)整合NodeRBGA类
(6)查找子节点enumerateChildren
(7)渲染顺序zOrder
(8)坐标转换
1、节点的属性
节点的属性有:位置、缩放、旋转、倾斜、锚点、内容大小、可见性。
///***位置Position*设置节点的坐标(x,y).在OpenGL中的坐标*增加3D坐标*增加标准化坐标设置*/virtualvoidsetPosition(constVec2&position);//Vec2坐标virtualvoidsetPosition(floatx,floaty);//(x,y),比Vec2更有效率virtualvoidsetPositionX(floatx);virtualvoidsetPositionY(floaty);virtualconstVec2&getPosition()const;virtualvoidgetPosition(float*x,float*y)const;virtualfloatgetPositionX(void)const;virtualfloatgetPositionY(void)const;//增加3D坐标virtualvoidsetPosition3D(constVec3&position);//Vec3坐标virtualVec3getPosition3D()const;virtualvoidsetPositionZ(floatpositionZ);virtualfloatgetPositionZ()const;//增加标准化坐标设置//Node的位置像素会根据它的父节点的尺寸大小计算//Sizes=getParent()->getContentSize();//_position=pos*s;virtualvoidsetNormalizedPosition(constVec2&position);virtualconstVec2&getNormalizedPosition()const;/***放缩Scale*设置节点的放缩比例.对XYZ轴进行放缩*例如一张图片.放缩它的宽X,高Y,深Z*/virtualvoidsetScaleX(floatscaleX);//放缩宽XvirtualvoidsetScaleY(floatscaleY);//放缩高YvirtualvoidsetScaleZ(floatscaleZ);//放缩深ZvirtualvoidsetScale(floatscaleX,floatscaleY);//X放缩fScaleX倍,Y放缩fScaleY倍virtualvoidsetScale(floatscale);//XYZ同时放缩scale倍virtualfloatgetScaleX()const;virtualfloatgetScaleY()const;virtualfloatgetScaleZ()const;virtualfloatgetScale()const;//当x,y放缩因子相同时,得到该节点的缩放因子/***旋转Rotation*设置节点的旋转角度.负顺,正逆时针旋转*增加3D旋转*/virtualvoidsetRotation(floatrotation);virtualfloatgetRotation()const;//增加3D旋转virtualvoidsetRotation3D(constVec3&rotation);virtualVec3getRotation3D()const;/***倾斜Skew*设置XY轴的倾斜角度*setRotationalSkew()模拟Flash的倾斜功能*setSkew()使用真正的倾斜功能*/virtualvoidsetSkewX(floatskewX);//水平旋转倾斜.负顺时针变形virtualvoidsetSkewY(floatskewY);//垂直旋转倾斜virtualvoidsetRotationSkewX(floatrotationX);virtualvoidsetRotationSkewY(floatrotationY);virtualfloatgetSkewX()const;virtualfloatgetSkewY()const;virtualfloatgetRotationSkewX()const;virtualfloatgetRotationSkewY()const;/***锚点AnchorPoint*锚点就像一枚图钉,将图片钉在屏幕上.而锚点就是图片的坐标.*当然图钉可以钉在图片的左下角,右上角,或者中心都可以.*(0,0)表示左下角,(1,1)表示右上角*默认的锚点是(0.5,0.5),即节点的正中心*/virtualvoidsetAnchorPoint(constVec2&anchorPoint);//标准化的锚点virtualconstVec2&getAnchorPoint()const;//标准化的锚点virtualconstVec2&getAnchorPointInPoints()const;//返回绝对像素的锚点,即屏幕坐标//是否忽略锚点的设置//若忽略锚点设置,锚点永远为(0,0)//默认值是false,但是在Layer和Scene中是true//这是一个内部方法,仅仅被Layer和Scene使用,不要自行调用!virtualvoidignoreAnchorPointForPosition(boolignore);virtualboolisIgnoreAnchorPointForPosition()const;/***内容大小ContentSize*contentSize依然是相同的,无论节点是缩放或者旋转*所有的节点都有大小,图层和场景有相同的屏幕大小*/virtualvoidsetContentSize(constSize&contentSize);virtualconstSize&getContentSize()const;/***可见性Visible*/virtualvoidsetVisible(boolvisible);virtualboolisVisible()const;//
2、节点的操作
节点的操作有:标记、名字、自定义数据、父节点管理、子节点管理、其他操作管理。
///***标记与名字TagandName*setTag:给节点设置一个编号*setName:给节点设置一个名字*/virtualvoidsetTag(inttag);virtualvoidsetName(conststd::string&name);virtualintgetTag()const;virtualstd::stringgetName()const;/***自定义数据UserData/Object*setUserData:设置一个用户自定义的数据.可以为一个数据块,结构体或者一个对象.*setUserObject:设置一个用户自定义的对象.和userData类似,但它是一个对象而不是void**/virtualvoidsetUserData(void*userData);virtualvoidsetUserObject(Ref*userObject);virtualvoid*getUserData();virtualRef*getUserObject();/***设置父节点Parent*setParent,removeFromParent*/virtualvoidsetParent(Node*parent);virtualNode*getParent();virtualvoidremoveFromParent();virtualvoidremoveFromParentAndCleanup(boolcleanup);//true则删除该节点的所有动作及回调函数./***管理子节点Child*addChild,*getChildBy**,getChildren,getChildrenCount*removeChild,removeAllChildren*reorderChild,sortAllChildren*///添加子节点//localZOrderZ轴顺序为了绘画的优先权//tag节点编号,可通过tag获取子节点//name节点名字,可通过name获取子节点virtualvoidaddChild(Node*child);virtualvoidaddChild(Node*child,intlocalZOrder);virtualvoidaddChild(Node*child,intlocalZOrder,inttag);virtualvoidaddChild(Node*child,intlocalZOrder,conststd::string&name);//获取子节点virtualNode*getChildByTag(inttag)const;virtualNode*getChildByName(conststd::string&name)const;virtualVector<Node*>&getChildren();//获得所有子节点,并以Vector数组返回virtualssize_tgetChildrenCount()const;//子节点总数//删除子节点virtualvoidremoveChild(Node*child,boolcleanup=true);virtualvoidremoveChildByTag(inttag,boolcleanup=true);virtualvoidremoveChildByName(conststd::string&name,boolcleanup=true);virtualvoidremoveAllChildren();//删除所有节点virtualvoidremoveAllChildrenWithCleanup(boolcleanup);//cleanup为true则删除子节点的所有动作//重排子节点//重新排序一个子节点,设定一个新的z轴的值//child它必须是已经添加的//localZOrderZ轴顺序为了绘画优先级virtualvoidreorderChild(Node*child,intlocalZOrder);virtualvoidsortAllChildren();//重新排序所有子节点/***其他操作管理*/virtualvoidonEnter();//节点开始进入舞台时调用.即创建时调用.virtualvoidonEnterTransitionDidFinish();//节点进入舞台后调用.即创建完后调用.virtualvoidonExit();//节点离开舞台时调用.即移除时调用virtualvoidonExitTransitionDidStart();//节点离开舞台前调用.//绘制节点virtualvoiddraw()final;//递归访问所有子节点,并重新绘制virtualvoidvisit()final;//返回包含Node(节点)的Scene(场景).//若不属于任何的场景,它将返回nullptrvirtualScene*getScene()const;//返回节点在父节点坐标中的矩形边界框virtualRectgetBoundingBox()const;//暂停所有的活动着的动作和调度器virtualvoidcleanup();//
3、动作相关Action
动作管理:运行、暂停、取消等操作。
///***动作管理Action*setActionManager*runAction,stopAction,getActionByTag,getNumberOfRunningActions*///设置被所有动作使用的ActionManager对象//如果你设置了一个新的ActionManager,那么之前创建的动作将会被删除virtualvoidsetActionManager(ActionManager*actionManager);virtualActionManager*getActionManager();Action*runAction(Action*action);//执行一个动作Action*getActionByTag(inttag);//获取动作,根据tag标记voidstopAllActions();//暂停动作voidstopAction(Action*action);//暂停动作voidstopActionByTag(inttag);//暂停动作ssize_tgetNumberOfRunningActions()const;//获取正在运行的动作数量//
4、定时器相关schedule
定时器管理,默认定时器、自定义定时器、一次性定时器。
///***定时器管理schedule*setScheduler*scheduleUpdate:默认定时器*schedule:自定义定时器*scheduleOnce:一次性定时器*///设置一个调度器对象,来调度所有的“update”和定时器//如果你设置了一个新的调度器,那么之前创建的timers/update将会被删除。virtualvoidsetScheduler(Scheduler*scheduler);virtualScheduler*getScheduler();//得到调度器对象//开启默认定时器.刷新次数为60次/秒.即每秒60帧.//与update(floatdelta)回调函数相对应.//给予定时器优先级priority.其中priority越小,优先级越高voidscheduleUpdate(void);voidscheduleUpdateWithPriority(intpriority);voidunscheduleUpdate(void);//取消默认定时器virtualvoidupdate(floatdelta);//update为scheduleUpdate定时器的回调函数.//设置自定义定时器.默认为每秒60帧.//interval:每隔interval秒,执行一次.//repeat:重复次数.//delay:延迟时间,即创建定时器delay后开始执行.voidschedule(SEL_SCHEDULEselector,floatinterval,unsignedintrepeat,floatdelay);voidschedule(SEL_SCHEDULEselector,floatinterval);voidschedule(SEL_SCHEDULEselector);//默认为每秒60帧voidscheduleOnce(SEL_SCHEDULEselector,floatdelay);//只执行一次,delay秒后执行voidunschedule(SEL_SCHEDULEselector);//取消一个自定义定时器voidunscheduleAllSelectors(void);//取消所有定时器voidresume(void);//恢复所有定时器和动作voidpause(void);//暂停所有定时器和动作//
5、整合NodeRGBA类
整合NodeRGBA类,增加颜色、透明度的设置。
///***整合NodeRGBA类*setOpacity:透明度*setColor:颜色*/virtualGLubytegetOpacity()const;virtualGLubytegetDisplayedOpacity()const;virtualvoidsetOpacity(GLubyteopacity);virtualconstColor3B&getColor()const;virtualconstColor3B&getDisplayedColor()const;virtualvoidsetColor(constColor3B&color);//
6、enumerateChildren
新增的Node::enumerateChildren方法,且支持C++ 11的正则表达式。
用于枚举某个Node节点的子节点,并让名字符合"name通配符"的子节点执行callback函数。
且callback函数返回类型应该为一个bool值,并且返回为true时,结束查找。
//virtualvoidenumerateChildren(conststd::string&name,std::function<bool(Node*node)>callback)const;//
使用举例:
////Findnodeswhosenameis'nameToFind'andendwithdigits.node->enumerateChildren("nameToFind[[:digit:]]+",[](Node*node)->bool{...returnfalse;//returntruetostopatfirstmatch});//Findnodeswhosenameis'nameToFind'andendwithdigitsrecursively.node->enumerateChildren("nameToFind[[:digit:]]+",[](Node*node)->bool{...returnfalse;//returntruetostopatfirstmatch});//
通配符匹配举例:
////搜索语法选项'//':递归访问所有子节点,只能放在搜索串的开头位置'..':搜索移至node的父节点,只能放在某个字符串的结束位置'/':搜索移至node的子节点,可以放在任何位置,除了搜索串的开头位置//代码举例enumerateChildren("//MyName",...):递归访问Node的所有子节点。查找匹配"MyName"的子节点enumerateChildren("[[:alnum:]]+",...):在Node的儿子节点中查找。所有项enumerateChildren("A[[:digit:]]",...):在Node的儿子节点中查找。名字为"A0","A1",...,"A9"的子节点enumerateChildren("Abby/Normal",...):在Node的孙子节点中查找。其节点为"Normal",且父节点为"Abby"enumerateChildren("//Abby/Normal",...):递归访问Node的所有子节点。其节点为"Normal",且父节点为"Abby"//
注意:使用gccV4.8或更低版本构建的程序运行时会崩溃。由于OTHER_LDFLAGS不能在Xcode6 beta3中使用,在iOS上我们使用包括64位库文件fat library。但Xcode 5.0或更低版本不支持这种方式。
所以:
* Android编译需要NDK R9D以上版本
* Linux编译需要GCC4.9以上版本
* iOS编译需要 Xcode5.1以上版本
7、渲染顺序
在2.x中是使用Zorder来控制节点渲染的先后顺序的。而在3.x中渲染的顺序则是由两个因素决定。
>全局Z顺序:GlobalZOrder。所有节点之间对比。
>局部Z顺序:LocalZOrder。 兄弟节点之间对比。
且Z顺序越小,最先渲染。
7.1、全局Z顺序
>定义渲染节点的顺序,拥有全局Z顺序越小的节点,最先渲染。
>假设:两个或者更多的节点拥有相同的全局Z顺序,那么渲染顺序无法保证。唯一的例外是如果节点的全局Z顺序为零,那么场景图顺序是可以使用的。
>默认的,所有的节点全局Z顺序都是零。这就是说,默认使用场景图顺序来渲染节点。
>全局Z顺序是非常有用的当你需要渲染节点按照不同的顺序而不是场景图顺序。
>局限性: 全局Z顺序不能够被拥有继承“SpriteBatchNode”的节点使用。
//virtualvoidsetGlobalZOrder(floatglobalZOrder);virtualfloatgetGlobalZOrder()const;//
7.2、局部Z顺序
>LocalZOrder是“key”(关键)来分辨节点和它兄弟节点的相关性。
>父节点将会通过LocalZOrder的值来分辨所有的子节点。如果两个节点有同样的LocalZOrder,那么先加入子节点数组的节点将会比后加入的节点先得到渲染,那么先加入的节点会被后加入的节点遮盖[update 20140927]。
>同样的,场景图使用“In-Order(按顺序)”遍历数算法来遍历。并且拥有小于0的LocalZOrder的值的节点是“left”子树(左子树) 所以拥有大于0的LocalZOrder的值得节点是“right”子树(右子树)。
////设置这个节点的局部Z顺序((相对于兄弟节点))virtualvoidsetLocalZOrder(intlocalZOrder);virtualintgetLocalZOrder()const;//
8、坐标转换
参考:http://www.tairan.com/archives/5739
8.1、坐标转换函数
坐标分为两种坐标:
>世界坐标:就是相对节点的世界坐标。
>局部坐标:就是相对节点的坐标。
///***坐标转换convertTo*WorldSpace:世界坐标*NodeSpace:局部坐标**///把世界坐标,转换到当前节点的本地坐标系中//基于AnchorPoint,把基于当前节点的本地坐标系下的坐标,转换到世界坐标系中Vec2convertToNodeSpace(constVec2&worldPoint)const;Vec2convertToNodeSpaceAR(constVec2&worldPoint)const;//把基于当前节点的本地坐标系下的坐标,转换到世界坐标系中//基于AnchorPoint.把世界坐标,转换到当前节点的本地坐标系中Vec2convertToWorldSpace(constVec2&nodePoint)const;Vec2convertToWorldSpaceAR(constVec2&nodePoint)const;//把触点坐标,转换到当前节点的本地坐标系中Vec2convertTouchToNodeSpace(Touch*touch)const;Vec2convertTouchToNodeSpaceAR(Touch*touch)const;//
8.2、举例
> node1坐标为:(20,40), 锚点(0,0)。
> node2坐标为:(-5,-20),锚点(1,1)。
> Vec2 point1 = node1->convertToNodeSpace(node2->getPosition());
结果为:(-25,-60)。(即:相对node1节点坐标位置,的,相对坐标)
分析 :node2相对node1节点的坐标为:(-5,-20) - (20,40) 。
也就是说:node2相对node1的坐标位置。
> Vec2point2 = node1->convertToWorldSpace(node2->getPosition());
结果为:(15,20)。(即:相对node1的世界坐标系统下,的,世界坐标)
分析 :将node1作为参照,转换到世界坐标为:(20,40) + (-5,-20) 。
也就是说:node2的坐标现在被看做是相对node1的坐标位置,然后转换到世界坐标。
8.3、在屏幕触控中的应用
判断触摸点是否触摸到某个精灵图片sp的内部区域。
//boolHelloWorld::onTouchBegan(Touch*touch,Event*unused_event){//将触点坐标,转换为相对节点sp的,相对坐标Vec2point=sp->convertTouchToNodeSpace(touch);//构造sp的尺寸矩形Sizesize=sp->getContentSize();Rectrect=Rect(0,0,size.width,size.height);//判断触点是否触摸到sp内部if(rect.containsPoint(point)){CCLog("点中");returntrue;}returnfalse;}//
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。