繁体   English   中英

Javascript Platformer冲突检测

[英]Javascript platformer collision detection

因此,这个问题可能之前曾被问过几次,但我似乎找不到找到使碰撞检测正常工作的方法。

我正在尝试制作HTML canvas / Javascript平台游戏。 如果您想查看它的功能,则在codepen上: https ://codepen.io/Arthurvanhoorebeke/pen/zpaZYM

我正在做的是检查播放器的角在哪个图块/“框”中。 这意味着我可以对播放器上方和下方的块进行检测,但是横向检测非常糟糕。

我知道对底部碰撞的检查是使横向检测混乱的原因,但是我似乎无法修复它。 这就是我现在得到的:

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}
}

我知道只有当玩家方块的一个角碰到其他东西时,才能进行横向检测。 问题是,当玩家击中障碍物时,底部碰撞检查器会更改其垂直位置(至少我认为是问题所在)。

如果您想查看确切的问题,请尝试打开Codepen链接并跳一下...

是否有此修复程序,还是我需要重新考虑整个功能?

完全重新考虑。 借助碰撞检测,其思想是预测一条路径,该路径既适用于2d又适用于3d,并且暗示了更多的完整模拟,然后,如果路径被阻塞,您必须找到(最重要的是经常错过)碰撞点。 因此,在2d中使用盒子时,它变得微不足道。 计算带有XY分量的轨迹向量。 然后测试每个盒子是否发生碰撞,如果很多盒子都使用实例检测球,则只需检查它们之间的距离即可确定是否存在碰撞,并达到一个碰撞点。 然后,冲击矢量将用作角色的下一个位置。 这样可以在边缘反弹并反弹。 希望我能帮上忙。 否则,请指定任何错误,您的代码将签出。

也许您想尝试更改此设置:

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)){

基本上与上述相同,但现在检查上限。 希望这可以帮助。

顺便说一句,尽管我相信这些解决方案是正确的,但是按照建议,无论如何重写该函数都没有害处。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM