スポンサーリンク

【JavaScript】 15パズルの作り方を初学者向けに1行づつ解説![後半]【ゲーム】

javascript
勉強の為にJavaScriptで15スライドパズルを作りたい!

という方、初学者向けの解説記事です。

※前半がまだの方は⇩をご連絡ください。コピペするだけで15パズルを遊ぶことができます。

【JavaScript】 15パズルの作り方を初学者向けに1行づつ解説![前編]【ゲーム】

この記事を読んでできること

15パズルの作り方を理解することができる
「●●をクリックすると〇〇を発動させる」ができるようになる

概要説明

後半は3つのステップに分かれます。

・クリックイベントの設定
・カードを入れ替える関数 change(i,j) を自作する
・初期配置をランダムにする

順に説明していきます。

クリックイベントの設定

クリックしたら〇〇の処理をします

これをクリックイベントと呼び、大変便利な機能です。
折角なので簡単に設定する方法をここでは解説します。

ポイントをまとめてみました。

・クリックする要素に、onclickプロパティを使う
・onclickで設定した名前の関数を作る
・関数に処理したい内容を書く

まず、onclickプロパティについて見ていきましょう。完成図はこちら⇩

クリックイベントの設定

onclickプロパティ

itimai.onclick = moveCard;

●●.onclick=  “〇〇“;

これは「●●クリックした時関数〇〇を発動」という処理です。
itimai(カード1枚分)クリックした時関数moveCardを発動するという意味になります。

関数を作ろう!

function moveCard(e) {
   let i = e.target.index;
      ~~~~~~~~~~~~~~~
                                 }

moveCardが関数名。(e)が引数。e.targetと書くことで
イベント(=クリック)が発生した要素= let i とすることができます。

つまり、この「let i = e.target.index」は
「クリックした要素のindex番号を変数 iとする」という意味になります。

index以外にも「value」など色々な条件で引数を直感的にとることができます。
是非覚えてみてください。

上下左右に空白のカードがあるかチェックしよう!

長くてビックリしてしまうかもしれませんが、順番に理解すれば大丈夫です!

if (i - 4 >= 0 && cards[i - 4].value === 0) {
    change(i, i - 4);
  } else if (i + 4 < 16 && cards[i + 4].value === 0) {
    change(i, i + 4);
  } else if (i % 4 !== 0 && cards[i - 1].value === 0) {
    change(i, i - 1);
  } else if (i % 4 !== 3 && cards[i + 1].value === 0) {
    change(i, i + 1);
  }

色分けすると、4つの条件式からできていることが分かります。
上との入れ替え部分だけを抜き出して日本語訳してみましょう。

if (i - 4 >= 0 && cards[i - 4].value === 0) {
change(i, i - 4);
}

クリックしたindexが4以上で、そのindexから4引いた数字が0だったら
[クリックしたカード ⇔ 4引いたカード]を交換しなさい』

4引いた数字とはクリックしたカードの上にあるカード。
クリックしたindexが4以上か確認するのは一番上の列だった場合、
上にカードが存在しないからです。

これと同様の比較をにしています。

change(i , i-4)関数は下記で解説致します。

カードを入れ替える関数 change(i,j) を作ろう

ついにカードをクリックして、その数字を交換できるようになりました!
あと少し頑張りましょう!

function change(i, j) {
  let clickedCard = cards[i].value;
  cards[i].textContent = cards[j].textContent;
  cards[i].value = cards[j].value;
  cards[j].textContent = clickedCard;
  cards[j].value = clickedCard;
}

・let clickedCard = cards[i].value ⇒ クリックされたカードのvalueをclickedCardにする

・cards[i] ⇒ クリックされたカード
・cards[j] ⇒ 何も書かれてないカードまとめると上記のようになります。
valueとtextContentを入れ替えることで、数字が移動したような挙動を実現させました。

value = 表示されている数値/index = 通し番号

ここでのポイントを追記します。
・valueは実際に表示されている数字

・indexは通し番号(左上から0.1.2…)

「indexの数値を交換する」と設定してしまうと複雑になってしまいます。
valueを変数として設定し、そのvalueとtextContentを交換するよう設定すれば
管理もしやすく大変わかりやすいです。

初期配置をランダムにする

いよいよ最後です。
初期配置をランダムにして、ゲームとして遊べるようにしましょう。

for (let i = 0; i < 500; i++) {
  moveCard({ target: { index: Math.floor(Math.random() * 16) } });
}

これは「カードをランダムに500回クリックして」という処理です。

Math.floor(Math.random() * 16)だけ解説しますと

Math.floor(●●) ⇒ ●●の数字を整数値にしなさい
Math.random() * 16 ⇒ 0.1~1 のランダムな数字を発生させて16をかける

という命令です。
これでindexのランダムな数字に対してmoveCard関数を発動させることができます。

500回もすれば初期配置も混ざってくれるだろうと思います。

もちろん、1000回でも2000回でも変更可能ですし、その方がよりランダムになると思います。

完成図を今一度見てみましょう!

まとめ

お疲れ様でした!!

15パズル、いかがだったでしょうか。

難しく感じた方も多いと思いますが、できるだけ分かりやすく解説できていれば幸いです。

当サイトではCSSについても紹介しております。
お時間あればこちらもご参考下さい。

CSSが効かない時の対処法を解説