如何动态检索用于初始化实例的变量?
我试图为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问题,所以我想我们在思考的时候把它抛出去!
这里是我的,你应该如何实现这个建议:
相反
allTurnCounters[i]
,给小怪turn_counter
属性,并使用allMobsSpawned[i].turn_counter
。然后,删除allTurnCounters
。-
而不是存储暴民号码
whose_turn
,存储暴民本身。(注:当我说 “暴民本身”,这是短期的 “参考对暴民本身”)所以不是
whose_turn = i
你会:
whose_turn = allMobsSpawned[i]
现在
whose_turn
拥有这个轮到它的人。你可以很容易地检查whose_turn == player1
,whose_turn == player2
等。作为奖励,它不再依赖于玩家成为第一个暴徒。
您可以通过whose_turn
访问暴民的属性 - 如果whose_turn == player1
例如是真的,那么whose_turn.x
访问同一个字段作为player1.x
在间隔的时间内,我自己想出了一个稍微不同的解决方案。但是你的回答有一个很好的建议,我会用自己的回答少一些。 –
下面是可以通过结合方法进行更优雅几分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的蚂蚁。
“我该如何让Lua动态检索与该表中给定的turn_counter/value相关联的表的名称?” - 1)表没有名称,2)在你的代码中,allTurnCounters中的条目和其他表/名称/任何内容之间没有关联。 – immibis
我的意思是“名称”是与表相关的变量,用于初始化Mob类的实例。所以,例如,player1或small_ant1或其他。我知道这些可以重新定义,并且参考不是固定的。但我不确定如何以建设性的方式将这些知识用于这个应用程序,这就是我问的原因。这是正确的,所有的TurnCounters和其他都没有关联。你能提出一个解决这个问题的好方法吗? –