Corona LUA和面向对象设计
所以,我来自使用面向对象编程原则的传统游戏开发领域,从我所见,你可以通过了解 LUA 来模拟这种编程方式。在一些代码发布中,我发现你可以使用 director 类,并创建具有 new() 函数等的文件。我正在寻找一种管理武器的方法。我有一个玩家和一个对手,我希望只有一个武器类,比如 weaponCanon。我所做的是:
-- 此处为私有变量
local power
local canonSprite
local whatever
local someFunction = function()
...
end
-- 此处为私有内容
local weaponCanon = {}
weaponCanon.fire = function(atX, atY)
...
end
weaponCanon.reset = function()
...
end
return weaponCanon
然后我只需要在我的关卡代码中如下调用:
local weaponCanon = require("weaponCanon")
weaponCanon.fire(100, 100)
这很好用,可以让我在编写武器代码时使用“私有”和“公共”的心态。问题在于,如果我希望玩家和对手拥有加农炮:
local playerWeapon = require("weaponCanon")
local opponentWeapon = require("weaponCanon")
它只会返回相同的对象,而不是新实例。所以只有在 opponentWeapon 处我得到一个 weaponCanon。这显然不是我想要或需要的。我们的游戏中有很多武器,有一个方法是只有一个每个文件版本,并使用一个设置告诉我们它是对手武器还是玩家武器。另一种方法是复制每个文件,并创建 weaponPlayerCanon 和 weaponOpponentCanon,但我想到每次修改一个文件并必须更改 2+ 个文件就会毛骨悚然。
我该如何使其返回实例,以及如何构造 LUA 文件?感谢你提供的任何帮助!
-d
原文链接 https://stackoverflow.com/questions/6345365
这里没有对象 - 你只有一堆全局数据。你真的需要创建实例。
function NewWeapon(arg)
return {
fire = function(self, atX, atY)
print(self.var)
end,
var = arg,
}
end
NewWeapon(3):fire(1, 2)
NewWeapon(7):fire(3, 5)
如果您后来需要继承(即,LaserCannon 是 Weapon 的子类),您可能需要更深入地使用元表。
有很多库可以让您在 Lua 上进行“面向对象编程”。您可以在此处查看非常好的列表:
http://lua-users.org/wiki/ObjectOrientedProgramming
我是 middleclass 的作者。使用我的库,您需要执行以下操作:
local Weapon = class('Weapon')
function Weapon:initialize(a,b,c)
self.x,self.y,self.z = a,b,c
end
function Weapon:fire(x,y)
...
end
很容易实现 LaserCannon - 您只需向类传递第二个参数:
local LaserCannon = class('LaserCannon', Weapon)
function LaserCannon:initialize(a,b,c,d)
self.w = d
Weapon.initialize(self, a,b,c) -- superclass' constructor
end
function LaserCannon:foo()
...
end
您可以像这样使用它:
require 'middleclass' -- so you can use "class"
LaserCannon = require 'laser_cannon'
local playerWeapon = LaserCannon:new() -- a laser
local opponentWeapon = Weapon:new() -- a regular generic weapon
opponentWeapon:fire(100,200) -- typical use
playerWeapon:fire(100, 200) -- LaserCannon inherits fire from Weapon
playerWeapon:foo() -- LaserCannon-exclusive
这是使用我喜欢的 middleclass 做的。我之前提到的页面上的其他库提供类似的功能。
虽然你为武器对象创建了一个新的表,但并没有创建新的变量。在模块顶部声明的任何变量都是静态变量(即,所有类实例共享的变量)。要创建唯一于该对象的变量,需要在表中创建它们,例如:
weaponCannon = {}
weaponCannon.power = 10
而且你只需要创建一个对象,需要一个“构造函数”来创建表:
function new()
local weaponCannon = {}
weaponCannon.power = 10
end
顺便提一下,与你的答案没有直接相关性的两件非常有用的修改代码。首先,在方法中使用冒号而不是句号调用函数将允许您在方法内使用“self”关键字,例如:
function weaponCannon:fire()
--this is only a test
print(self.power)
end
然后
local playerWeapon = require("weaponCanon")
playerWeapon:fire()
其次,您实际上可以将显示对象用作表,而不必创建一个空表,然后将显示对象放入该空表中:
weaponCannon = display.newImage("cannon.png")
weaponCannon.power = 10
请注意,如果这样做,您无法设置元表。我发现这种方法看起来更合乎逻辑,因此不喜欢使用元表,但这是您的决定。
我喜欢ponzao的回答。但是我会对它进行更改:
local WeaponCannon = {}
function WeaponCannon:new()
local instance = {}
setmetatable(instance, {__index = WeaponCannon})
-- 在这里设置你的新实例
return instance
end
function WeaponCannon:fire(x, y)
-- 通过self引用和参数(x,y)进行某些操作
end
return WeaponCannon
在您的调用代码中:
local WeaponCanon = require('WeaponCannon')
local playerWeapon = WeaponCannon:new()
local opponentWeapon = WeaponCannon:new()
我做出了以下更改:
- 创建本地实例变量以允许在返回实例之前进行设置
- 更紧凑的设置元表的方法
- 在调用代码时使用一个变量来表示类
- 如何在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中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
我猜你想用你的源文件建立一个类的模型。这意味着除非你希望它们共享所有状态,否则你还应该有一个函数来创建该类的新实例。
如下所示(未经测试):
local WeaponCannon = {} WeaponCannon.__index = WeaponCannon function WeaponCannon:new() return setmetatable({}, self) end function WeaponCannon:fire(x, y) -- 通过 self 引用和参数(x,y)执行某些操作 end return WeaponCannon
在你的调用代码中(同样未经测试):
require('WeaponCannon') local playerWeapon = WeaponCannon:new() local opponentWeapon = WeaponCannon:new()