如何在返回值时不破坏 function/loop (Js)

How NOT to break a function/loop on returning a value (Js)

嘿,我正在制作一个 2D 瓷砖游戏,或者我真的只是在胡闹。我用一个数组制作了地图,其中 0 代表什么都没有,其他字符代表一个可步行的瓦片。

var map=[["t","t","t","t","t","t","t","t","t","t","t","t","t","t","t","t","t","t","t","t"],
    ["l","1","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","r"],
    ["l","r","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","r"],
    ["l","1","t","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","l","r"],
    ["l","1","1","t","t","t","t","t","t","t","t","t","t","t","t","r","0","0","l","r"],
    ["l","b","b","b","b","b","b","b","b","1","1","b","b","b","b","b","t","t","b","r"],
    ["0","0","0","0","0","0","0","0","0","l","r","0","0","0","0","0","0","0","0","0"],
    ["0","0","0","0","0","0","0","0","0","l","r","0","0","0","0","0","0","0","0","0"],
    ["0","0","0","0","0","0","0","0","0","l","r","0","0","0","0","0","0","0","0","0"],
    ["0","0","0","0","0","0","0","0","l","1","1","r","0","0","0","0","0","0","0","0"],
    ["0","0","0","0","0","0","0","l","1","1","1","1","r","0","0","0","0","0","0","0"],
    ["t","t","t","t","t","t","t","1","1","1","1","1","1","t","t","t","t","t","t","t"]];

On screen it looks like this

你也可以在这里看到我的可移动角色。 现在我已经走到这一步了,我希望我的角色与我的地图数组中表示为 0 值的空图块发生碰撞。

这是我检查碰撞的代码(脚本中括号是正确的):

function collisioncheck(ind){
for(var i in map){
    for(var j in map[i]){
        if(yass==true){
            if(map[i][j]==0){
                if(ind==0 && playerPosX==j*32+32 && playerPosY>i*32-32 && playerPosY<i*32+32){
                    return false;
                }else if(ind==1 && playerPosX==j*32-32 && playerPosY>i*32-32 && playerPosY<i*32+32){
                    return false;
                }else if(ind==2 && playerPosY==i*32+32 && playerPosX>j*32-32 && playerPosX<j*32+32){
                    return false;
                }else if(ind==3 && playerPosY==i*32-32 && playerPosX>j*32-32 && playerPosX<j*32+32){
                    return false;
                }else{
                    return true;
                }
            }
        }else{
            return true;
        }
    }
}
var yass=false;
function exist(){
for(var i in map){
    for( var j in map[i]){
        if(map[i][j]==0){
            yass=true;
            break;
        }
    }
}

所以,这行得通。但仅限于地图中的第一个 0。我的问题是 return 语句破坏了 for 循环和函数。所以我的角色不会与第一个以外的任何其他空白图块发生碰撞。

我将不得不重写这个,但是有什么聪明的解决方案吗?

Link to jsfiddle here(字符不可见)

您需要在第 15 行

主 if/else 块的最后一个 else 中使用 continue 而不是 return

你走在正确的轨道上,你的循环只运行一次迭代,因为你总是 return 迭代后的东西。但是,您应该只在知道最终结果时调用 return ,因为 - 如您所说 - 它会退出该功能。

检测到碰撞后立即调用'return false'是正确的,因为如果玩家与至少一个方块发生碰撞,那么就会发生碰撞。相反,'return true'只有当你确定整个棋盘上根本没有碰撞时才应该调用,你需要测试地图上的每个方块才能确认这一点。

function collisioncheck(ind) {
    for (var i in map) {
        for (var j in map[i]) {
            if (yass == true) {
                if (map[i][j] == 0) {
                    if (ind == 0 && playerPosX == j * 32 + 32 && playerPosY > i * 32 - 32 && playerPosY < i * 32 + 32) {
                      return false;
                    } else if (ind == 1 && playerPosX == j * 32 - 32 && playerPosY > i * 32 - 32 && playerPosY < i * 32 + 32) {
                      return false;
                    } else if (ind == 2 && playerPosY == i * 32 + 32 && playerPosX > j * 32 - 32 && playerPosX < j * 32 + 32) {
                      return false;
                    } else if (ind == 3 && playerPosY == i * 32 - 32 && playerPosX > j * 32 - 32 && playerPosX < j * 32 + 32) {
                      return false;
                    } 
                    // else: do nothing. (i.e. let the loop run for the next block)
                }
            } else {
              return true;
            }
        }
    }
    return true;
}

我们在这里做的是遍历所有块,如果我们发现碰撞我们 return false 并退出函数。如果我们遍历所有块而没有发现任何碰撞,我们只会到达 'return true' 语句,这正是您想要的。