【cocosStdio系列】之UI控件下
大家好,我是Lampard
今天与大家通过一个demo了解cocos给我们提供的各个UI控件
reference:《cocos2d-x游戏开发》--刘克男
(一)场景切换
上篇文章我们成功的创建了登录场景,熟悉了部分的UI控件。今天我们就创建一个新的场景,用于测试剩下的富文本(RichText),位图文字(BMFont),图集文本标签(AtlasLabel), 滑动条(Slider),基础容器(panel),滚动容器(Scrollview),列表容器(listView),翻页容器(WidgetPageView),序列帧动画(Animate),骨骼动画(Dragon),瓦片地图(TMX)
(1)创建新场景
之前的登陆场景在成功登录之后,会调用计时器设置进度条的进度。那么现在加一下逻辑,当进度条跑到100%之后就进入到新的场景。至于新的场景我们就套用项目创建时生成"hello world"的场景(MainScene)就好了
因为要切换到MainScene场景,所以需要先引入MainScene这个模块,MainScene是继承于场景类的,场景在实例化的时候简单的生成了一个文本为"hello world"的Label
之后我们在进度到达100%的时候调用display.replaceScene即可,函数中会利用cc.Director来进行场景切换
display.replaceScene有四个参数,newScene:新的场景对象,transitionType:过渡效果名, time:过渡时间,more:过渡效果附加参数。如果不需要过度效果的话,后面的三个参数不需要填写
(2)场景切换过度效果
引擎给我们提供了许多场景过度的效果,看了备注大概有一下那么多,我们随便拿两种来试一试
turnOffTiles 当前场景分成多个块,逐渐替换为新场景
pageTurn 翻页效果,如果指定附加参数为 true,则表示从左侧往右翻页
(二)主场景UI编辑
(1)重新生成一个UI项目
重新生成一个UI项目命名为mainScene,和之前一样,把UI根节点类型设置为node类型,然后给这个场景先加上一个背景图(imageView)
(2)panel基础容器
面板容器时其他UI容器的基础,它封装了UI容器最重要的功能:矩形裁剪。ccui.Layer对应Cocos Studio中的panel控件
panel的基础属性和其他控件无异,能够设置它的大小位置锚点等信息。我们可以给panel设置背景图片,只需要把资源拖动过去即可
当把背景图添加为背景图的时候明显能看到背景图超出了panel的大小(背景图640*960,panel600*800),但是依旧能够显示出来,那是因为没有勾选到裁切内容这个勾选项。当勾选了之后超出的部分就会消失,同样的我们可以在代码中通过setClippingEnabled()来实现
我们还可以对panel的背景颜色进行填充,可以选择纯色或者渐变的方式进行,并可以对背景填充进行透明度和颜色的设置。但是值得注意的是,这些属性只会影响填充色而不会背景图片,且当两者都存在的时候,背景图的层级更高
我们创建三个panel分别用于展示文本,容器和动画,并用滑动条来控制显示哪一个panel
(3)Slider滑动条
滑动条比起进度条多出了一个用于调节进度的滑块,至于滑块的样式就像按钮一样需要三种状态。如果需要设置进度的话一方面可以像进度条那样通过setPercent来设置,也可以通过手动滑动滑块来设置
可以通过addEventListener(sender, eventType)来监听滑动条事件,当eventType == ccui.SliderEventType.percentChanged 的时候则证明触发了滑动事件。大致的想法就是通过滑动条来控制显示哪一个panel,若小于3分之1则显示字体pnl,大于3分之2则显示动画pnl否则显示容器pnl。最后再设置一个文本用于显示当前的pnl
(4)TTFLabel,BMFont,AtlasLabel和RichText字体
TTF是一种字库的规范,是苹果和微软共同推出的字体文件格式。TTF类型的本文标签是通过系统TTF字体渲染文字,它使用简单,支持任意字体大小和字距的文本。但是如果需要修改文本标签的内容,则会重新重建一个新的openGL纹理,就跟重新创建一个TTF字体一样,所以其刷新的效率不高。由于上一篇文章已经有介绍Label所以这里就不多说了
BMFont文本标签支持FNT类型的文件,它适用于频繁更新的文本标签。BMF把所有的字符都整合到一张纹理图片上,通过纹理坐标控制字符串的显示,每次的更新只是更换坐标而不用新建纹理。同时图片可以使用美术设计的艺术字体,体现更好的效果。在windows平台上可以使用BMFont软件来制作美术字,创建出fnt和png文件之后导入到UI编辑器就可以了
AtlasLabel图集文本标签是由一连串等宽图片拼接成的一张整图,要求这些图片中符号的ASCALL码是连续的,通常是0~9这几个数字,引擎模板左下角的字体就是AtlasLabel。AtlasLabel存在的意义首先变化次数多不能用ttf,其次没必要使用bmf那么大的资源。由于目前使用的cocosStdio版本没有AtlasLabel,因此我们留到代码中再去实现。
RichText富文本是多样式文本和图片进行混合排版的渲染控件。比如一行聊天信息中包含了不同颜色,大小的文本以及表情图片等。可以通过ccui.RichText:create()来创建一个富文本。同样的由于cocosStdio中无法制作,我们留到代码中实现。
(5)Scrollview滚动容器,ListView列表容器,PageView翻页容器
滚动容器可以用于显示多于一个屏幕的内容,超出屏幕范围的内容,可以通过滑动来查看,它的实现原理是把显示的内容存放在_innerContener上(可以理解成一块大的画布),然后通过设置显示窗口(一块小的区域)的位置来显示不同内容。滚动容器支持水平,垂直和双向三种滚动属性
相比于panel容器来说,滚动容器多了滚动区域和滚动方向的选项。滚动区域可以比显示区域要大,也就是说可以点击“看不见”的区域,但是也能实现滚动效果。但是不可以比显示区域小,也就是说当玩家滑动显示区域的时候都能够实现滚动效果。还可以勾选上回弹效果来决定拉到底的时候会不会有一个回弹的效果,我们往容器中加入三个按钮当作子项来展现滑动效果
列表容器是在滚动容器基础上进行拓展的,它是滚动容器典型应用场景的一个实现。列表容器把子节点抽象为item项,内部有序排列item并自动计算每个item的位置和_innerContainer的大小。列表能够实现垂直或者水平滚动,不能双向滚动
列表容器因为是自动计算每一个控件的位置的,所以往里面增加控件的时候它会根据你设置的控件间隔和控件对齐方式自动添加
分页视图控件的内容是视窗区域的1~n倍,一个视窗的内容叫做一页。创建分页视图后默认显示第一页。用户可以左右切换显示其他页。我们可以通过setCustomScrollThreshold()来设置一个阈值,当用户松开触摸后,控件自动判断滑动距离是否超过阈值,当前应该显示哪一页,然后自动滚动使该页居中显示在视窗中。分页视图经常被用作引导的界面中。它的子项必须是layout,也就是cocosStdio中的panel
分页视图的属性和panel没什么区别,我们把三个panel当作子节点加入到分页视图中,然后每一个panel上添加一个按钮用作显示
(6)序列帧动画和骨骼动画
序列帧动画就是逐帧动画,也就是动画的每一帧都有独立的数据保存,通过连续的播放帧从而形成动画,常见的GIF就是序列帧动画。骨骼动画就是把动画中的元素拆分为骨骼,在编辑器中移动,旋转或缩放每一个骨骼,从而生成一些关键帧,两个关键帧之间由引擎帮你生成一些中间帧。序列帧相较于骨骼动画,其实现简单但是占用存储的空间大。骨骼动画占据内存小,播放流畅,但是因为要生成中间帧,所以比起序列帧会占用cpu
因为两个动画都要在代码中实现,因此我们在cocosStdio中只需要帮他们占个位置就可以了。至此我们的UI编辑工作就完成啦~然后发布,并且把资源复制到项目的res目录下即可
(三)主场景代码逻辑
(1)导入UI项目文件,实现滑动条逻辑
导入UI项目文件和登录场景一样,把scb文件导入并加到场景中就可以了
然后是对三个panel的一个初始化
紧接着就可以初始化我们的滑动条,并通过addEventListener方法监听滑动条百分比的更改事件。若当前的百分比是少于3分之1,则显示pnlFont,大于3分之2显示pnlAnimation,否则显示pnlView。旁边的文本也随之改变,显示当前pnl的名称以下是代码的实现
然后我们看一下现在的效果
(2)实例化文本层
之前TTF和BMFont类型地文本我们都已经在UI编辑器中构建,剩下Atlas图集文本标签和richText富文本还没有生成。我们先生成一个Atlas。Atlas是使用方法cc.Label:createWithCharMap来进行,cc.Label:createWithCharMap的参数有4个,分别是图集图片,字符宽度,字符高度,图集第一个文本的ASCALL码
我们根据实际图集的属性创建一个文本试试看
然后是富文本,富文本可以说是一个容器,通过方法ccui.RichText:create()就可以生成,它本身不具备显示的元素我们需要后续把元素push到富文本中去。元素一般是文本,图片,自定义的节点等等,以下我列举了几个例子
最后我们看看效果
(3)实例化容器层
容器层我们在UI编辑器中已经配置完毕。所以我们主要是看看各个容器的效果。想要了解学习各个容器相关函数接口的同学可以查阅cocos的一个官方文档。首先看看有回弹效果的scrollView
然后是没有回弹效果的listView和翻页容器PageView
(4)实例化动画层
对于序列帧动画,我们需要把用到的帧打包成一张纹理大图png和一份plist文件,plist文件中是以键值对形式记录了各帧在该大图的xy坐标。我们可以使用texturePacker进行打图,网上有许多相关的教程。为了方便我是直接在素材网下载了一份资源,我们首先把它们放置在res目录下
plist的部分截图
生成序列帧动画需要三步,首先是生成一个序列帧frame,然后以frames作参数生成一个animation动作类对象,最后以动作类对象作为参数生成一个animate动画对象。在代码里首先需要把资源导入到精灵帧缓存中
然后通过 display.newFrames把刚才导入的精灵帧取出,生成f序列帧Frame类,参数有三个分别是图片的名称,起始帧编号,终止帧编号
然后通过display.newAnimation生成动作类annimation对象,参数有两个分别是帧类对象,播放的时间。最后再把动作类对象作为参数生成一个动画对象animate,只有动画对象才可以被node节点类runAction进行播放
最后就是利用首帧创建一个精灵播放该动画即可,由于我想实现循环播放的效果,所以可以利用cc.RepeatForever来把当前的动作调整为循环播放的一个动画。如果一个节点相同时播放两个动画,或者两个动画我想按顺序播放可不可以呢?明确告诉大家是可以的,并列执行可以用到Spawn类,顺序执行使用Sequence类,具体的测试以后再表~
最后看看效果,额,挺丑的,不过好歹会动哈哈哈~
最后就是骨骼动画的实现了。上文提过,骨骼动画的原理就是把身体各个元素分开,通过骨骼再把资源连接起来,然后在时间轴上选择想要的时间结点调整骨骼生成关键帧,最后导出使用的时候,引擎会帮助我们计算生成中间帧从而做出动画效果。一般的骨骼动画有两种编辑器,分别是spine和dragonBone,我们可以随便选择一个来进行骨骼动画编辑。以下就是使用spine的例子。
首先把骨骼动画项目导出,可以选择生成.skel二进制格式或者.json键值对格式的文件。二进制文件的效率相对较高,然后我就导出使用了。但是我就踩了一个坑,skel是在spine3.6之后才新加入的文件格式。而我引擎里面spine的版本是2.x,导入的时候就不支持这一种。所以大家在设计的时候要注意版本信息看引擎支不支持,被迫无奈我们就只好用json格式的导入了,SkeletonAnimation这个类帮助我们生成骨骼动画对象。我们设置这个骨骼动画循环播放"walk"这个动作。看看效果