有嵌套循环的问题



当运行moveRight()函数时,我得到一个错误,它不识别地图[x][y],说这是未定义的。这只发生在"Player"处于最后一个y循环时。我不明白为什么会这样,有人能解释一下吗?

var map = [
    ["Blank", "Blank", "Blank", "Blank"],
    ["Blank", "Blank", "Blank", "Blank"],
    ["Blank", "Blank", "Blank", "Blank"],
    ["Blank", "Player", "Blank", "Blank"],
    ["Blank", "Blank", "Blank", "Blank"],
    ["Blank", "Blank", "Blank", "Blank"],
    ["Blank", "Blank", "Blank", "Blank"]
];
function moveRight() {
    var breakLoop = false;
    for (y = 0; y < map.length; y++) {
        for (x = 0; x < map[y].length; x++) {
            var posX = map[x][y].indexOf("Player");
            if (posX <= -1) continue;
            if (y >= map[y].length-1) {
                breakLoop = true;
                break;
            }
            breakLoop = true;
            console.log("x: " + x);
            console.log("y: " + y);
            map[x][y] = "Blank";
            map[x][y+1] = "Player"; 
            break;
        }
        if (breakLoop) break;
    }
}

您编写循环的方式是y在外循环,x在内循环,映射需要先由y访问,然后是x

var posX = map[y].indexOf("Player");

那么y的边界检查应该代替x,这是有意义的,因为这是一个水平移动。

if (x >= map[y].length - 1) {

移动线应为:

map[y][x] = "Blank";
map[y][x+1] = "Player"; 

另外,在你的局部变量声明中添加var是一个好主意,这样它们就不会泄漏到全局作用域。

for (var y = 0; y < map.length; y++) {
    for (var x = 0; x < map[y].length; x++) {

最后,看起来不需要内循环。您正在使用indexOf搜索每一行,因此不需要遍历行中的每个单独的正方形。这意味着posX可以变成x


应用所有这些想法,这是最终的代码。注意,通过一些仔细的重构,我们也去掉了breakLoop变量。

for (var y = 0; y < map.length; y++) {
    var x = map[y].indexOf("Player");
    if (x <= -1) {
        continue;
    }
    if (x < map[y].length - 1) {
        console.log("x: " + x);
        console.log("y: " + y);
        map[y][x]     = "Blank";
        map[y][x + 1] = "Player"; 
    }
    break;
}

循环的结构是y是第一个索引,x是第二个索引。在接下来的两行中,尽管您使用它们的顺序不对

map[x][y] = "Blank";
map[x][y+1] = "Player"; 

应该是

map[y][x] = "Blank";
map[y + 1][x] = "Player"; 

另外,y + 1索引是可疑的。在循环的最后一次迭代时,它将在数组的边界之外。您是想将循环条件更改为y + 1 < map.length吗?

最新更新