スポンサーリンク

【JavaScript】 神経衰弱の作り方を初学者向けに1行づつ解説![後編]【ゲーム】

javascript
勉強の為にJavaScriptで神経衰弱を作りたい!

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

※前半がまだの方は⇩をご覧ください
【JavaScript】 神経衰弱の作り方を初学者向けに1行づつ解説![前編]【ゲーム】

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

15パズルの作り方を理解することができる
「2つの要素を比較して、条件ごとの処理をさせる」が理解できるようになる

概要説明

まず、完成品を先に見ていただきましょう。

前半のコードとの主な違いをまとめておきます。

【変数】
let modosuTime = NaN; // 裏に戻すためのタイマー
let score = 0; // スコア
let itimaimeCard = null; // 1枚目に裏返したカード

【クリックイベント追加】
td.onclick = uragaesu; 

【削除すべきもの】
td.textContent = td.number;

今回のポイント

これに加えて、今回のメインになるのが function uaragaesu(e)です。

function uragaesu(e) {
 let clicked = e.target;
 if (modosuTime || clicked.textContent !== "") {
 return;
 }

let nowNumber = clicked.number;
clicked.className = "omote";
clicked.textContent = nowNumber;

 if (itimaimeCard == null) {
 itimaimeCard = clicked;
 return;
 }

if (itimaimeCard.number === nowNumber) {
  if (++score === 10) {
  clearInterval(timer);
  }
 itimaimeCard = null;
 clearTimeout(modosuTime);
} else {
  modosuTime = setTimeout(function () {
  itimaimeCard.textContent = "";
  itimaimeCard.className = "omote ura";
  clicked.textContent = "";
  clicked.className = "omote ura";
  modosuTime = NaN;
  itimaimeCard = null;
  }, 1000);
 }
}

30行ほどの関数で、長く感じる方もいるかと思います。
しかし、3つのポイントを押さえれば、理解を深めることができます。

処理を終わらせるべきかの判定
1枚目のカードを引いた時の処理
2枚目のカードを引いた時の処理

順に説明していきます。

処理を終わらせるべきかの判定

神経衰弱のルールを思い出していただくとこの部分はよく理解ができるかと思います。

let clicked = e.target;  
 if (modosuTime || clicked.textContent !== "") {
    return;
   }

まず、選択した要素をlet clicked = e.targetで変数clickedに代入します。
そして、以下どちらかの条件にあてはまる場合return関数の処理を止めます

modosuTime:2枚が表になってしばらく表示されている場合
clicked.textContent !== "":既に表になったカードがクリックされた場合

この判定をすることで、3枚目のカードを引いたり、表にしたカードをクリックしたら
裏に戻ってしまうなどの不備を防ぐことができます。

1枚目のカードを引いた時の処理

この部分は「1枚目のカードを引いた時」の処理です。

let nowNumber = clicked.number; 
clicked.className = "omote"; 
clicked.textContent = nowNumber;  

if (itimaimeCard == null) {
     itimaimeCard = clicked;  
  return;  
    }

clicked「今クリックしたカードであること」を意識するとこの後の理解が楽になります。

まず、nowNumberに今クリックした番号を代入します。
そしてclassNametextContentでカードが表になった時用のCSS、textContentを表示させます。

続いて、青文字の部分。

if (itimaimeCard == null){
     itimaimeCard = clicked;
return;
}

itimaimeCard (一枚目のカード)がnull、つまりこのクリックが2枚目かどうかを判定します。

1枚目であればitimaimeCard = clicked;「クリックして表になったカード情報を記憶」が適用されます。
2枚目であれば既にitimaimeCard = clicked;で1枚目の情報が保管されているはずです。つまり、if (itimaimeCard == null)には該当しないため、次の処理に進みます。

2枚目のカードを引いた時の処理

あと一息頑張りましょう!
まず、黒太文字if (itimaimeCard.number === nowNumber)に該当します。
itimaimeCard(1枚目)とnowNumber(2枚目)が同じ場合ならというif文です。
部分が「同じ場合」、部分が「違った場合」です。

if (itimaimeCard.number === nowNumber) {
   if (++score === 10) {
   clearInterval(timer);   
        }  
    itimaimeCard = null;  
    clearTimeout(modosuTime); 
    } else {
   modosuTime = setTimeout(function () {
   itimaimeCard.textContent = "";   
       itimaimeCard.className = "omote ura";
   clicked.textContent = "";
   clicked.className = "omote ura";
   modosuTime = NaN;
   itimaimeCard = null;   
     }, 1000);  
}

clearInterval(〇〇) とは?

clearInterval(timer);

clearInterval(〇〇)

これは「既に開始された〇〇のカウント停止する」という処理です。
timerはゲーム開始時点からカウントが始まっていました。

これをif (++score === 10)、10ペア分表になったら停止しなさいという意味です。

clearTimeout(〇〇) とは?

 clearTimeout(modosuTime)

clearTimeout(〇〇)

こちらも同じく「既に開始された〇〇のカウント停止する」という処理です。

c表にした2枚が異なる数だった場合

こちらで最後になります。
setTimeout使うと「何秒後に〇〇の処理をする」という予約をすることができます。

今回はの部分の内側が処理内容です。
itimaimeCardclickedmodosuTime の3つの変数を最初の状態に戻す処理です。

秒数を指定することで、めくって違った瞬間に裏に戻ってしまう不備を防ぐことができます。

setTimeout(function () {
   itimaimeCard.textContent = "";
   itimaimeCard.className = "omote ura";
   clicked.textContent = "";
   clicked.className = "omote ura";
   modosuTime = NaN;
   itimaimeCard = null;
}, 1000); 

まとめ

お疲れ様でした!!

神経衰弱、いかがだったでしょうか。

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

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

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