【cocos2d-x3.2游戏开发】 lua 类, 继承, 面向对象

【cocos2d-x3.2游戏开发】 lua 类, 继承, 面向对象,第1张

概述本文转载自http://blog.csdn.net/teng_ontheway/article/details/38900211 1.lua中的类     lua中其实是没有类的,有的只是表(table),而类之间的继承也就是将父类的表连到了一起,派生类中没有找到的属性和方法就通过元表查找父类 2.lua中类的属性    classA = {width =10, height=10}    cla

本文转载自http://blog.csdn.net/teng_ontheway/article/details/38900211


1.lua中的类

lua中其实是没有类的,有的只是表(table),而类之间的继承也就是将父类的表连到了一起,派生类中没有找到的属性和方法就通过元表查找父类

2.lua中类的属性

classA = {wIDth =10,height=10}

classA={}

classA.wIDth=10

classA.height=10

两种方法都可以,通过点self.wIDth统一调用

3.类方法


[cpp]view plaincopy

functionBox:collsion()

--默认第一个参数隐藏传递self,可以通过self.xxx调用属性和方法

end

functionBox.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设置为father

print(son.house)

输出结果是nil,如果代码改为

father={

house=1

}

father.__index=father--把father的__index方法指向自己

son={

car=1

}

setMetatable(son,father)

print(son.house)

输出的结果就为1了

这就解释了为什么我们经常在cocos2dx的类中经常见到如下

localBox=class("Box",function(filename)

returncc.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的基础类

localShape=class("Shape")

--ctor()是类的构造函数,在调用Shape.new()创建Shape对象实例时会自动执行

functionShape:ctor(shapename)

self.shapename=shapename

printf("Shape:ctor(%s)",self.shapename)

end

--为Shape定义个名为draw()的方法

functionShape:draw()

printf("draw%s",self.shapename)

end

--

--Circle是Shape的继承类

localCircle=class("Circle",Shape)

functionCircle:ctor()

--如果继承类覆盖了ctor()构造函数,那么必须手动调用父类构造函数

--类名.super可以访问指定类的父类

Circle.super.ctor(self,"circle")

self.radius=100

end

functionCircle:seTradius(radius)

self.radius=radius

end

--覆盖父类的同名方法

functionCircle:draw()

printf("draw%s,raIDus=%0.2f",self.shapename,self.raIDus)

end

--

localRectangle=class("Rectangle",Shape)

functionRectangle:ctor()

Rectangle.super.ctor(self,"rectangle")

end

--

localcircle=Circle.new()--输出:Shape:ctor(circle)

circle:setRaIDus(200)

circle:draw()--输出:drawcircle,radius=200.00

localrectangle=Rectangle.new()--输出:Shape:ctor(rectangle)

rectangle:draw()--输出:drawrectangle

~~~

###高级用法

class()除了定义纯Lua类之外,还可以从C++对象继承类。

比如需要创建一个工具栏,并在添加按钮时自动排列已有的按钮,那么我们可以使用如下的代码:

~~~lua

--从cc.Node对象派生Toolbar类,该类具有cc.Node的所有属性和行为

localToolbar=class("Toolbar",function()

returndisplay.newNode()--返回一个cc.Node对象

end)

--构造函数

functionToolbar:ctor()

self.buttons={}--用一个table来记录所有的按钮

end

--添加一个按钮,并且自动设置按钮位置

functionToolbar:addbutton(button)

--将按钮对象加入table

self.buttons[#self.buttons+1]=button

--添加按钮对象到cc.Node中,以便显示该按钮

--因为Toolbar是从cc.Node继承的,所以可以使用addChild()方法

self:addChild(button)

--按照按钮数量,调整所有按钮的位置

localx=0

for_,buttoninipairs(self.buttons)do

button:setposition(x,0)

--依次排列按钮,每个按钮之间间隔10点

x=x+button:getContentSize().wIDth+10

end

end

~~~

class()的这种用法让我们可以在C++对象基础上任意扩展行为。

既然是继承,自然就可以覆盖C++对象的方法:

~~~lua

functionToolbar:setposition(x,y)

--由于在Toolbar继承类中覆盖了cc.Node对象的setposition()方法

--所以我们要用以下形式才能调用到cc.Node原本的setposition()方法

getMetatable(self).setposition(self,x,y)

printf("x=%0.2f,y=%0.2f",y)

end

~~~

**注意:**Lua继承类覆盖的方法并不能从C++调用到。也就是说通过C++代码调用这个cc.Node对象的setposition()方法时,并不会执行我们在Lua中定义的Toolbar:setposition()方法。

@paramstringclassname类名

@param[mixedsuper]父类或者创建对象实例的函数

@returntable

]]

functionclass(classname,super)

localsuperType=type(super)

localcls

ifsuperType~="function"andsuperType~="table"then

superType=nil

super=nil

end

ifsuperType=="function"or(superandsuper.__ctype==1)then

--inheritedfromnativeC++Object

cls={}

ifsuperType=="table"then

--copyfIEldsfromsuper

fork,vinpairs(super)docls[k]=vend

cls.__create=super.__create

cls.super=super

else

cls.__create=super

cls.ctor=function()end

end

cls.__cname=classname

cls.__ctype=1

functioncls.new(...)

localinstance=cls.__create(...)

--copyfIEldsfromclasstonativeobject

doinstance[k]=vend

instance.class=cls

instance:ctor(...)

returninstance

end

else

--inheritedfromLuaObject

ifsuperthen

cls={}

setMetatable(cls,{__index=super})

cls.super=super

else

cls={ctor=function()end}

end

cls.__cname=classname

cls.__ctype=2--lua

cls.__index=cls

functioncls.new(...)

localinstance=setMetatable({},cls)

instance.returninstance

end

end

returncls

end


传入是一个父类的话,会调用cls.new函数,然后创建实例,调用ctor构造函数

6. 调用一个实例:

假设派生自一个cocos的类 Sprite

--class可以传1、2个参数

--@param类名,内部做记录而已,一般和返回的类名一致即可

--@param如果传参数2使用当前函数作为构造函数如果没参数2默认的构造函数

localBox=returncc.Sprite:create(filename)

end)

--设置元彪更改元表默认的元方法

--访问table中不存在的字段时,解释器查找__index的元方法,否则返回nil

--多用于继承http://blog.csdn.net/q277055799/article/details/8463883

Box.__index=Box

Box.isDead=false--定义属性

--构造函数(会自动调用)

--外界构造时可以传任意参数XXX.new(...)

functionBox:ctor(pic_path)

localfunctiononNodeEvent(event)

if"enter"==eventthen

Box:onEnter(pic_path)

elseif"exit"==eventthen

Box:onExit()

end

end

self:registerScriptHandler(onNodeEvent)

localfunctiononUpdate()

end

self:scheduleUpdateWithPriorityLua(onUpdate,0)

end

functionBox:onEnter(pic_path)

end

functionBox:onExit()

end

functionBox.create(parent,position)

localBox=Box.New("data/Box.png")

parent:addChild(Box)

returnBox

end

returnBox


如果是一个table,可以直接使用

localBomb=class("Bomb")


7.我们常见cocos2dx的例子中有大量的extend和tolua.getpeer用法如下:

localTimelineTestScene=class("TimelineTestScene")

TimelineTestScene.__index=TimelineTestScene

functionTimelineTestScene.extend(target)

localt=tolua.getpeer(target)

ifnottthen

t={}

tolua.setpeer(target,t)

end

setMetatable(t,TimelineTestScene)

returntarget

end

functionTimelineTestScene.create()

localscene=TimelineTestScene.extend(cc.Scene:create())

returnscene

end

用的时tolua.getpeer,其实它的功能就相当于调用了class,所以请远离extend吧

class("TimelineTestScene",cc.Scene)

TimelineTestScene.__index=TimelineTestScene

总结

以上是内存溢出为你收集整理的【cocos2d-x3.2游戏开发】 lua 类, 继承, 面向对象全部内容,希望文章能够帮你解决【cocos2d-x3.2游戏开发】 lua 类, 继承, 面向对象所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1073610.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-26
下一篇2022-05-26

发表评论

登录后才能评论

评论列表(0条)