という方、初学者向けの解説記事です。
ちなみに完成品はこちら⇩
この記事を読んでできること
・神経衰弱の作り方を理解することができる
対象読者様
②コードの意味や作り方を理解したい方
上記のような読者様を想定しております。
当記事では javascriptで初めて何かを作りたい方 を想定している為
前半(カードを表示させる)・後半(カードをめくって判定する)の2つに分けて解説をしていきます。
前半は下記のようにカードを表示させる(+経過時間をカウントする)ところまで解説していきます。
前半_概要説明
前半のポイントは3つです。
②kousin関数(経過時間を取得して表示する)
③shuffle関数(シャッフル関数を作成する)
①は当サイトで解説している15パズルで解説した内容とほぼ同じ
②は実質7行ほどで③にいたってはコピペです。特別な知識は必要なく、変数やプロパティの基本が分かれば楽しく作ることができます。順に見ていきましょう。
解説①html/CSSを準備しよう
まずはhtmlで次の2つを準備します。
・<table id=”field”>を入れる
・<h2><span id=”time”>0</span>秒経過</h2>を入れる
それぞれの役割はこちら⇩
■<script src=”main.js”>
⇒「scriptにsrc(ソース)としてmain.jsってファイルを読み込みます」
■<table id=”field”>
⇒このtableタグの子要素にタグ(tr.td)を追加していきます
■<h2><span id=”time”>0</span>秒経過</h2>
⇒このspanタグの中の数字が経過時間に従って変化していきます
CSSについては基本的なものばかりなので、省略いたします。
上記で説明したポイントの箇所だけ太文字にしています。
<html lang="ja">
<head>
<title>神経衰弱</title>
</head>
<script src="main.js"></script>
<body>
<style>
.omote {
width: 100px;
height: 140px;
border: 1px solid red;
border-radius: 5px;
text-align: center;
font-size: 36px;
box-shadow: rgb(100, 100, 100) 2px 2px;
}
.ura {
background-color: black;
border: 0px solid black;
}
</style>
<table id="field"></table>
<h2><span id="time">0</span>秒経過</h2>
</body>
</html>
解説② init() 関数を作ろう
いよいよjavascriptです。
3つある関数の内、一番長い関数がこのinit関数です。
まずは、関数の全体図を見てみましょう。
// 変数
let timer = NaN;
let start = null;
// 初期化
function init() {
let table = document.getElementById("field");
let cards = []; // 配列を格納
for (let a = 1; a <= 10; a++) {
cards.push(a);
cards.push(a);
}
cards.shuffle(); // カードをシャッフル
for (let i = 0; i < 4; i++) {
let itiretu = document.createElement("tr");
for (let j = 0; j < 5; j++) {
let itimai = document.createElement("td");
itimai.className = "omote";
itimai.number = cards[i * 5 + j];
itiretu.appendChild(itimai);
itimai.textContent = itimai.number;
}
table.appendChild(itiretu);
}
start = new Date(); // ゲーム開始時刻を保存
timer = setInterval(kousin, 1000); // 1秒ごとに「kousin」を発動する
}
赤:②-1 配列に数字を格納しよう!
青:②-2 tr.tdタグを追加しよう!
緑:②-3「時間」についての変数を設定しよう!
に分けて必要な知識を解説していきます。
解説②-1 配列に数字を格納しよう!
let cards = []; // 配列を格納
for (let a = 1; a <= 10; a++) {
cards.push(a);
cards.push(a);
}
cards.shuffle(); // カードをシャッフル
※shuffle()
は後述しますが、「配列内の数字をシャッフルしなさい」という関数です
cards.push(a);
」が2つ並んでいるのは神経衰弱の都合上、同じ数字が2セット必要だからです。つまり
という処理になります。
解説②-2 tr.tdタグを追加しよう!
続いて、table > tr > td となるように必要なタグを子要素として追加しましょう。
for文/className/textContent/appendChild を使えばコンパクトにまとめることができます。
それぞれの役割や使い方は⇩の「解説②-1 for文を使おう!」にて解説しておりますので、もし不安のある方はどうぞ
【JavaScript】 15パズルの作り方を初学者向けに1行づつ解説!
解説②-3 「時間」についての変数を設定しよう!
start = new Date(); // ゲーム開始時刻を保存
timer = setInterval(kousin, 1000); // 1秒ごとに「kousin」を発動する
まず、new Date()
について解説します。
これは現在時刻を取得するメソッドで、変数start
に代入されています。
どのような数字が入るかconsole.log見てみると…
上記のように、現在時刻を取得することができます。
続いて、setInterval()を解説します。
forは内側の処理が全て終わった後に外側の処理します。覚えておきましょう。
timer = setInterval(kousin, 1000)
〇〇 = setInterval(●●, ■■■■)
これは「〇〇にsetIntervalを代入し、■■■■秒ごとにを●●を実行しなさい」
という命令です。●●は関数、■■■■は1000 = 1秒換算になります。
まとめますと
「timerにsetIntervalを代入し、1秒ごとにをkousinを実行しなさい」
という処理になります。
このkousinはこの後解説する関数のことです。
解説③経過時間を取得して表示しよう!
続いて関数:kousin()についての解説です。
// 時間経過を計測
function kousin() {
let now = new Date();
let keika = Math.floor((now.getTime() - start.getTime()) / 1000);
document.getElementById("time").textContent = keika; // 経過時刻を表示
}
以下が処理の流れです。
・現在時刻をnow
に格納する
・「現在時刻(最新の時刻)」ー「現在時刻(関数が初めて処理された時刻)」を計算
・計算した経過時間をkeika
に格納
・html > time にテキストとして表示させる
補足
一番長い、経過時間を計算する箇所のみ抜粋して補足しますと…
let keika = Math.floor((now.getTime() - start.getTime()) / 1000);
Math.floor()
は小数点を切り捨てて、整数に表示させることができる
now.getTime()
は最新の現在時刻を知ることができる
()/ 1000
で割り算をすることで単位を秒にあわせることができる
このようになります。
このkousin() 関数が1秒ごとに発動することによってゲーム開始時からの経過をカウントすることができるのです。
最期にshuffle()関数を見てみましょう。
解説④ shuffle()関数をコピペしよう
// 配列シャッフル
Array.prototype.shuffle = function () {
let i = this.length;
while (i) {
let j = Math.floor(Math.random() * i);
let t = this[--i];
this[i] = this[j];
this[j] = t;
}
return this;
};
この関数ですが、結論から言いますとコピペしましょう。
コピペをおすすめするのは、これは「フィッシャーイエーツ関数」という名前がついているからです。
ということで、何も考えずコピペしてしまいましょう。これで、1-10の数字2セットを配列に格納した上で、シャッフルすることができます。
もし詳しくアルゴリズムを知りたい方はこちらのサイト様が分かりやすく解説されています。
まとめ
ここまでで前半終了です!
お疲れさまでした!
後半は カードを選択して同じ数字かどうか判定する 処理を実装していきます。
難しく感じる方も多いと思いますが、できるだけ分かりやすく解説できればと思います。