我在Lua上使用游戏框架。现在,如果我想创建一个按钮,我可以通过为我的按钮创建一个表来保存函数和两个精灵(按钮向下和向上)。
Sprites有很多基本功能,如setLocation(self, x, y)
或getDimensions(self)
。
我不想创建这样的大量函数:
function button.setLocation(self, x, y)
self.buttonUpSprite(self, x, y)
end
但我想"自动"将对按钮的大多数调用直接委托给buttonUp sprite。
只需将按钮表的元表__index
设置为指向精灵就可以将调用转发给精灵的函数,但self
引用会指向按钮仍然没有我要操作的精灵。
这个代表团有干净的方法吗?
答案 0 :(得分:3)
您可以使用嵌套的metatable自动构建重定向函数:
----------------------------------
-- sprite.lua
----------------------------------
local Sprite = {}
local mt = {__index = Sprite}
function Sprite.new(filename)
local sprite_object = {
img = load_image_from_file(filename),
x = 0,
y = 0
}
return setmetatable(sprite_object, mt)
end
function Sprite:setLocation(x, y)
self.x = x
self.y = y
end
function Sprite:getDimensions()
return self.img.getWidth(), self.img.getHeight()
end
return Sprite
----------------------------------
-- button.lua
----------------------------------
local Sprite = require'sprite'
local Button = {}
local function build_redirector(table, func_name)
local sprite_func = Sprite[func_name]
if type(sprite_func) == 'function' then
Button[func_name] = function(button_object, ...)
return sprite_func(button_object.up_sprite, ...)
end
return Button[func_name]
end
end
local mt = {__index = Button} -- main metatable
local mt2 = {__index = build_redirector} -- nested metatable
function Button.new(upSprite)
return setmetatable({up_sprite = upSprite}, mt)
end
return setmetatable(Button, mt2)
----------------------------------
-- example.lua
----------------------------------
local Sprite = require'sprite'
local Button = require'button'
local myUpSprite = Sprite.new('button01up.bmp')
local myButton = Button.new(myUpSprite)
myButton:setLocation(100, 150)
-- Sprite.setLocation() will be invoked with sprite object as self
print(myButton:getDimensions())
-- Sprite.getDimensions() will be invoked with sprite object as self