我正在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标志或其他东西来实现碰撞规则。
然而,我对如何进行只有模糊的想法。任何帮助将不胜感激,包括(可能特别)反馈,以更好的方式来做我想做的事情。谢谢!答案 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
现在我们有一张桌子,里面有我们所有的小怪,还有一种方法可以访问他们的每个位置。如果您有任何进一步的询问,请告诉我。