JavaScript: スライドパズルの作り方

バラバラに並んでいる数値を、順番に並ぶように入れ替えるスライドパズルを作ります。

数値のないパネルの上下左右をクリックするとパネルが移動します。 1~8、空白の順番に並べることが出来れば成功です。

動作サンプル、サンプルコード、コード解説の順番で記述しています。

動作サンプル

HTML


<div id="panel"></div>

CSS


#panel {
    width: 160px;
    height: 160px;
    overflow: hidden;
}

.tile {
    width: 50px;
    height: 50px;
    line-height: 50px;
    border: 1px solid silver;
    border-radius: 10px;
    text-align: center;
    font-size: 26px;
    font-weight: bold;
    box-shadow: gray 2px 2px;
    float: left;
    cursor: pointer;
}

JavaScript


// グローバル  div要素を格納
tiles = [];

window.onload = function() {
    
    var arr = ['', '1', '2', '3', '4', '5', '6', '7', '8'];
    // シャッフル
    shuffle(arr);

    var panel = document.getElementById('panel');
    
    // div要素作成
    for (i = 0; i < 9; i++){
        var div = document.createElement('div');
        div.className = 'tile';
        div.index = i;
        div.textContent = arr[i];
        div.onclick = click;
        panel.appendChild(div);
        tiles.push(div);
    }
} 

// シャッフル用関数
function shuffle(arr) {
    var n = arr.length;
    var temp, i;

    while (n) {
        i = Math.floor(Math.random() * n--);
        temp = arr[n];
        arr[n] = arr[i];
        arr[i] = temp;
    }
    return arr;
}

// タイルのtextContentを入れ替える
function swapContent(i, k){
    
    var temp = tiles[i].textContent;
    tiles[i].textContent = tiles[k].textContent;
    tiles[k].textContent = temp;
    
}

// クリック時の処理
function click(e) {
    
    var i = e.target.index;

    if (i <= 5 && tiles[i + 3].textContent == '' ){
        // 下と入れ替え
        swapContent(i, i + 3);
    }else if ( i >= 3 && tiles[i - 3].textContent == ''){
        // 上と入れ替え
        swapContent(i, i - 3);
    }else if (i % 3 !== 2 && tiles[i + 1].textContent == ''){
        // 右と入れ替え
        swapContent(i, i + 1);
    }else if (i % 3 !== 0 && tiles[i - 1].textContent == ''){
        // 左と入れ替え
        swapContent(i, i - 1);
    }
}

コード解説

div要素をfloat: leftで配置する


.tile {
    width: 50px;
    height: 50px;
    line-height: 50px;
    border: 1px solid silver;
    border-radius: 10px;
    text-align: center;
    font-size: 26px;
    font-weight: bold;
    box-shadow: gray 2px 2px;
    float: left;
    cursor: pointer;
}

9つのパネルをdiv要素で作成します。作成はJavaScript側で行います。 作成したdiv要素をfloat: leftとし、9つのパネルが3X3個に並ぶように配置。

パネル用 div要素を作成


var panel = document.getElementById('panel');

// div要素作成
for (i = 0; i < 9; i++){
    var div = document.createElement('div');
    div.className = 'tile';
    div.index = i;
    div.textContent = arr[i];
    div.onclick = click;
    panel.appendChild(div);
    tiles.push(div);
}

div要素を9つ作成し、appendChild()で追加します。

ポイントは最後のtiles.push(div)で配列tilesにdiv要素を追加している部分です。 この配列tilesを使って要素の内容やindexを取得します。

例えば、最初のパネルのindexは「tiles[0].index」で取得し、 textContentは「tiles[0].textContent」で取得します。

クリックされた時の処理


// クリック時の処理
function click(e) {
    
    var i = e.target.index;
    
    if (i <= 5 && tiles[i + 3].textContent == '' ){
        // 下と入れ替え
        swapContent(i, i + 3);
    }else if ( i >= 3 && tiles[i - 3].textContent == ''){
        // 上と入れ替え
        swapContent(i, i - 3);
    }else if (i % 3 !== 2 && tiles[i + 1].textContent == ''){
        // 右と入れ替え
        swapContent(i, i + 1);
    }else if (i % 3 !== 0 && tiles[i - 1].textContent == ''){
        // 左と入れ替え
        swapContent(i, i - 1);
    }
}

上下左右に移動できる場合を想定して、4つの場合分けになっています。 条件に一致する場合は、数値を入れ替えるswapContent()を実行します。

JavaScript入門