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

本文转载自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

  1. functionBox:collsion()

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

  3. end

  4. functionBox.create(self)

  5. --必须手动传递参数self,否则无法用self.xxx调用属性和方法

  6. 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

  • 版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

    相关推荐


        本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
    Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
    第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
        Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
    1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
       Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
     下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
    分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
    1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
    原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
    2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
    原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
    环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
    1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
    原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
    原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
    为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
    Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
    需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
    v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是