2016-09-07 67 views
2

我试图为roguelike实现基于速度的转弯系统。我已经建立了使用元方法一宗黑社会类,使分配以下的变量将产生一个暴徒到地图在某些网格坐标:如何动态检索用于初始化实例的变量?

function Mob:spawn(x,y,m) 
    local mob = {} 
    setmetatable(mob, Mob) 
    mob.x = x 
    mob.y = y 
    mob.is_monster = m 
    return mob 
end 

一旦这样做了,我把以下内容:

function Mob:roll_call() 
    who_is_here[self.y][self.x] = self.is_monster 
    self.turn_counter = self.turn_counter * math.random(0.9, 1.1) 
    table.insert(allTurnCounters, self.turn_counter) 
end 

这会将怪物的self.turn_counter放入表格中。与此同时,在另一个模块中,我定义这两个函数,问题的心脏:

function turn.decrement_counters(dt) -- runs in Dungeon.update(dt) and subtracts from allTurnCounters 
    for i = 1,#allMobsSpawned do 
      if allTurnCounters[i] <= 0 then 
        allTurnCounters[i] = 0 
        turn_active = true 
        whose_turn = i 
        return 
      elseif allTurnCounters[i] > 0 then 
        allTurnCounters[i] = allTurnCounters[i] - (10 * dt) 
      end 
    end 
end 

function turn.whose_is_it() -- called when an entry in allTurnCounters goes zero 
    if whose_turn == 1 then -- spots 1 and 2 in the spawn list are only ever for players 
      player1.my_turn = true -- turns on player 1's keys 
    elseif whose_turn == 2 then 
      player2.my_turn = true -- turns on player 2's keys 
    elseif whose_turn >= 3 then -- above 3 we're in monster territory 

    end 
end 

我已经决定,挑战者的前两个​​实例初始化永远是玩家1和2,分配分别给变量player1和player2。而且,事实上,它可以在玩家之间来回传递控制权。但显然,这对于一款功能齐全的游戏还不够。我也需要怪物。

allTurnCounters表从每个生成的怪物(一个既包含玩家又包括怪物的类别,因此可共享统计数据)中依次获得新条目。这里是我的问题:如何让Lua动态检索与该表中给定的turn_counter /值相关联的表的名称,并将其用于优先考虑,即使在我不知道程序化的情况下提前产卵或在产卵次序中占据什么位置?

我有3个想法,其中没有一个我坚实如何实施。一种方法是将整个实例表发送到另一个表,而不仅仅是它们的turn_counters,然后以某种方式获取一对值(表中的表本身和my_turn),直接更新my_turn的值。

另一种方法可能是使用环境_G ...以某种方式。我仍然在仔细阅读PiL的第14章,试图将它适用于我的目的,但value = _G [varname]似乎是我可以用于此的一个强大的代码。不知道如何,只是尚未。

我最后的想法是写一些可以在每个暴徒的表中获取其他值的字符串感应查找替换,然后将其弹出到my_turn的前面。就像为每个怪物类型分配一个已知模式的值,我可以在一个string.find中使用一个值,然后使用一个string.gsub,像...手动使代码行按预期方式读取。虽然似乎不雅。

我很高兴在这里问我以前的Lua/Love2D问题,所以我想我们在思考的时候把它抛出去!

+0

“我该如何让Lua动态检索与该表中给定的turn_counter/value相关联的表的名称?” - 1)表没有名称,2)在你的代码中,allTurnCounters中的条目和其他表/名称/任何内容之间没有关联。 – immibis

+0

我的意思是“名称”是与表相关的变量,用于初始化Mob类的实例。所以,例如,player1或small_ant1或其他。我知道这些可以重新定义,并且参考不是固定的。但我不确定如何以建设性的方式将这些知识用于这个应用程序,这就是我问的原因。这是正确的,所有的TurnCounters和其他都没有关联。你能提出一个解决这个问题的好方法吗? –

回答

1

这里是我的,你应该如何实现这个建议:

  1. 相反allTurnCounters[i],给小怪turn_counter属性,并使用allMobsSpawned[i].turn_counter。然后,删除allTurnCounters

  2. 而不是存储暴民号​​码whose_turn,存储暴民本身。(注:当我说 “暴民本身”,这是短期的 “参考对暴民本身”)

    所以不是

    whose_turn = i 
    

    你会:

    whose_turn = allMobsSpawned[i] 
    
  3. 现在whose_turn拥有这个轮到它的人。你可以很容易地检查whose_turn == player1,whose_turn == player2等。作为奖励,它不再依赖于玩家成为第一个暴徒。

您可以通过whose_turn访问暴民的属性 - 如果whose_turn == player1例如是真的,那么whose_turn.x访问同一个字段作为player1.x

+0

在间隔的时间内,我自己想出了一个稍微不同的解决方案。但是你的回答有一个很好的建议,我会用自己的回答少一些。 –

0

下面是可以通过结合方法进行更优雅几分janky解决方案另一个答案。这就是我在等待答案时自己提出的。

-- in "Mob.lua" module 
function Mob:roll_call() 
    who_is_here[self.y][self.x] = self.is_monster 
    self.turn_counter = self.turn_counter * math.random(0.9, 1.1) 
    table.insert(allMobs, {self.name, self.turn_counter}) 
    if self.is_monster == true then 
     table.insert(allMonsters, {self.name, self.turn_counter}) 
    end 
end 

    function Mob:move(dx, dy) 
    who_is_here[self.y][self.x] = nil 
     self.x, self.y = self.x + dx, self.y + dy 
     who_is_here[self.y][self.x] = self.is_monster 
     self.turn_counter = 1 * self.speed 
     for k,v in ipairs(allMobs) do 
     if v[1] == self.name then 
      v[2] = self.turn_counter 
     end 
    end 
    self.my_turn = false -- flags turn is over 
    turn_active = false -- flags no active turn 
    end 

-- in "turn.lua" module 
function turn.decrement_counters(dt) 
    if turn_active == false then 
     for k,v in ipairs(allMobs) do 
      v[2] = v[2] - (10 * dt) 
      if v[2] < 0 then 
       v[2] = 0 
       turn_active = true 
       whose_turn = v[1] 
       return 
      end 
     end 
    else turn.whose_is_it() 
    end 
end 

function turn.whose_is_it() 
    if whose_turn == player1.name then 
     player1.my_turn = true 
    elseif whose_turn == player2.name then 
     player2.my_turn = true 
    elseif whose_turn == ant1.name then 
     ant1.my_turn = true 
    end 
end 

turn.whose_is_it()是需要精炼的部分。如果我使用immibis分配allMobs [i] .turn_counter的方法,这将大大简化事情并允许将来扩展。这个答案只适用于player1,player2和特别是名为ant1的蚂蚁。

+0

当你有无限数量的蚂蚁时,你会做什么? (比如说,一个蚂蚁女王每100回合就会在50回合后孵化一次蛋) – immibis

+0

我不明白你为什么不能把怪物本身放到所有怪兽和allMobs中。 – immibis

+0

这就是我最终做的。 –