如何从类的多个实例中获取值?

时间:2016-09-04 05:16:51

标签: lua love2d roguelike

我正在Love2D做一个roguelike作为一个爱好项目。我的方法是尝试尽可能多地使用Lua和Love2D(0.10.1)API的原生功能,而不依赖于像middleclass或HUMP这样的花哨库,以便更多地了解该语言。

在阅读了关于OOP的PiL章节并看到了它的强大功能后,我决定建立一个Mob类(使用元方法来模拟类功能),包括玩家,怪物和其他NPC(任何可以移动的东西) )。所以,到目前为止,它工作得很漂亮,我可以轻松地创建各种各样的实例,分享方法和所有这些东西。但是,有很多我不知道该怎么做的事情,其中​​一个就是让我的原型从进一步的进展中恢复过来。

设置与地图本身的碰撞并不是太糟糕。我的地图是充满整数的表格,其中0表示地板。游戏吸引了#34;。"和"#"和" +"并且这样表示来自每个表的各种无生命物体。玩家1使用小键盘移动,并通过将他们的原始像素位置除以32来跟踪他们的位置以创建32x32" tile"的网格。然后,在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。这可以防止他们走过地图本身没有开放地砖的任何东西。

但是,我试图实施某种"碰撞检测"防止MOB彼此走过并使用写作战斗规则,这是更棘手的。我有一个方法来计算怪物之间的距离,但是我告诉这可能最终会导致舍入错误,而且必须为我想要测试的每个怪物组合单独编写。

我想知道的是:是否有一种已知的(最优雅的)方法可以让特定类的所有实例将一些值传递给表格?

我想做的是"问"每个暴徒在给定的地图上,并且有他们"报告" self.grid_x和self.grid_y到另一个地图层,仅用于跟踪怪物(如果self.is_here为真,则为1,如果不为,则为0,或类似),每回合都会更新。然后,我可以基于坐标相等,或者可能是foo.is_here标志或其他东西来实现碰撞规则。

然而,我对如何进行只有模糊的想法。任何帮助将不胜感激,包括(可能特别)反馈,以更好的方式来做我想做的事情。谢谢!

2 个答案:

答案 0 :(得分:0)

一个简单的想法是为该字段的每个单元存储“谁在这里”信息,并在每个对象的每次移动时更新此信息。

 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(键):

if key == "kp8" and player1:can_move(0, -1) then
    player1:move(0, -1)
end

答案 1 :(得分:0)

有几种方法可以获取所有实例数据,但其中一种更简单的方法可能是在创建表时将它们全部添加到表中。如果为该实例添加整个表,则所有值都将在主表中更新,因为它的作用类似于指针集合。

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

在这里,我们将所有小怪插入表格#all; 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

现在我们有一张桌子,里面有我们所有的小怪,还有一种方法可以访问他们的每个位置。如果您有任何进一步的询问,请告诉我。