我正在使用Lua重建Pacman太太,最近刚学会了一系列用于碰撞和移动的瓷砖;我试图重新创造它。这是瓷砖地图:
JEDITERM_SOURCE
这会产生没有错误的迷宫,但我遇到的问题是吃豆子在瓷砖上平滑移动,没有从瓷砖跳到瓷砖,到瓷砖......所以我有这个代码来"顺利"移动Pacman:
nodemap = {
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1},
{1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1},
{1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1},
{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1},
{1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1},
{1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1},
{1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1},
{1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1},
{1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1},
{1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1},
{1,1,1,1,0,1,1,1,1,1,0,1,1,1,0,0,1,1,1,0,1,1,1,1,1,0,1,1,1,1},
{1,1,1,1,0,1,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1},
{1,1,1,1,0,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,0,1,1,1,1},
{1,1,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0,1,1,0,1,1,1,1},
{1,1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1,1},
{1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1},
{1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1},
{1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1},
{1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1},
{1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1},
{1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1},
{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{1,1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,1},
{1,1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,1},
{1,1,0,1,1,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,1,1,0,1,1},
{1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1},
{1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1},
{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
}
mrspacman.dz =面临的角度。
mrspacman.dir =记录的按键。
mrspacman.speed = .1(是一个小数,以便顺利移动)。
执行此代码会导致Pacman在按下向后键时冻结,并且当在角落中旋转,穿过墙壁时其位置变得混乱......可以看到here。
如何解决这个问题?
更新
我添加了一个名为math2的表,由cos和sin fx组成(仅返回4个基本方向的值):
-- Make Pacmans position consist of a single decimal (because over time a number of 1.899999994 will occur and that's ugly)
mrspacman.x = math.floor(mrspacman.x*10)/10
mrspacman.y = math.floor(mrspacman.y*10)/10
--If an arrowkey was pressed (Think of this as "A new direction was queued")
if (mrspacman.nextDirection) then
-- If Pacman is in the center of a tile, then
if (mrspacman.x == math.floor(mrspacman.x)) and (mrspacman.y == math.floor(mrspacman.y)) then
-- If the tile in front of Pacman is empty, set direction to that
if (nodemap[mrspacman.y-math2.sin(mrspacman.dir)][mrspacman.x+math2.cos(mrspacman.dir)]~=1) then
mrspacman.dz = mrspacman.dir
-- Disable this queue
mrspacman.nextDirection = false
end
end
end
-- If Pacman is NOT in the center of a tile
if (mrspacman.x ~= math.floor(mrspacman.x)) or (mrspacman.y ~= math.floor(mrspacman.y)) then
-- Constantly move forwards
mrspacman.x = mrspacman.x + (math2.cos(mrspacman.dz)*mrspacman.speed)
mrspacman.y = mrspacman.y - (math2.sin(mrspacman.dz)*mrspacman.speed)
else
-- If the tile in front of Pacman is empty, move to that tile
if (nodemap[mrspacman.y-math2.sin(mrspacman.dz)][mrspacman.x+math2.cos(mrspacman.dz)] ~= 1) then
mrspacman.x = mrspacman.x + (math2.cos(mrspacman.dz)*mrspacman.speed)
mrspacman.y = mrspacman.y - (math2.sin(mrspacman.dz)*mrspacman.speed)
end
end
答案 0 :(得分:0)
所以问题非常广泛:
如何解决这个问题? 答案是:通过调试程序。
问题非常模糊,视频中的测试用例非常庞大且没有重点。要了解发生了什么,您至少需要详细了解该计划的某些步骤。也就是说,问题是,如果墙壁左侧的瓷砖是空的,那么mrspacman可以穿过墙壁。这暗示了检查墙存在的代码可能存在一些错误。
问题中的代码不完整,因此错误可能源自其外部。然而,在过去的一个小时里,我已经整理了一个原始框架来测试来自问题的代码。 (它列在答案的最后)
玩弄了代码之后,我现在相信整个pacman不仅没有单一的三角函数,而且根本没有浮点数。
float numbers的问题是它们不适合精确计算。有些编译器和计算系统甚至会为你做诅咒。
在编辑之前,有问题的代码中包含正弦和余弦的表达式:
math.floor(math.sin(mrspacman.dir*pi/180))
我现在已经在我的计算机上对其进行了评估,实际上dir
的{{1}}评估为0, 90, 180, 270
。但那是在64位机器上。我不确定TI-Nspire是否可以信任以获得相同的精度。
在我的测试中,我遇到浮动的另一个问题:
0, 1, 0, -1
会在十进制数字中引入错误:对于mrspacman.x = math.floor(mrspacman.x*10)/10
等于mrspacman.x
,它将评估为4.3
,导致pacwoman冻结。奇怪的是,当在提示中直接评估时,它会表现正常。无论如何,该功能的common implementation在地板之前会增加一些偏差:4.2
。
除此之外,轴方向存在轻微的打嗝,由于框架转储的所有调试信息,可以快速检测到这些打嗝。
这就是全部。代码有效(尽管如此,我只是在这里留下this而没有更多的参数)。如果代码仍未在您的设备上运行,则您需要在其他地方查找问题。
我已将变量保留为全局变量,因为它们可能属于您的程序,并且在单个文件脚本中可能并不重要。但总的来说,除非有其他原因,否则制作任何变量math.floor(mrspacman.x*10+0.5)/10
是一个好习惯。
local