Lua固定了瓷砖运动问题

时间:2018-05-16 00:57:49

标签: lua tile ti-nspire

我正在使用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

1 个答案:

答案 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