model层用dictionary存储所有数据
-- 初始化所有卡牌的数据(服务器)
function CardModel:InitAllCardData(data)
for key, value in pairs(data) do
self.dictAllCardData[value.thisId] = value
end
end
-- 获取卡牌数据,通过唯一id
function CardModel:GetCardDataById(thisId)
return self.dictAllCardData[thisId]
end
用字典存储,查找方便。如果用list则每次都要遍历。
key为唯一id,value为具体的数据。
对所有数据进行筛选和排序时,不复制所有数据,而是用list存储所有数据的唯一id,进行筛选和排序
筛选和排序时,我们既要保留原来的所有数据,也要有一份筛选和排序后的数据。只存唯一id,避免复制多一份所有数据。
在筛选的时候,遍历原来的所有数据,用list存下符合的数据的唯一id。
在排序的时候,对list进行排序,通过唯一id,去原来的数据里面获取数据来进行对应的排序判断。
lua里的local最好不要在类里直接使用,除非静态数据,容易导致时序性问题
如:local cardModel = ModelMgr.instance("CardModel")
可能cardModel 需要的东西,在当前脚本创建的时候,还没实现,导致报错
方式1、封装到一个方法里面
function CardUI:GetModel()
return ModelMgr.instance("CardModel")
end
方式2、在初始化或别的方法里面获取了再保存为self.cardModel
各种组件自身的独立性,item:SetData之外不依赖别的数据,除非必需要从Model再读必要的数据之外另说
未改前:
-- 刷新数据(item的索引)
function CardSkillItem:UpdateData(index)
不通用,耦合性太强,里面需要依赖卡牌界面当前选择的卡牌,当前技能是当前卡牌的第几个技能(index)。在当前的卡牌界面,根据index可以方便的获取到卡牌的数据,技能id和技能级别。
但是如果在其他界面就用不了,如单独展示一个技能item。
技能item,一般必须的只是技能id和技能级别。
修改后:
function CardSkillItem:UpdateData(skillId, curLevel)
大部分功能相同的Item的实现方式
方法一、SetData的时候,增加参数来区分。
每个参数对应一种不同的功能。如isShowXXX传个true,false。
缺点很明显,不同的越多,参数越多。
方法二、通过Type来设置,每个type对应一种UI界面
然后里面的逻辑代码,根据具体的type来执行不同代码。
缺点:type多的话,会有一堆的if elseif之类的结构。
方法三、每个Item都是独立的,但是他们会引用共同的部分(推荐)
可以用继承,共同的部分作为基类。
可以用引用,共同的部位作为一个独立的item,其他item都去引用它,如把它放在prefab的子节点。
方法四、同一个item,但包含所有状态。每种需要控制的状态提供对外接口。还有Reset方法重置所有状态
在Awake、onhide的时候,调用Reset方法,把所有状态设置为默认状态。外部需要改变状态的时候,再调用对应状态的方法。
onHide的时候需要设置的原因是,item通常都会用对象池来管理,回池的时候,如果重置状态,会导致下次使用的时候,有状态残留。
不在update里面调用Reset,因为update调用会很频繁。如果已经在Awake、onhide调用Reset了,还是会在刷新的时候,有状态残留,update的时候就要重新设置对应的状态。
当然,如果不同的地方只有一个,那方法一就行了。但是如果你预计后续类似的功能会有不少,那方法三就很适合了。
方法四适合状态多,但是又是同一个item的。如通用的道具item,既要通用,又会包含多种状态。
每次读取配置后,都需要判空,不能直接使用
注意:是每次,不能只在容易出错的地方判断。策划经常会改表,不能因为读表错误导致游戏卡死,游戏部分界面异常都比卡死好多了。