如何在返回值(Js)时不中断函数/循环

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

本文关键字:中断 函数 循环 返回值 Js      更新时间:2023-09-26

嘿,所以我正在制作一个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"]];

在屏幕上,它看起来像这个

你也可以在这里看到我的可移动角色。现在我已经走到了这一步,我希望我的角色与映射数组中值为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循环和函数。因此,我的角色不会与任何其他空白瓷砖碰撞,而是与第一块瓷砖碰撞。

我必须重写这个,但有什么聪明的解决方案吗?

此处链接到jsfiddle(字符不可见)

您正处于正确的轨道上,您的循环只运行一次迭代,因为您总是在迭代后返回一些内容。但是,您应该只在知道最终结果时调用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;
}

我们在这里要做的是遍历所有的块,如果我们发现冲突,我们会返回false并退出函数。只有当我们遍历了所有的块而没有发现任何碰撞时,我们才能达到"return true"语句,这正是你想要的。

您需要在第15行上的主if/else块的最后一个else中使用continue而不是return