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

我正在使用Love2D作为我的业余项目,制作一个roguuelike游戏。我的方法是尽可能地利用Lua的本地功能和Love2D(0.10.1) API,而不是依赖于像middleclass或HUMP这样的高级库,以便更多地了解这种语言。

在阅读PiL对OOP的章节并看到其强大功能后,我决定设置一个Mob类(使用元方法模拟类功能),它包含玩家、怪物和其他NPC(任何可以移动的东西)。到目前为止,它的运作非常完美,我可以轻易地创建各种实例,这些实例共享方法和所有东西。但是有很多事情我还不知道如何做,其中一个是阻止我进一步进展。

设置与地图本身的碰撞并不困难。我的地图是由一个个整数组成的表格,0表示地板。游戏根据每个表格绘制"."和"#"和"+"等字符来表示各种静态对象。玩家1使用数字键盘移动,其位置由将其原始像素位置除以32以创建32x32的"瓷砖"的网格来跟踪。然后,在love.keypressed(key)内,我有像这样的代码行:

if key == "kp8" and currentmap[player1.grid_y - 1][player1.grid_x] == 0 then
        player1.grid_y = player1.grid_y - 1

以此类推,对于每个玩家可以按键的键,都有elseif语句。这可以防止他们在地图本身不是开放地板的任何东西中行走。

但是,我正在尝试实现某种"碰撞检测",以防止MOB互相穿越,以及在编写战斗规则时使用,这更加棘手。我已经有了一种计算MOB之间距离的方法,但是我被告知这可能最终会导致舍入误差,同时必须为我要测试的每个MOB组合单独编写。

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

我想要做的是,在给定地图上“询问”每个Mob它们的位置,并使它们向另一层地图“报告”self.grid_x和self.grid_y,该层地图仅用于跟踪MOB,如果self.is_here为true则为1,否则为0或类似),每回合更新。然后,我可以基于坐标相等或者可能是foo.is_here标志之类的实现碰撞规则。

然而,我对如何继续只有模糊的想法。任何帮助都将不胜感激,包括(也许特别包括)反馈关于我试图做的事情更好的方法。谢谢!

点赞
用户1847592
用户1847592

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

function create_game_field()
    -- 初始化用于存储“谁在这里”的信息的表格
    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)
    -- 更新“谁在这里”
    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) -- 查看谁站在相邻的单元格上
    return who_is_here[self.y + dy][self.x + dx] -- 返回 mob 或 nil
end

function Mob:roll_call()
    who_is_here[self.y][self.x] = 1
end

用法示例:

-- player1 在网格坐标 (6,9) 处生成
player1 = Mob:spawn(6,9)
-- player1 添加到 who_is_here
player1:roll_call()

然后,在 love.keypressed(key) 中:

if key == "kp8" and player1:can_move(0, -1) then
    player1:move(0, -1)
end
2016-09-04 07:58:06
用户6336645
用户6336645

有几种方法可以获取所有实例数据,但其中比较简单的一种可能是在创建实例时将它们全部添加到表格中。只要为该实例添加整个表格,所有值都将在主表格中更新,因为它充当了指针的集合。

function mob:new( x, y, type )
    self.x = 100
    self.y = 200
    self.type = type
    --任何其他必要声明
    table.insert(allMobs, self)
    return self
end

在这里,我们将所有移动对象插入表格“allMobs”中。一旦我们做到了这一点,我们就可以简单地遍历表格并获取所有坐标。

for i, v in ipairs(allMobs) do
    local x, y = v.x, v.y
    --进行任何您需要的坐标操作。将它们添加到另一个表格中,与其他坐标进行比较等等。
end

现在我们有了一个包含所有移动对象的表格,并且可以访问它们各自的位置。如果您还有任何其他疑问,请告诉我。

2016-09-04 08:31:56