解决了,查看最后算法的帖子底部
背景:我正在使用JS和HTML canvas元素处理2D平台游戏.关卡图是基于图块的,但播放器没有夹在图块上.我在Code inComplete中使用了"Tiny Platformer"中概述的碰撞检测算法.它主要适用于一个边缘情况(或''ledge''情况).
问题:

玩家正在倒下并向右移动进入墙壁.当它下降时,它会传送到壁架的高度.相反,玩家应该在没有传送的情况下正常下降.
有没有办法改变算法来防止这种行为?如果没有,你能建议一个备用的碰撞检测算法吗?理想情况下,任何修复都不会假设玩家总是摔倒,因为在游戏中玩家的跌倒方向在上/下/左/右之间切换.
算法:
假设没有碰撞,计算玩家的新位置.(未在下面的代码中显示)
一个被调用的函数getBorderTiles接受一个对象(玩家)并返回触及每个玩家4个角落的图块.由于玩家不大于瓷砖,因此这些边框瓷砖必然是玩家正在触摸的唯一瓷砖.请注意,其中一些图块可能相同.例如,如果玩家仅占据一列,则左上/右上方的区块将与左下方/右下方区块相同.如果发生这种情况,getBorderTiles仍会返回所有四个图块,但有些图块会相同.
它会检查水平贴图(2D阵列)中的这些边框切片,看它们是否是实心的.如果图块是实心的,则该对象与该图块碰撞.
它测试上/下/左/右碰撞.如果玩家向下移动并与向下的瓷砖碰撞但没有与相应的向上的瓷砖碰撞,则玩家正在向下碰撞.如果玩家向左移动并与左侧瓷砖碰撞但没有与相应的右侧瓷砖碰撞,则它向左碰撞.等等.在向左/向右检查之前执行向上/向下检查.如果在执行左/右检查之前存在向上/向下碰撞,则调整存储边界图块的变量.例如,如果玩家碰撞,它将被推入向上的区块,因此BL/BR区块现在与TL/TR区块相同.
玩家的x,y和速度将根据其碰撞的方向进行调整.
算法失败的原因:

右下方的瓷砖是实心的,但是右上方没有,所以(步骤4)玩家向下碰撞并且(步骤5)它被向上推.此外,它与BR瓦片碰撞但不与BL碰撞,因此它向右碰撞并向左推.最后,玩家将被渲染到壁架的上方和左侧.实际上它是传送的.
尝试解决方案:我试图修复此问题,但它只创建了另一个问题.我添加了一个检查,以便玩家只有在瓷砖内有一定距离(例如3px)时才与瓷砖碰撞.如果玩家只是在BR牌中,则该算法不会记录下来的碰撞,因此玩家不会传送.但是,如果球员在另一场比赛中摔倒在地,那么直到球员进入地面才会确认碰撞.当玩家跌落到地面,被推回地面,再次跌落等等时,玩家会感到不安.
感谢您阅读这篇文章.我非常感谢您的反馈.
当前算法代码:
var borderTiles = getBorderTiles(object), //returns 0 (a falsy value) for a tile if it does not fall within the level
tileTL = borderTiles.topLeft,
tileTR = borderTiles.topRight,
tileBL = borderTiles.bottomLeft,
tileBR = borderTiles.bottomRight,
coordsBR = getTopLeftXYCoordinateOfTile(tileBR), //(x, y) coordinates refer to top left corner of tile
xRight = coordsBR.x, //x of …Run Code Online (Sandbox Code Playgroud)