繁体   English   中英

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

[英]By modifying arr[1][0] multiple cells are modified

我正在尝试制作三消游戏(喜欢糖果的人)。 我有一个对象level ,该对象level具有2d数组的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]被修改,而且多个单元也被修改。 有趣的是,每次随机细胞受到影响

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

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

等等

发生这种情况是因为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);
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM