Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript平台碰撞检测_Javascript_Html - Fatal编程技术网

Javascript平台碰撞检测

Javascript平台碰撞检测,javascript,html,Javascript,Html,所以这个问题以前可能被问过好几次,但我似乎找不到一种方法使碰撞检测正常工作 我正在尝试制作一个HTML画布/Javascript平台游戏。如果您想查看它的功能,请在codepen上: 我所做的是检查我的播放器的角落是哪个瓷砖/盒子。这意味着我可以检测到玩家上方和下方的方块,但是侧向检测非常糟糕 我知道检查底部碰撞会使侧面检测变得混乱,但我似乎无法修复它。 这就是我现在得到的: function tileCheck(world){ var player_topy = Math.ceil(pla

所以这个问题以前可能被问过好几次,但我似乎找不到一种方法使碰撞检测正常工作

我正在尝试制作一个HTML画布/Javascript平台游戏。如果您想查看它的功能,请在codepen上:

我所做的是检查我的播放器的角落是哪个瓷砖/盒子。这意味着我可以检测到玩家上方和下方的方块,但是侧向检测非常糟糕

我知道检查底部碰撞会使侧面检测变得混乱,但我似乎无法修复它。 这就是我现在得到的:

function tileCheck(world){
  var player_topy = Math.ceil(player1.pos[1] / world.squareHeight) || 0;
  var player_bottomy = Math.ceil((player1.pos[1]+player1.height)/world.squareHeight) || 0;
  var player_leftx = Math.floor(player1.pos[0]/world.squareWidth) || 0;
  var player_rightx = Math.floor((player1.pos[0]+player1.width)/world.squareWidth) || 0;

  var topRightBlock = getSquare(world1,player_rightx,player_topy-1); 
  var topLeftBlock = getSquare(world1,player_leftx,player_topy-1);
  var bottomRightBlock = getSquare(world1,player_rightx,player_bottomy-1);
  var bottomLeftBlock = getSquare(world1,player_leftx,player_bottomy-1);
  //checks if blocks are solid
  var topRightSol = world.legend[topRightBlock].solid;
  var topLeftSol = world.legend[topLeftBlock].solid;
  var bottomRightSol = world.legend[bottomRightBlock].solid;
  var bottomLeftSol = world.legend[bottomLeftBlock].solid;

  //This kinda messes up my 'sideways collision detection'.
  if((bottomRightSol && !topRightSol) || (bottomLeftSol && !topLeftSol)){
    player1.pos[1] -= (player1.pos[1]+player1.height) - (player_bottomy-1)*world.squareHeight;
    player1.vel[1] = 0;
    player1.grounded = true;
  }
  else{
    player1.grounded = false;
    }
  if((topLeftSol && !bottomLeftSol) || (topRightSol && !bottomRightSol)){
    player1.pos[1] += player_topy*world.squareHeight - player1.pos[1];
    player1.vel[1] = 0;
  }
  //This doesn't work properly.
  if(topLeftSol && bottomLeftSol){
    player1.vel[0] = 0;
    player1.wallLeft = true;
    player1.pos[0] += (player_leftx+1)*world.squareWidth - player1.pos[0];
  }
  else{player1.wallLeft = false}
  if(topRightSol && bottomRightSol){
    player1.vel[0] = 0;
    player1.wallRight = true;
    player1.pos[0] -= (player1.pos[0]+player1.width) - (player_rightx)*world.squareWidth;
  }
  else{player1.wallRight = false}
}
我知道当只有一个角落的球员块击中其他东西时,横向检测是不起作用的。问题是,当玩家击中一个方块时,其垂直位置会被底部碰撞检查器改变(至少我认为这是问题所在)

如果你想看到确切的问题,试着打开代码笔链接,跳一跳


是否有解决方法,或者我需要重新思考我的整个功能?

完全重新思考。使用碰撞检测的想法是预测路径,这适用于2d以及3d和im,建议进行更全面的模拟,然后如果路径被阻塞,您必须找到(最重要的是经常错过)碰撞点。 因此,在2d中使用长方体变得很简单。 计算具有X和Y分量的轨迹向量。 然后测试每个框是否存在碰撞,如果许多框使用了实例化检测球体,只需检查两个框之间的距离是否接近colldet,即可获得碰撞点。 然后,应将影响向量用作角色的下一个位置。这允许滑动边缘反弹和反弹。
希望我能帮忙。否则,请指定任何错误,您的代码将被签出。

也许您想尝试更改:

if((bottomRightSol | | |!topRightSol)| | |(bottomLeftSol&&!topLeftSol)){

为此:

if((bottomRightSol | | bottomLeftSol)&&(!topRightSol&&!topLeftSol)){

这里的区别是,如果我正确理解了你的代码,你现在应该检查确保你至少在一个角落里与地面相撞,然后确保你没有在角落里与任何东西相撞。我认为这应该可以防止玩家在半空中被移动


编辑以下评论:

//This kinda messes up my 'sideways collision detection'.
  if((bottomRightSol && !topRightSol) || (bottomLeftSol && !topLeftSol)){
    player1.pos[1] -= (player1.pos[1]+player1.height) - (player_bottomy-1)*world.squareHeight;
    player1.vel[1] = 0;
    player1.grounded = true;
  }
  else{
    player1.grounded = false;
    }
  if((topLeftSol && !bottomLeftSol) || (topRightSol && !bottomRightSol)){
    player1.pos[1] += player_topy*world.squareHeight - player1.pos[1];
    player1.vel[1] = 0;
  }
上面的
if
语句我已经建议了修复。下面的第二个语句我将更改为以下内容:

if((topLeftSol | | topRightSol)&&(!bottomLeftSol&!bottomRightSol)){

这与上面的更改基本相同,但现在检查上限。希望这有帮助


顺便说一句,虽然我相信这些解决方案是正确的,但正如建议的那样,重新编写函数也没有什么坏处。

这确实解决了向下移动的问题。但我留下的问题是向上移动……我想我只需重新编写整个函数,我已经编辑了“ifs”,并添加了一个检查,这样底部碰撞就不会产生任何影响当玩家向上移动时。这似乎解决了问题,这样我就可以自己计算出其余的:)谢谢!我已经得到了玩家在一个数组中的速度,所以我可以用它作为一个向量,是吗?谢谢你的详细回答,我会看看我是否能做到这一点