我试图为roguelike实施基于速度的转弯系统。我已经使用metamethods设置了Mob类,因此将以下内容分配给变量会在某些网格坐标处将一个mob生成到地图中:
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
我已经确定要初始化的前两个Mob实例将始终是玩家1和2,分别分配给变量player1和player2。并且,实际上,它可以在玩家之间来回传递控制!但显然,对于功能齐全的游戏而言,这还不够。我也需要怪物。
allTurnCounters表按顺序从每个产生的怪物中获取新条目(包括玩家和怪物的类,因此他们可以共享统计数据)。这是我的问题:如何让Lua动态检索与该表中给定的turn_counter /值相关联的表的名称,并使用它来优先考虑,即使我不喜欢&不知道提前在程序上产生了什么,或者在产生的订单中占据了什么位置?
我有3个想法,其中没有一个我在如何实施方面很扎实。一种方法是将整个实例表发送到另一个表,而不仅仅是它们的turn_counters,然后以某种方式获取一对值(表本身和表中的my_turn),直接更新my_turn的值。 / p>
另一种方法可能是以某种方式使用环境_G ......我仍在仔细研究PiL的第14章,试图让它适应我的目的,但是value = _G [varname]似乎是一个强大的代码,我可能会用它。尚不确定如何。
我的最后一个想法是,可能会写一些字符串感应的find-replace,它可以在每个mob的表中获取一些其他值,然后将它弹出my_turn的前面。比如,为每个mob类型分配一个已知模式的值,我可以在string.find中使用,然后在string.gsub中使用,以便...手动使代码行按预期读取。但是看起来不那么优雅。
我很高兴在这里问我之前的Lua / Love2D问题,所以我想在我思考的时候把它扔掉那里!
答案 0 :(得分:1)
以下是我对如何实施此建议的建议:
而不是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
相同的字段
答案 1 :(得分:0)
这是一个有点笨拙的解决方案,通过结合其他答案的方法可以使其更加优雅。这就是我在等待答案时自己想出来的。
-- 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&#39;分配allMobs [i] .turn_counter的方法,这将大大简化事情并允许未来的扩展。这个答案仅适用于player1,player2和一个名为ant1的蚂蚁。