如何从 class 的多个实例中获取值?
How can I get values from multiple instances of a class?
我正在Love2D中制作一个roguelike作为一个爱好项目。我的方法是尝试尽可能多地使用 Lua 和 Love2D (0.10.1) API 的原生功能,而不依赖像 middleclass 或 HUMP 这样的奇特库,以便更多地了解这门语言。
在阅读了 PiL 关于 OOP 的章节并看到其中的强大功能后,我决定设置一个包含玩家、怪物和其他元素的 Mob class(使用元方法来模拟 class 功能) NPC(任何可以移动的东西)。所以,到目前为止,它工作得很好,我可以轻松地创建各种共享方法和所有东西的实例。但是有很多事情我还不知道该怎么做,其中之一就是阻止我的原型进一步发展。
设置与地图本身的碰撞还不错。我的地图是 table 充满 table 的整数,0 是地板。游戏绘制“.”和“#”和“+”等表示各种无生命的物体,来自每个 table。玩家 1 使用小键盘移动,通过将原始像素位置除以 32 来创建 32x32 "tiles" 的网格来跟踪他们的位置。然后,在 love.keypressed(key) 里面,我有这样的行:
if key == "kp8" and currentmap[player1.grid_y - 1][player1.grid_x] == 0 then
player1.grid_y = player1.grid_y - 1
等等,玩家可以按下的每个键都有 elseifs。这可以防止他们穿过地图本身不是开放地砖的任何东西。
但是,我正在尝试实施某种 "collision detection" 以防止 MOB 相互穿行并用于编写战斗规则,这比较棘手。我有一个方法可以计算生物之间的距离,但有人告诉我这最终可能会导致舍入错误,而且必须为我想要测试的每种生物组合单独编写。
我想知道的是:是否有已知的(最好是优雅的)方法让特定 class 的所有实例将一些值传递给 table?
我想做的是 "ask" 给定地图上的每个生物所在的位置,并将它们 "report" self.grid_x 和 self.grid_y 到另一层仅用于跟踪生物的地图(如果 self.is_here 为真则为 1,否则为 0,或类似),每回合都会更新。然后,我可以根据坐标相等或 foo.is_here 标志或其他东西来实施碰撞规则。
但是,我对如何进行只有模糊的想法。任何帮助将不胜感激,包括(也许尤其是)关于更好地做我想做的事情的反馈。谢谢!
一个简单的想法是为字段的每个单元格存储 "who is here" 信息,并在每个对象的每次移动时更新此信息。
function create_game_field()
-- initialize a table for storing "who is here" information
who_is_here = {}
for y = 1,24 do
who_is_here[y] = {}
for x = 1,38 do
who_is_here[y][x] = 0
end
end
end
function Mob:can_move(dx, dy)
local u = currentmap[self.y + dy][self.x + dx]
local v = who_is_here[self.y + dy][self.x + dx]
if u == 0 and v == 0 then
return true
else
end
end
function Mob:move(dx, dy)
-- update "who is here"
who_is_here[self.y][self.x] = 0
self.x, self.y = self.x + dx, self.y + dy
who_is_here[self.y][self.x] = 1
end
function Mob:who_is_there(dx, dy) -- look who is standing on adjacent cell
return who_is_here[self.y + dy][self.x + dx] -- return mob or nil
end
function Mob:roll_call()
who_is_here[self.y][self.x] = 1
end
用法示例:
-- player1 spawns in at (6,9) on the grid coords
player1 = Mob:spawn(6,9)
-- player1 added to who_is_here
player1:roll_call()
然后,在 love.keypressed(key):
if key == "kp8" and player1:can_move(0, -1) then
player1:move(0, -1)
end
有几种方法可以获取所有实例数据,但其中一种更简单的方法可能是在创建它们时将它们全部添加到 table。如果您为该实例添加整个 table,所有值都将在主 table 中更新,因为它就像一个指针集合。
function mob:new( x, y, type )
self.x = 100
self.y = 200
self.type = type
-- any other declarations you need
table.insert(allMobs, self)
return self
end
这里我们将所有的生物插入table 'allMobs'。一旦我们有了它,我们就可以简单地遍历并获得我们所有的坐标。
for i, v in ipairs(allMobs) do
local x, y = v.x, v.y
-- Do whatever you need with the coordinates. Add them to another table, compare
-- them to others, etc.
end
现在我们有一个 table,里面有我们所有的生物,还有一种访问它们每个位置的方法。如果您有任何疑问,请告诉我。
我正在Love2D中制作一个roguelike作为一个爱好项目。我的方法是尝试尽可能多地使用 Lua 和 Love2D (0.10.1) API 的原生功能,而不依赖像 middleclass 或 HUMP 这样的奇特库,以便更多地了解这门语言。
在阅读了 PiL 关于 OOP 的章节并看到其中的强大功能后,我决定设置一个包含玩家、怪物和其他元素的 Mob class(使用元方法来模拟 class 功能) NPC(任何可以移动的东西)。所以,到目前为止,它工作得很好,我可以轻松地创建各种共享方法和所有东西的实例。但是有很多事情我还不知道该怎么做,其中之一就是阻止我的原型进一步发展。
设置与地图本身的碰撞还不错。我的地图是 table 充满 table 的整数,0 是地板。游戏绘制“.”和“#”和“+”等表示各种无生命的物体,来自每个 table。玩家 1 使用小键盘移动,通过将原始像素位置除以 32 来创建 32x32 "tiles" 的网格来跟踪他们的位置。然后,在 love.keypressed(key) 里面,我有这样的行:
if key == "kp8" and currentmap[player1.grid_y - 1][player1.grid_x] == 0 then
player1.grid_y = player1.grid_y - 1
等等,玩家可以按下的每个键都有 elseifs。这可以防止他们穿过地图本身不是开放地砖的任何东西。
但是,我正在尝试实施某种 "collision detection" 以防止 MOB 相互穿行并用于编写战斗规则,这比较棘手。我有一个方法可以计算生物之间的距离,但有人告诉我这最终可能会导致舍入错误,而且必须为我想要测试的每种生物组合单独编写。
我想知道的是:是否有已知的(最好是优雅的)方法让特定 class 的所有实例将一些值传递给 table?
我想做的是 "ask" 给定地图上的每个生物所在的位置,并将它们 "report" self.grid_x 和 self.grid_y 到另一层仅用于跟踪生物的地图(如果 self.is_here 为真则为 1,否则为 0,或类似),每回合都会更新。然后,我可以根据坐标相等或 foo.is_here 标志或其他东西来实施碰撞规则。
但是,我对如何进行只有模糊的想法。任何帮助将不胜感激,包括(也许尤其是)关于更好地做我想做的事情的反馈。谢谢!
一个简单的想法是为字段的每个单元格存储 "who is here" 信息,并在每个对象的每次移动时更新此信息。
function create_game_field()
-- initialize a table for storing "who is here" information
who_is_here = {}
for y = 1,24 do
who_is_here[y] = {}
for x = 1,38 do
who_is_here[y][x] = 0
end
end
end
function Mob:can_move(dx, dy)
local u = currentmap[self.y + dy][self.x + dx]
local v = who_is_here[self.y + dy][self.x + dx]
if u == 0 and v == 0 then
return true
else
end
end
function Mob:move(dx, dy)
-- update "who is here"
who_is_here[self.y][self.x] = 0
self.x, self.y = self.x + dx, self.y + dy
who_is_here[self.y][self.x] = 1
end
function Mob:who_is_there(dx, dy) -- look who is standing on adjacent cell
return who_is_here[self.y + dy][self.x + dx] -- return mob or nil
end
function Mob:roll_call()
who_is_here[self.y][self.x] = 1
end
用法示例:
-- player1 spawns in at (6,9) on the grid coords
player1 = Mob:spawn(6,9)
-- player1 added to who_is_here
player1:roll_call()
然后,在 love.keypressed(key):
if key == "kp8" and player1:can_move(0, -1) then
player1:move(0, -1)
end
有几种方法可以获取所有实例数据,但其中一种更简单的方法可能是在创建它们时将它们全部添加到 table。如果您为该实例添加整个 table,所有值都将在主 table 中更新,因为它就像一个指针集合。
function mob:new( x, y, type )
self.x = 100
self.y = 200
self.type = type
-- any other declarations you need
table.insert(allMobs, self)
return self
end
这里我们将所有的生物插入table 'allMobs'。一旦我们有了它,我们就可以简单地遍历并获得我们所有的坐标。
for i, v in ipairs(allMobs) do
local x, y = v.x, v.y
-- Do whatever you need with the coordinates. Add them to another table, compare
-- them to others, etc.
end
现在我们有一个 table,里面有我们所有的生物,还有一种访问它们每个位置的方法。如果您有任何疑问,请告诉我。