cocos2dx lua继承C++类

这段时间用lua在做一个项目,用cocos2dx为基础来开发,采用lua脚本语言为核心语言。但是对lua几乎零基础的我,处处碰壁。首先了解到lua一般是用面向过程的方式来写脚本,并且看到cocos2dx里的lua sample几乎都是用的面向过程的方式来写的,但是我还是比较熟悉C++的面向对象的方式来写。

先是研究到lua通过元表的方式可以模拟面向对象的编程方式,但在网上多数的资料都是子类继承lua写的基类,而cocos2dx却要继承C++的类,所以cocos2dx里的extern.lua就派上用场了,它里面编写了lua继承C++类的模板,直接调用class函数就可以实现继承cocos2dx里C++类。

extern.lua保存在cocos2dx的cocos2d-x-2.2.1\samples\Lua\TestLua\Resources\luaScript\extern.lua。

以下简单写写试用方式:

 

require "luaScript/extern.lua"

local Login = class("Login",
	function()
		return CCLayer:create()
	end
)

function Login:create()
	local ret = Login.new()
	ret:init()
	return ret
end

function Login:init()
	--添加需要的初始化脚本
	
end


然后就可以用local login = Login:create()来创建以上的子类了。

 

 

但是随着功能的增加发现又要重写C++父类的方法,该怎么写呢,又在网上一通查找,可以没发现几个真正能用的方式。最后还是发现了一个blog写的实现了这样的功能。链接地址是http://www.litefeel.com/lua-override-userdata/。实际上早有发现这样个blog,但是当时没看明白就忽略了,后来再次发现的时候,茅塞顿开。这里简单写下我的使用方式,以上链接的blog写了几种实现的方式,各有利弊。

方法一:

 

local _setVisible = nil
local MyLayer = class("MyLayer", function()
    local layer = CCLayer:create()
    -- save c++ member method point.
    _setVisible = layer.setVisible
    return layer
end)
-- override CCLayer::setVisible
function MyLayer:setVisible(visible)
    -- invoke CCLayer::setVisible
    _setVisible(self, visible)
    -- to do something.
end

以上方法一虽然是作者说的最优的方法,但是总感觉这样写很别扭。而且怀疑实例化以上多个类时,_setVisible这个变量是不是被所有实例化的类共享的,比较懒一直没去证实。 

 

方法二:

 

local MyLayer = class("MyLayer", function()
    return CCLayer:create()
end)
-- override CCLayer::setVisible
function MyLayer:setVisible(visible)
    -- invoke CCLayer::setVisible
    getmetatable(self).setVisible(self, visible)
    -- to do something.
end

此方法二虽然实现很简洁,但是经测试,以上的方式只能继承C++的直接父类,父类的父类是不能继承的。我也很喜欢这中实现方式,但很遗憾,不是所有情况都能用。

 

 

然后继承了C++的父类,怎么添加lua类里自己的成员变量呢,网上大多数都是这样写的:

require "extern"
  
MySprite = class("MySprite", 
    function(fileName) 
        return CCSprite:create(fileName)  
    end 
) 
  
MySpriteMySprite.__index = MySprite
  
MySprite.type = 0
  
function MySprite:createMS(fileName,_type)
    local mySprite = MySprite.new(fileName) 
    mySprite:myInit(_type) 
    return mySprite 
end 
  
function MySprite:myInit(_type)
    self.type =_type 
end 

但是经使用发现,以上的方法 MySprite.type = 0 这个成员变量是被所有实例化的lua类共享的,所有此种方式对于实例化一次的类来说使用不影响,但如果多次实例化就出现问题了。经过多次研究测试后发现以下这样写就可以被多次实例化:

 

 

require "extern"

MySprite = class("MySprite",
    function(fileName)
        return CCSprite:create(fileName)
    end
)

function MySprite:createMS(fileName,_type)
    local mySprite = MySprite.new(fileName)
    mySprite.type = 0
    mySprite:myInit(_type)
    return mySprite
end
  
function MySprite:myInit(_type)
    self.type =_type
end


可能刚开始接触lua的时候看到过这样的说法,self类似于C++里的this,大概可以这样理解,但并不是完全一样。self.var里的self是指当前var所属于的table,与直接使用Table.var是不一样的(这里的Table是指定义的table变量名)。

 

 

以上都是自己在使用lua过程中,对lua的一些结论和认识,如有发现问题,欢迎指正和讨论。

 

最后给自己写的小游戏打下广告,一个释放你压力的小游戏,一个你敢叫它敢动的小游戏。敢不敢来试下?

点击下载,或在 Google Play Store 搜索 Make a Noise

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值