为什么这段代码似乎在return语句之后执行?

时间:2016-08-18 12:49:02

标签: javascript html5 loops game-physics

背景信息:我正在使用HTML5画布制作一个非常基本的2D平台游戏。 在我的主游戏循环中,我遍历所有对象以检查玩家是否站在一个物体上。如果是这样,我结束函数的执行直到下一个循环。

如果对象和玩家发生碰撞,在使用return退出该功能之前(因为我们知道玩家正站在该对象上),我在Y轴上设置了玩家的速度为0,稍微调整他的Y位置只是为了正确对齐他和对象,并将玩家的属性player.grounded设置为true。这是主要问题所在。它是与player.isFalling属性绑定的必需布尔值。更新功能检查玩家的Y速度是否高于0并检查他是否未接地。在那种情况下player.isFalling是真的。仅当isFalling为真时,才会执行standingCheck辅助函数。

const standingCheckHandler = (player) => {
  for(let i = 0; i < objects.length; i ++){
    if(standingCheck(player, objects[i])){
      player.pos.y = objects[i].pos.y - player.height;
      player.velocity.y = 0;
      player.grounded = true;
      return;
    }else{
      player.grounded = false;
    }
  }
}

现在出现问题:即使我退出函数,或使用break,循环仍然继续迭代其他对象。我会记录player.grounded,甚至在设置为true之后(这意味着函数应该自行退出,对吗?),它将继续循环其他对象并设置{{ 1}}到player.grounded,这导致游戏本身的狡猾的运动。 (从理论上讲它是有效的,但是玩家继续上下浮动,这并不是一个很好的景象)。

我尝试过各种各样的事情。使用新属性,计算玩家可以站立的对象数量,似乎没有任何效果。我觉得我忽略了某些东西,但我不确定那可能是什么。

(抱歉文字墙!)

更新:这是standCheck方法:

false

1 个答案:

答案 0 :(得分:1)

我想我找到了答案。虽然它没有直接修复bug,但我设法通过引入一个新的帮助函数来解决这个问题:
groundedCheckstandingCheck大致相同。它基本上只检查玩家是否有效地仍然接地(如果player.y + player.height等于object.y)。

可能 肯定是一种更快捷的方式,但现在可以使用。

我是如何解决的:

const standingCheckHandler = (player) => {
  for(let i = 0; i < objects.length; i ++){
    if(standingCheck(player, objects[i])){
      player.pos.y = objects[i].pos.y - player.height;
      player.velocity.y = 0;
      player.grounded = true;
      break;
    }
  }
  // this is new
  if(player.grounded){
    let len = objects.length;
    for(let j = 0; j < objects.length; j ++){
      if(!groundedCheck(player, objects[j])){
        len --;
      }
    }
    if(len <= 0){
      player.grounded = false;
    }
  }
}

// so is this
const groundedCheck = (a, b) => {
  // a = player, b = object
  if(!(a.pos.x > b.pos.x + b.width || a.pos.x + a.width < b.pos.x)){
    if(a.pos.y + a.height === b.pos.y){
      return true;
    }
  }
}