Lua元表:类字段与实例字段
2014-5-7 18:9:8
收藏:0
阅读:147
评论:2
我正在使用Corona/Lua制作一个游戏,并实现了一个名为“Item”的类,用于表示游戏中的武器、装甲、护身符等,但是我对面向对象的Lua不熟悉。
创建类的新实例后,我发现设置对象的某些属性似乎将它们设置到类元表中,而不是对象本身。
以下是类和构造函数:
local Item = {
name = nil,
itemType = nil,
scarcity = "basic",
baseDamage = 0, -- Bow only
bonuses = {
damageBonus = 0,
speedBonus = 0,
critBonus = 0,
dropBonus = 0,
rechargeBonus = 0,
xpBonus = 0
}
}
-- Creates a simple blank instance of the Item class.
function Item:new(o)
local item = o or {}
setmetatable(item, self)
self.__index = self
return item
end
现在假设我基于此原型创建了两个对象:
local bow = Item:new()
bow.itemType = "bow"
starterBow.baseDamage = 5
local ring = Item:new()
ring.itemType = "ring"
ring.bonuses.damageBonus = 0.25
令人沮丧的是,“bonuses.damageBonus”属性似乎被设置在元表中,因此应用于每个项目(即弓也获得伤害奖励,并与戒指叠加)。然而,该行为似乎仅限于“bonus”属性。如果我设置“itemType”属性,则如预期那样附加到对象而不是类。
我想看到的行为是可以针对个别项目设置“bonuses”表的字段。您知道我做错了什么吗?谢谢!
点赞
用户3585949
__index 元字段会在你试图从表格中获取一个不存在的字段时触发。
ring.bonuses.damageBonus = 0.25 试图从 ring 获取 bonuses,由于它不存在,会去元表中查找并返回你的 bonuses 表格,然后将它的 damageBonus 索引设置为 0.25。
要理解的是,仅在 Item 表格中声明变量并不意味着你的 Item 实例会将它们作为实例变量继承。为此,你需要在 Item:new() 函数中声明/初始化它们:
function Item:new(o)
local item = o or {}
setmetatable(item, self)
self.__index = self
item.bonuses={} -- 创建实例 bonuses 表格并设置默认值
for k,v in pairs(self.bonuses) do
item.bonuses[k]=v
end
return item
end
2014-05-07 18:57:51
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
bonuses表在实例中不存在,所以查找时会在元表中查找,并在__index表中找到它。然后继续在该表中查找。类似地,赋值也是一样的。然而只有一个bonuses表,这是关键,因为你从未复制它,唯一存在的副本是在Item类中,然后通过__index元表查找找到它。你可以为每个实例添加
__index元表魔法(对于默认值但局限于实例的赋值),也可以为每个实例简单地复制/创建新的bonuses表。