2017-10-31 4 views
0

私はマッチ3のゲームをしようとしています。オブジェクトleveltilesの2d配列のプロパティを持っています。私はいくつかの操作が、私はこのシンプルなラインを使用して-1に特定の要素の種類を変更したいん(私はforを使用することがありますが、今のところ、私は実証の目的のために、それは簡単で行った)後arr [1] [0]を変更することで、複数のセルが変更されます

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]が変更されていない

が、複数のセルです。興味深いのは、ランダムなセルが影響を受けるたびに発生することです。

+0

これは、オブジェクトが参照を使用してコピーされているためです。ですから、あなたが 'var x = typeTiles [0]; var y = tileTypes [0] 'は、両方とも同じオブジェクトへの参照を保持します。 1つの変更は両方とも変更されます – Rajesh

+0

@Rajesh Typo:オブジェクトは**コピーされていません**リンクされています。 –

+0

@ÁlvaroGonzálezそれを指摘してくれてありがとう。 – Rajesh

答えて

1

getRandomTile()はタイルタイプではなく、そのコピーを参照を返すために発生します。

I.e.このケースを簡素化するために:

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

問題は、別のタイプにリンクするのではなくタイプオブジェクトを変更することです。解決策は、タイルを作成するときに、それを複製するようになります:

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

(あなたの目標に応じて)もう一つは、タイルオブジェクト、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; 
    } 
} 

など

0

これは、渡されたインデックスが同じである場合tileTypesで定義されたobjectの同じ参照を返すgetRandomTileによって引き起こされます。何が起こるかを理解するのに役立つようにtileTypesを印刷することができます。

関連する問題