quick的MVC

来源:互联网 发布:mysql需要多大内存 编辑:程序博客网 时间:2024/06/18 16:39

前端时间,因为项目需要,要用到战斗,自己就写了一下游戏的战斗,现在的战斗模式跟之前的有点不一样,之前项目中使用的是想dota传奇那种类型的,自动战斗模式的战斗机制,半自动的,中间会打断的。

先来说说之前的战斗逻辑,主要还是分2层,数据处理的逻辑层,AI表现 。我们战斗的数据逻辑的模块代码与服务器共用一套。因为服务器要对游戏中的战斗进行验证。战斗开始的时候,战斗人物的信息数据都是从服务器发来。游戏战斗的数据与服务器值交互2次,一次是战斗开始的时候,还有就是战斗结束的时候。发送数据包不像回合货moba类型的那么频繁。

现在开始先说MVC中的model模块

Model的功能。Quick中的model可以用于游戏中的一些道具数据类之类的。在数据多的类中的华,优势很快就能体现出来了。刚开始使用lua的时候,在自己的道具数据类,卡牌数据类的时候,每一项数据都要自己手动写,当时就感觉听麻烦的。Quick中的model在数据属性的时候就会方便很多。例如一个角色昵称,等级,气血

那么就可以直接定义它的属性

 

local Actor = class("Actor",cc.mvc.ModelBase)

Actor.schema =clone(cc.mvc.ModelBase.schema)

Actor.schema["nickname"] ={"string"} -- 字符串类型,没有默认值

Actor.schema["level"]    = {"number", 1} -- 数值类型,默认值 1

Actor.schema["hp"]       = {"number", 1}

Actor.schema["mydefine"] ={"number", 10}

 

之后我们在类中可以直接通过

Self.level_来获取那项数值

 

例如我们定义

Actor.schema["abc"] ={"number", 10}  -- abc属性名字number属性类型10默认值

 

我们在Actor类是从cc.mvc.ModelBase类中继承而来,那么我们就去看ModelBase是怎么实现的。在这里我有一个小小的建议:对于一些初学者,学习代码没几年的小伙伴,也包括我(今年刚毕业,程序小屌丝)。有空可以多去看看引擎中的一些类的实现,在看他们代码的同时总结下他们写代码的哪里好,可以可以借鉴模仿,那样自己的代码质量也会越来越高。刚开始看quick的代码会有点吃力,但是看多了,熟悉了,也都懂了。Quick代码还是比较好理解的。

localModelBase =class("ModelBase")

ModelBase.idkey = "id"

ModelBase.schema = {

id = {"string"}

}

ModelBase.fields = {"id"}

 

local function filterProperties(properties,filter)

fori, field in ipairs(filter) do

properties[field] = nil

end

end

 

functionModelBase:ctor(properties)

cc(self):addComponent("components.behavior.EventProtocol"):exportMethods()

 

self.isModelBase_ = true

if type(properties) ~= "table"then properties = {} end

self:setProperties(properties)

end

 

functionModelBase:getId()

local id = self[self.class.idkey .."_"]

assert(id ~= nil,string.format("%s:getId() - invalid id", self.class.__cname))

return id

end

 

functionModelBase:isValidId()

localpropname = self.class.idkey .."_"

local id = self[propname]

return type(id) == "string" andid ~= ""

end

 

functionModelBase:setProperties(properties)

assert(type(properties) =="table", string.format("%s:setProperties() - invalidproperties", self.class.__cname))

   -- 类中的数据属性都存放在self.class.schema这个变量中

   -- self[propname] = val中存放数据这就是为什么我们能够直接通过self.XX_的形式直接得到数据值

   -- 以schema["mydefine"] = {"number", 10} 的方式存在

for field, schema inpairs(self.class.schema) do

       local typ, def = schema[1], schema[2]  -- 类型定义

localpropname = field .. "_"

 

       local val = properties[field] -- 自己设置属性的时候的值

       if val ~= nil then   -- 存在就改变值

iftyp == "number" then val =tonumber(val) end

assert(type(val) == typ,string.format("%s:setProperties() - type mismatch, %s expected %s, actualis %s", self.class.__cname, field, typ, type(val)))

self[propname] = val

elseifself[propname] == nil and def ~= nilthen  --若为空

           if type(def) == "table" then -- 值为表那么就克隆一个表对象

val = clone(def)

elseif type(def) == "function"then  -- 如果函数就一定一个函数属性

val = def()

            else                                    -- 其他就是一个值可能是数字货userdata...

val = def

end

self[propname] = val

end

end

 

return self

end

 

functionModelBase:getProperties(fields,filter)

local schema = self.class.schema

if type(fields) ~= "table" thenfields = self.class.fields end

 

   --遍历自己存在的数据找到相应的数据值

local properties = {}

fori, field in ipairs(fields) do

localpropname = field .. "_"

localtyp = schema[field][1]

localval = self[propname]

assert(type(val) == typ,string.format("%s:getProperties() - type mismatch, %s expected %s, actualis %s", self.class.__cname, field, typ, type(val)))

properties[field] = val

end

 

   --properties中的数据都是以"XXX_"

if type(filter) == "table" then

filterProperties(properties, filter)

end

 

   -- 数据都是以properties["hp"] = self["hp_"] 的方式存放在properties中

   -- 第二个参数是过滤用的可以用来删除一些属性数据

   -- 例如self:getProperties({"hp", "level"},{"hp"})  --可以把hp这样属性数据删除

   -- 这只是在得到数据的时候不会返回那样属性值,类中这样属性值还是存在的

return properties

end

 

returnModelBase

 

各个函数接口的功能

主要还是调3个重要的接口说下

filterProperties(properties, filter)用于过滤属性用

setProperties(properties)设置属性

getProperties(fields, filter)获得属性

 

里面主要还是setProperties(properties)跟:getProperties(fields,filter)这2个方法。通过这2个方法我们在处理数据的时候就会比传统的方法方便很多

例如我们想修改之前定义的abc这项数据的值,那么我们可以直接直接使用

Actor:setProperties({abc=12})来改变abc这项属性的值.同时也支持多想属性

如果想要获得某一项属性的值,那么就直接Actor:setProperties({“abc”}).同样也支持多项属性同时获得

player:getProperties({"hp","level",”abc”})

这样做项目中是不是使用起来很方便呢

 

0 0