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

问题描述:

背景信息:我正在用HTML5画布制作一个非常基本的2D平台。 在我的主循环中,我遍历所有对象以检查玩家是否站在对象上。如果是这样,我结束该函数的执行直到下一个循环。为什么这段代码似乎在return语句后执行?

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

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(意味着该函数应该退出本身,对吗?)后,它会继续循环其他对象并将player.grounded设置为false,这会导致游戏本身的诡计。 (理论上它是有效的,但玩家不停地上下摆动,这不是一个真正的好景象)。

我试过各种东西。使用新的属性,计算玩家可以站在的对象的数量,似乎没有任何工作。我觉得我忽略了一些东西,但我不确定这可能是什么。

(抱歉文本墙!)

更新:这是standingCheck方法:

const standingCheck = (a, b) => { 
    // a = player, b = object 
    if(a.isFalling){ 
    if(!(a.pos.x > b.pos.x + b.width || a.pos.x + a.width < b.pos.x)){ //x 
     if(a.pos.y + a.height < b.pos.y && a.pos.y + a.height >= b.pos.y){ //y 
      return true; 
     } 
    } 
    } 
} 
+0

返回FALSE; ?并将我更新为objects.length,i = objects.length。 – Roberrrt

+0

return;等于返回false – Gatsbill

+0

@Gatsbill它实际上等于'return undefined;'然后在逻辑表达式中求值为false。 ;) – zfor

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

There 可能是 绝对是一个更快的方式来做到这一点,但现在工作。

我如何固定它:

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