问题的产生

项目是用ccs1.6做的UI,在某个需求中,需要把一个Sprite的SpriteFrame clone一份,去构造另一个
代码类似于

这样并没有问题
但是如果sprite的SpriteFrame被set过一个新的,那sprite2得到的SpriteFrame,依然是老的

怎么回事?

查看源码,我们发现Node:clone()方法被重写了(在NodeEx.lua里)

粗读一下代码,先克隆一个实例,然后克隆基础属性,最后递归把子节点也克隆了

那问题就应该出现在self:createCloneInstance_()上
查阅发现

好吧…直接用构造参数返回一个实例是什么鬼

既然出事了,就弄弄大

我们发现所有UI组件的createCloneInstance_方法都有这个问题
写一段比较简单的代码

 
可以看到,屏幕上显示label显示after,label2显示before

如果不用UI组件呢?

我试了一下,直接使用Sprite和LabelTTF是没有问题的,那这个就可以定性为quick的bug了

懒加载

我最先接触懒加载(延时加载)是在Hibernate里,因为一次和数据库交互过多,导致应用程序卡顿,所以就延迟加载这些数据,等需要的时候再取.可以认为懒加载就是非即时的加载数据.

 

问题的产生

在游戏开发中,也会碰到一次处理太多数据造成游戏卡顿降帧,比较典型的比如”背包”模块,背包可以认为是一个ListView,由一个lua table里的一些元素作为数据源来构建,当用一个for循环去构造界面时,背包格子过多会导致游戏线程卡住,游戏降帧在所难免.如何做到不降帧?我们可以把一个复杂的逻辑分在多个帧里去做.

 

来看看代码

用法

Github

戳这里

ScrollView滚动视图

在游戏开发过程中,由于手机屏幕空间有限,加上手指的灵动性,滑动成了最好的替换翻页的操作方式
ScrollView就是在这种需求驱动下的产物

cc.ScrollView和cc.ui.UIScrollView

前者是cocos2dx3.3原生的c++类,继承于cc.Layer
后者是QuickUI组件中的lua类,继承于cc.ClippingRectangleNode

quick中的cc.ui.UIScrollView用法

在实际运用过程中,我发现quick的滚动组件存在性能问题(windows上),一旦组件多了之后滚动不流畅,卡顿严重

原生cc.ScrollView用法

在出现对话的时候,我们往往不希望文字一下子突然出现,于是有了这个需求

文字要慢慢的出现,但是点击时,一下子显示完

用法如下

 

有倒计时功能的标签这个还是挺常见的

直接上代码吧

用法如下

 

除了text外,display.newTTFLabel里的所有参数都有效
新增了time参数(单位毫秒),format参数(支持H M S),triggerTime参数(触发事件,不传时为0)
倒计时结束会触发TimerLabel.ON_COUNT_DOWN

2.x时代的CCControlButton的确十分方便,策划们也十分喜欢按下有缩放的效果

到了3.x的项目,工具链已经相当完善,我使用的是cocos2dx3.2+quick3.2rc1+cocos code ide 1.0.1+cocos studio 1.6(以下简称ccs)

在ccs里建立的按钮,到了程序里实际上是UIPushButton

从quick的源码可以看出,UIPushButton继承于UIButton,UIButton继承于cc.Node

那么按下弹起的效果就得自己写了,好在quick扩展的方式很方便

我用起来是全局的

在载入ccs之后,会遍历所有节点,找出node.__cname == “UIPushButton”的元素,然后UIButtonEx.extend(node); node:setPressedActionEnabled(true)就可以了

需要按钮放大的,把0.9改成1.1就行了

转自http://www.swfdiy.com/?p=1663

在quick-cocos2dx里, 通过class() 函数进行类的定义

下面贴出quick-cocos2d-x-2.2.1-rc 里 class()的源码

我们先考虑最简单的情况, 在没有继承的情况下定义一个类ClassA

这种情况下, ClassA 跟InstanceA的关系如下图

InstanceA的metatable为ClassA, 而且ClassA.__index = ClassA, 因此,对于InstanceA找不到的属性, 将在ClassA里进行查找。 需要注意的是,ClassA里的属性比如field1, 是相当于类变量的概念,所有实例都公用该属性,并非各自维护该字段的拷贝。

下面如果要再定义ClassB, 从ClassA 进行继承

这种情况下, ClassB 跟InstanceB, ClassA的关系如下图

 

同理,InstanceB里没有定义的属性, 将首先在ClassB里进行搜索, 如果ClassB里搜不到, 将向上追寻到ClassA里。

上面考虑的都只是针对纯Lua类, 在实际情况中, 我们需要对C++里生成的对象(userdata)进行扩展, 可以如下定义

ClassC跟InstanceC的关系如下图

在调用InstanceC(实际上是一个userdata)上的某个方法时, 首先会先去这个userdata绑定的peer这个table里寻找这个方法,如果找不到才会去c++那层调用。

所以我们可以通过给peer添加几个方法从而实现给InstanceC(userdata)扩展方法, 实际情况上也确实如此,在quick里,有几个专门的类,CCNodeExtend,CCLayerExtend,CCSceneExtend,CCSpriteExtend, 使用比如 CCNodeExtend.extend(someCCNodeInstance), 可以生成一个特殊的peer, 这个peer的metatable为CCNodeExtend, 这样我们就可以在someCCNodeInstance上调用CCNodeExtend定义了而原本CCNode没有的方法, 从而实现扩展。

下面再考虑ClassD从ClassC继承的情况

关系图:

===================

最先是看到下面这篇文章的,也写的很棒

相关文章:http://childhood.logdown.com/posts/169509/detailed-quickcocos2dx-inheritance-mechanism