【cocos2d-x3.2游戏开发】 lua 类, 继承, 面向对象
来源:互联网 发布:淘宝的的vx是什么意思 编辑:程序博客网 时间:2024/05/05 16:16
1.lua中的类
lua中其实是没有类的,有的只是表(table),而类之间的继承也就是将父类的表连到了一起,派生类中没有找到的属性和方法就通过元表查找父类
2.lua中类的属性
classA = {width =10, height=10}
classA={}
classA.width=10
classA.height=10
两种方法都可以,通过点self.width统一调用
3.类方法
function Box:collsion() -- 默认第一个参数隐藏传递self,可以通过self.xxx 调用属性和方法endfunction Box.create(self) --必须手动传递参数self,否则无法用self.xxx调用属性和方法end函数的声明和调用可以用":"和".",属性调用全部用点"."
4.类与元表的用法
lua查找一个表元素时的规则,其实就是如下3个步骤:
4.1.在表中查找,如果找到,返回该元素,找不到则继续
4.2.判断该表是否有元表,如果没有元表,返回nil,有元表则继续
4.3.判断元表有没有__index方法,如果__index方法为nil,则返回nil;如果__index方法是一个表,则重复1、2、3;如果__index方法是一个函数,则返回该函数的返回值
例如:
father = {house=1}son = {car=1}setmetatable(son, father) --把son的metatable设置为fatherprint(son.house)输出结果是nil,如果代码改为
father = {house=1}father.__index = father -- 把father的__index方法指向自己son = {car=1}setmetatable(son, father)print(son.house)输出的结果就为1了
这就解释了为什么我们经常在cocos2dx的类中经常见到如下
local Box = class("Box", function(filename) return cc.Sprite:create(filename) end)Box.__index = Box设置Box的元表的__index方法为自己,当派生类"SmallBox"派生自"Box",如果在SmallBox中查找不到的属性和方法,就检索元表,当然不是直接从元表中直接检索,是检索元表下的__index,如果__index为nil,则返回nil,如果__index是一个表,那么就到__index方法所指的表中查找对应的属性和方法
具体可以参考:Lua查找表元素过程(元表、__index方法是如何工作的)
5.Cocos2dx中的类
lua没有面向对象一说,cocos为我们准备了class的lua端函数,我们参考quick的class函数,里面还有对应的例子
--[[--创建一个类~~~ lua-- 定义名为 Shape 的基础类local Shape = class("Shape")-- ctor() 是类的构造函数,在调用 Shape.new() 创建 Shape 对象实例时会自动执行function Shape:ctor(shapeName) self.shapeName = shapeName printf("Shape:ctor(%s)", self.shapeName)end-- 为 Shape 定义个名为 draw() 的方法function Shape:draw() printf("draw %s", self.shapeName)end---- Circle 是 Shape 的继承类local Circle = class("Circle", Shape)function Circle:ctor() -- 如果继承类覆盖了 ctor() 构造函数,那么必须手动调用父类构造函数 -- 类名.super 可以访问指定类的父类 Circle.super.ctor(self, "circle") self.radius = 100endfunction Circle:setRadius(radius) self.radius = radiusend-- 覆盖父类的同名方法function Circle:draw() printf("draw %s, raidus = %0.2f", self.shapeName, self.raidus)end--local Rectangle = class("Rectangle", Shape)function Rectangle:ctor() Rectangle.super.ctor(self, "rectangle")end--local circle = Circle.new() -- 输出: Shape:ctor(circle)circle:setRaidus(200)circle:draw() -- 输出: draw circle, radius = 200.00local rectangle = Rectangle.new() -- 输出: Shape:ctor(rectangle)rectangle:draw() -- 输出: draw rectangle~~~### 高级用法class() 除了定义纯 Lua 类之外,还可以从 C++ 对象继承类。比如需要创建一个工具栏,并在添加按钮时自动排列已有的按钮,那么我们可以使用如下的代码:~~~ lua-- 从 cc.Node 对象派生 Toolbar 类,该类具有 cc.Node 的所有属性和行为local Toolbar = class("Toolbar", function() return display.newNode() -- 返回一个 cc.Node 对象end)-- 构造函数function Toolbar:ctor() self.buttons = {} -- 用一个 table 来记录所有的按钮end-- 添加一个按钮,并且自动设置按钮位置function Toolbar:addButton(button) -- 将按钮对象加入 table self.buttons[#self.buttons + 1] = button -- 添加按钮对象到 cc.Node 中,以便显示该按钮 -- 因为 Toolbar 是从 cc.Node 继承的,所以可以使用 addChild() 方法 self:addChild(button) -- 按照按钮数量,调整所有按钮的位置 local x = 0 for _, button in ipairs(self.buttons) do button:setPosition(x, 0) -- 依次排列按钮,每个按钮之间间隔 10 点 x = x + button:getContentSize().width + 10 endend~~~class() 的这种用法让我们可以在 C++ 对象基础上任意扩展行为。既然是继承,自然就可以覆盖 C++ 对象的方法:~~~ luafunction Toolbar:setPosition(x, y) -- 由于在 Toolbar 继承类中覆盖了 cc.Node 对象的 setPosition() 方法 -- 所以我们要用以下形式才能调用到 cc.Node 原本的 setPosition() 方法 getmetatable(self).setPosition(self, x, y) printf("x = %0.2f, y = %0.2f", x, y)end~~~**注意:** Lua 继承类覆盖的方法并不能从 C++ 调用到。也就是说通过 C++ 代码调用这个 cc.Node 对象的 setPosition() 方法时,并不会执行我们在 Lua 中定义的 Toolbar:setPosition() 方法。@param string classname 类名@param [mixed super] 父类或者创建对象实例的函数@return table]]function class(classname, super) local superType = type(super) local cls if superType ~= "function" and superType ~= "table" then superType = nil super = nil end if superType == "function" or (super and super.__ctype == 1) then -- inherited from native C++ Object cls = {} if superType == "table" then -- copy fields from super for k,v in pairs(super) do cls[k] = v end cls.__create = super.__create cls.super = super else cls.__create = super cls.ctor = function() end end cls.__cname = classname cls.__ctype = 1 function cls.new(...) local instance = cls.__create(...) -- copy fields from class to native object for k,v in pairs(cls) do instance[k] = v end instance.class = cls instance:ctor(...) return instance end else -- inherited from Lua Object if super then cls = {} setmetatable(cls, {__index = super}) cls.super = super else cls = {ctor = function() end} end cls.__cname = classname cls.__ctype = 2 -- lua cls.__index = cls function cls.new(...) local instance = setmetatable({}, cls) instance.class = cls instance:ctor(...) return instance end end return clsend
传入是一个父类的话,会调用cls.new函数,然后创建实例,调用ctor构造函数
6. 调用一个实例:
假设派生自一个cocos的类 Sprite
-- class可以传1、2个参数-- @param 类名,内部做记录而已,一般和返回的类名一致即可-- @param 如果传参数2 使用当前函数作为构造函数 如果没参数2 默认的构造函数local Box = class("Box", function(filename) return cc.Sprite:create(filename) end)-- 设置元彪 更改元表默认的元方法-- 访问table中不存在的字段时,解释器查找__index的元方法,否则返回nil-- 多用于继承 http://blog.csdn.net/q277055799/article/details/8463883Box.__index = BoxBox.isDead = false --定义属性-- 构造函数(会自动调用)-- 外界构造时可以传任意参数XXX.new(...)function Box:ctor(pic_path) local function onNodeEvent(event) if "enter" == event then Box:onEnter(pic_path) elseif "exit" == event then Box:onExit() end end self:registerScriptHandler(onNodeEvent) local function onUpdate() end self:scheduleUpdateWithPriorityLua(onUpdate, 0)endfunction Box:onEnter(pic_path)endfunction Box:onExit()endfunction Box.create(parent, position) local box = Box.New("data/box.png") parent:addChild(box) return boxendreturn Box
如果是一个table,可以直接使用
local Bomb = class("Bomb")
local TimelineTestScene = class("TimelineTestScene")TimelineTestScene.__index = TimelineTestScenefunction TimelineTestScene.extend(target) local t = tolua.getpeer(target) if not t then t = {} tolua.setpeer(target, t) end setmetatable(t, TimelineTestScene) return targetendfunction TimelineTestScene.create() local scene = TimelineTestScene.extend(cc.Scene:create()) return scene end
用的时tolua.getpeer,其实它的功能就相当于调用了class,所以请远离extend吧
local TimelineTestScene = class("TimelineTestScene", cc.Scene)TimelineTestScene.__index = TimelineTestScene
6 0
- 【cocos2d-x3.2游戏开发】 lua 类, 继承, 面向对象
- 【cocos2d-x3.2游戏开发】 lua 类, 继承, 面向对象
- Cocos2d-x Lua游戏开发之Lua 面向对象编程
- Cocos2d-Lua之面向对象的继承
- lua 类, 继承, 面向对象
- lua 类, 继承, 面向对象
- lua 类, 继承, 面向对象
- cocos2d-x3.0 lua开发环境
- cocos2d-x3.x+Lua开发工具
- cocos2d-x lua 面向对象
- Lua 之 面向对象 -- 继承
- lua面向对象、继承、多态
- Cocos2d-x3.0 lua绑定C++类
- Cocos2d-x3.0 lua绑定C++类
- cocos2d-x3.2 lua 返回键监听
- cocos2dx游戏开发学习笔记3-lua面向对象分析
- 游戏2048--基于cocos2d-x3.2
- 《游戏觉醒之Cocos2d-x3.10游戏开发》- 生命周期
- android popwindow类似QQ中控件
- linux free命令中buffer与cache的区别
- Android开发环境搭建 总结
- android 用release key 发布 百度地图
- cocos2dx schedule可延时的for循环 scheduleonce的问题
- 【cocos2d-x3.2游戏开发】 lua 类, 继承, 面向对象
- HDU1284钱币兑换问题
- POJ 1637 Sightseeing tour (混合图欧拉回路)
- js中 opener和parent的区别
- air max pas cher and put her purse snatched the phone. "The girl said the man robbed not tall
- Java中super的几种用法并与this的区别
- toms outlet I asked you to go to the ballpark where the ballpark Yeah
- giuseppe shoes the child has been successfully vaccinated in Shaanxi
- 总结一下Android Handler机制。