通过修改arr [1] [0],可以修改多个单元格

时间:2017-10-31 08:09:12

标签: javascript arrays

我试图进行一场3场比赛(像糖果一样)。我有一个对象level,它具有tiles属性,这是一个二维数组。在我做了一些操作之后,我想使用这个简单的行将特定元素的类型更改为-1(我将使用for,但是现在我已经使它变得简单了用于示范目的)

level.tiles[1][0].type = -1;

这是代码

var level = {
    x: 250,         // X position
    y: 113,         // Y position
    columns: 8,     // Number of tile columns
    rows: 8,        // Number of tile rows
    tilewidth: 40,  // Visual width of a tile
    tileheight: 40, // Visual height of a tile
    tiles: [],      // The two-dimensional tile array
    selectedtile: {selected: false, column: 0, row: 0}
};

var tileTypes = [
    {
        type: "red",
        colors: [255, 128, 128]
    },
    {
        type: "green",
        colors: [128, 255, 128]
    },
    {
        type: "darkBlue",
        colors: [128, 128, 255]
    },
    {
        type: "yellow",
        colors: [255, 255, 128]
    }
];
function createLevel() {
    for (var i = 0; i < level.columns; i++) {
        level.tiles[i] = [];
    }

    for (var i = 0; i < level.columns; i++) {
        for (var j = 0; j < level.rows; j++) {
            level.tiles[i][j] = getRandomTile();
        }
    }
}

function getRandomTile() {
    return tileTypes[Math.floor(Math.random() * tileTypes.length)];
}

createLevel();
level.tiles[1][0].type = -1;

不幸的是,不仅修改了tiles[1][0],还修改了多个单元格。有趣的是,每次随机细胞受到影响

3 个答案:

答案 0 :(得分:1)

问题是你修改了类型对象,而不是链接到另一种类型。解决方案是在创建切片时克隆它:

function getRandomTile() {
    var srcType = tileTypes[Math.floor(Math.random() * tileTypes.length)];
    return {type:srcType.type, colors:srcType.color};
}

另一个(取决于你的目标)是拥有Tile对象,每个对象都有一个Type对象的引用(不只是一个整数)。在这一点上,一些类可能会有所帮助:

class TileType {
   constructor(colors){
       this.colors = colors;
   }
}
let tileTypes = [...]

class Tile {
    constructor(){
        this.type = tileTypes[Math.random()*tileTypes.length|0];
    }
    setNewType(type){
        this.type = type;
    }
}

答案 1 :(得分:1)

这是因为getRandomTile()引用返回到磁贴类型,而不是它的副本。

即。为了简化这种情况:

var a = {x: 1};
var b = [a, a, a, a];
b[0].x = 2;
console.log(a, b);

将输出

{x: 2} [{x: 2}, {x: 2}, {x: 2}, {x: 2}]

如果你想让瓷砖可以修改,让getRandomTile返回一个副本 - 在这种情况下是浅拷贝,所以colors仍然是随机选择的瓷砖类型的参考,而不是副本

function getRandomTile() {
    const tileType = tileTypes[Math.floor(Math.random() * tileTypes.length)];
    // Idiom for shallow copy, i.e. assign all properties of tileType
    // into a new, unique object.
    return Object.assign({}, tileType);
}

答案 2 :(得分:0)

这是由getRandomTile引起的,如果传入的索引相同,则返回object中定义的tileTypes的相同引用。您可以打印tileTypes以帮助您了解会发生什么。