【cococos 2 d-x 3.2ゲーム開発】lua類、継承、対象向け


1.luaのクラス
luaにはクラスがありません.あるのはテーブルだけです.クラス間の継承は親のテーブルをつなぎ、派生クラスに見つからない属性と方法はメタテーブルで親を検索します.
2.luaのクラスの属性
   classA = {width =10, height=10}
   classA={}
   classA.width=10
   classA.height=10 
どちらの方法も可能で、点self.Width統合呼び出し
3.クラスメソッド
function Box:collsion()
    --            self,    self.xxx        
end

function 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   father
print(son.house)
出力結果はnilであり、コードが
father = {
	house=1
}
father.__index = father --  father __index      
son = {
	car=1
}
setmetatable(son, father)
print(son.house)
出力の結果は1です
これは、cococos 2 dxのクラスでよく見られる理由を説明しています.
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.Cocos 2 dxのクラス
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 = 100
end

function Circle:setRadius(radius)
    self.radius = radius
end

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

local 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
    end
end

~~~

class()             C++            。

     ,        C++      :

~~~ lua

function 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 cls
end

受信が親である場合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/8463883
Box.__index = Box
Box.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)

end

function Box:onEnter(pic_path)
end

function Box:onExit()
end


function Box.create(parent, position)
    local box = Box.New("data/box.png")
    parent:addChild(box)
    return box
end

return Box

tableならそのまま使えます
local Bomb = class("Bomb")

7.よく見られるcococos 2 dxの例にはextendとtoluaが大量に存在する.getpeerの使い方は次のとおりです.
local TimelineTestScene = class("TimelineTestScene")
TimelineTestScene.__index = TimelineTestScene

function TimelineTestScene.extend(target)
    local t = tolua.getpeer(target)
    if not t then
        t = {}
        tolua.setpeer(target, t)
    end
    setmetatable(t, TimelineTestScene)
    return target
end

function 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