1. 程式人生 > >[cocos2dx]cocos2dx-lua中class語法

[cocos2dx]cocos2dx-lua中class語法

在lua中,可以通過元表來實現類、物件、繼承等。與元表相關的方法有setmetatable()、__index、getmetatable()、__newindex

關鍵:實現Lua面向物件可以分解為類的定義和類的例項化兩個問題。類的定義主要是實現繼承,即怎麼讓子類擁有父類的方法集類的例項化需要解決例項如何共享類的方法集,但獨享自己的成員變數例項
方案:子類在定義時複製所有基類的方法,在例項化時將該類作為metatable的__index賦值給例項。這就是cocos2dx裡面的lua class的實現。

function clone(object)--clone函式
  local lookup_table = {}--新建table用於記錄
  local function _copy(object)--_copy(object)函式用於實現複製
    if type(object) ~= "table" then 
      return object   ---如果內容不是table 直接返回object(例如如果是數字\字串直接返回該數字\該字串)
    elseif lookup_table[object] then
      return lookup_table[object]--這裡是用於遞迴滴時候的,如果這個table已經複製過了,就直接返回
    end
    local new_table = {}
    lookup_table[object] = new_table--新建new_table記錄需要複製的二級子表,並放到lookup_table[object]中.
    for key, value in pairs(object) do
      new_table[_copy(key)] = _copy(value)--遍歷object和遞迴_copy(value)把每一個表中的資料都複製出來
    end
    return setmetatable(new_table, getmetatable(object))--每一次完成遍歷後,就對指定table設定metatable鍵值
  end
  return _copy(object)--返回clone出來的object表指標/地址
end
--[[
clone  深度克隆一個值。
格式:value = clone(值)
用法示例:
-- 下面的程式碼,t2 是 t1 的引用,修改 t2 的屬性時,t1 的內容也會發生變化
local t1 = {a = 1, b = 2}
local t2 = t1
t2.b = 3    -- t1 = {a = 1, b = 3} <-- t1.b 發生變化
 
-- clone() 返回 t1 的副本,修改 t2 不會影響 t1
local t1 = {a = 1, b = 2}
local t2 = clone(t1)
t2.b = 3    -- t1 = {a = 1, b = 2} <-- t1.b 不受影響
--]]

--Create an class.
function class(classname, super)--super為繼承的類
    local superType = type(super)
    local cls

    --如果父類既不是函式也不是table則說明父類為空
    if superType ~= "function" and superType ~= "table" then
        superType = nil
        super = nil
    end

    --如果父類的型別是函式或者是C物件
    if superType == "function" or (super and super.__ctype == 1) then
        -- inherited from native C++ Object
        cls = {}

        --如果父類是表則複製成員並且設定這個類的繼承資訊
        --如果是函式型別則設定構造方法並且設定ctor函式
        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

        --定義該型別的建立例項的函式為基類的建構函式後複製到子類例項
        --並且呼叫子數的ctor方法
        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
        --如果是繼承自普通的lua表,則設定一下原型,並且構造例項後也會呼叫ctor方法
        -- 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 cls
end
通過該方法,我們可以很方便的定義一個class、繼承一個class
--宣告一個類:
MyClass = class("MyClass")  
function MyClass:ctor()  
    print("MyClass:ctor()")  
end  
--定義一個物件  
local myclass = MyClass:new()  

--繼承一個類:
--繼承一個函式
GameLayer = class("GameLayer", function()local layer = cc.Layer:create() return layer end)  
local gamelayer = GameLayer:new()

ctor=constructor(建構函式)
dtor=destructor(解構函式)

1.在子類建構函式ctor()中要呼叫父類建構函式ctor(),這用self.super:ctor(param),這句話反應出並不會像C++那樣,在建立子類例項時,自動呼叫父類的建構函式。
2.使用class(classname,super)來子類繼承父類只會繼承父類的成員函式,而不會繼承父類的成員變數。

若要子類既要繼承父類的成員函式也要繼承父類的成員變數,且在建立子類例項時,自動呼叫父類的建構函式。這用下面的class(classname,super)

function class(classname, super)    
    local cls = {}
    if super then
        cls = {}
        for k,v in pairs(super) do cls[k] = v end
        cls.super = super
    else
        cls = {ctor = function() end}
    end

    cls.__cname = classname
    cls.__index = cls

    function cls.new(...)
        local instance = setmetatable({}, cls)
        local create
        create = function(c, ...)
             if c.super then -- 遞歸向上呼叫create
                  create(c.super, ...)
             end
             if c.ctor then
                  c.ctor(instance, ...)
             end
        end
        --create(instance, ...)--若替換成instance:ctor(...)則先呼叫自己的建構函式,若自己沒有,則呼叫父類的建構函式
        instance:ctor(...)
        instance.class = cls
        return instance
    end
    return cls
end

local BaseClass = class("BaseClass", nil)
function BaseClass:ctor(param)
     print("baseclass ctor")
     self._param = param
     self._children = {}
end
function BaseClass:addChild(obj)
     table.insert(self._children, obj)
     for k,v in ipairs(self._children) do
        print(k,v)
     end
end

local DerivedClass = class("DerivedClass", BaseClass)
function DerivedClass:ctor(param)
     print("derivedclass ctor")
end

local instance = DerivedClass.new("param1")
instance:addChild("child1")
--列印輸出
--baseclass ctor
--derivedclass ctor
--1 child1
極具有參考價值的文章:Lua 面向物件實現

相關推薦

[cocos2dx]cocos2dx-luaclass語法

在lua中,可以通過元表來實現類、物件、繼承等。與元表相關的方法有setmetatable()、__index、getmetatable()、__newindex。 關鍵:實現Lua面向物件可以分解為類的定義和類的例項化兩個問題。類的定義主要是實現繼承,即怎麼讓子類擁有父類

luaclass的一種實現方式,單例擴充

方式 tab 方法 span 實用 ble 核心 攔截 說我 先上代碼 1 local _class={} 2 3 function class(super,singleton) 4 local class_type={} 5

cocos2d-x luaclass的定義

在lua中要實現對類的定義一般都是通過metatable來做到的。。例如: Fjs = {} function Fjs:new(name) local out = {} setmetatable(out, self) self.__index = self out

cocos2dx-lualua專案class(sub,super)的理解

lua 模擬面向物件的繼承通常是通過class方法,今天簡析一下對class的理解,先例子 local MyApp = class("MyApp", cc.load("mvc").AppBase) 這是MyApp裡的一個方法繼承語句,class方法內部

cocos2dx lua使用class實現繼承api的類

如果需要擴充套件api中的類時,使用繼承的方式,需要重寫的就重寫,需要擴充套件就擴充套件 直接上程式碼,程式碼中有解釋 require "extern" --使用class方法需要的exte

lua 處理cocos2dx 的button 事件

close bsp then list type ddt cocos2 uic 取消 1、引入這個類:require "GuiConstants" 2、下面是回調函數的處理. local function menuZhuCeCallback(sender,eventTyp

Cocos2dx-LuaSprite精靈的3種創建方法

value text cocos2d color width obb set ttext fun ---1.從圖片文件創建 --適合於要顯示的這張圖片的全部區域或部分區域 function TestTest:CreateSprite1() local png =

Cocos2dx-lua使用LuaSocket

pri 客戶端使用 receive 一定的 根據 約定 組件 重點 cvt 項目背景 客戶端:C++和lua混合,cocos2dx 3.10版本;服務端:C++,某狐公司的棋牌服務端。 需求   手機客戶端使用socket與服務端通信,需要處理數據粘包半包、字符串編碼轉換、

Cocos2dx 3.x Lua socket 和 node.js 利用scoket互相通訊讀寫二進位制資料

第一部分,Lua socket如何讀寫二進位制資料。 cocos2dx 3.x 版本已經集成了lua socket所以可以直接使用無需自己整合。首先需要初始化lua socket 如下: socket = require("socket"); tcp

cocos-Luaclass與require機制

繼承 manager 包含 logic str src 傳參數 loaded 全局變量 cocos-Lua中的class與require機制 local layer = require("PaiGow.src.GamePlayerListLayer")local Gam

cocos2dx&cocos2dx-lua專案匯入龍骨DragonBones

前言 本來我也是直接百度的,看看有沒有現成的方法,然而看了幾篇,沒有能直接用的,只能自己搞了。 首先說下,這篇文章很長,不過我會按步驟加上標題的,可以直接看自己感興趣的部分。 然後是我的執行環境:win10+vs2017+cocos2d-x-3.17(之後可能會補上ma

cocos-Luaclass與require機制(小積累)

local layer = require("PaiGow.src.GamePlayerListLayer") local GameTableUI = class("GameTableUI", require("gamemanager.GameViewBase")); 一

Quick-Cocos2dx-Community lua繫結,lua呼叫C++ 類

這裡有篇文章,看三和四。 按上面操作,檔案都不缺少的,可以直接看  2. 和 3 . 記住:player3 來開啟專案, 的類格式化後,放到他的原始碼路徑下面, 解釋生成的lua 也要放到 api下面 player3  重新生成就可以了 player3    最後開

詳解es6 class語法constructor方法和super的作用

首先,ES6 的 class 屬於一種“語法糖”,所以只是寫法更加優雅,更加像面對物件的程式設計,其思想和 ES5 是一致的。 function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = fun

Cocos2d+Lua 遊戲開發的奇技淫巧系列之一 Lua require的語法

  媽蛋,感覺寫的部落格,又要爛尾了,我有罪,我的定力太差了,這就是我這麼聰明,這麼多年卻只能混成個窮逼的根本原因嗎?趕緊趁今天在公司暫時沒有事情做,先發一篇文章..... --------------------------------------------------

cocos2dx 3.2 Sequence和Spawn無法執行RepeatForever動作的問題解決

   (博主qq,1204802552,歡迎交流)  有時候,我們想在Sequence或者Spawn中加入RepeatForever的動作,但在實際執行中,該迴圈動作並未得到執行,我們先來說下解決的方法。    對於Spawn,很簡單,我們只需要把RepeatForever

cocos2dx(3.X)使用shader

一 shader的基本概念 1 什麼是shader shader即著色器,就是專門用來渲染3D圖形的一種技術。 通過shader,可以自己編寫顯示卡渲染畫面的演算法,使畫面更漂亮、更逼真。 2 shader分類 shader又分兩種,一種是

cocos2dx遊戲開發的問題

1.  模擬器的選擇 windows模擬器:   你遇到過模擬器不更新圖片的坑麼?你遇到過一張圖片在模擬器上顯示好好的?到了真機上顯示不出來麼?windows模擬器的字型為什麼比真機大呢?vs裡寫漢

cocos2dx-3.0 的關於物理引擎Box2D與chipmunk

~~~~我的生活,我的點點滴滴!!            http://www.cocos2d-x.org/wiki/Physics 上面這個連結是官方的,我隨便翻譯了一下,其實大意就是:cocos2dx 3.0(只能確定3.0,不知道後面版本有沒有新增)中有兩種物理

cocos2dx-3.0 的物理引擎Box2D使用(三)

~~~~我的生活,我的點點滴滴!! 我們從一個簡單的遊戲小豬快跑中抽出Box2D程式碼來講講在cocos2dx中使用Box2D,雖然不可能涉及到全部Box2D的應用,但是熟能生巧, 舉一反三。還是老規矩,要使用Box2D得有個物理世界,首先需要建立一個world物件,用