JavaScript: 神経衰弱ゲームの作り方
トランプゲームの定番ゲーム、「神経衰弱」をつくります。
カードを2枚めくり、違う数値ならやり直し、同じ数値ならそのカード2枚が消えます。 全てのカードがなくなると、下に表示されている経過秒数がストップします。
動作サンプル、サンプルコード、コード解説の順番で記述しています。
動作サンプル
HTML
<div id="panel"></div>
<div id="result">経過秒数: </div>
CSS
#panel {
width: 310px;
height: 340px;
overflow: hidden;
}
.card {
width: 60px;
height: 80px;
line-height: 80px;
border: 1px solid silver;
border-radius: 10px;
text-align: center;
font-size: 26px;
font-weight: bold;
box-shadow: gray 2px 2px;
background: white;
float: left;
cursor: pointer;
}
/* 裏の状態 */
.back {
background-image: url('img/back.png');
background-size: 60px 80px;
}
/* 終了時 */
.finish {
opacity: 0;
cursor: default;
}
/* 経過秒数 */
#result {
font-size: 1.2em;
font-weight: bold;
}
JavaScript
// グローバル
// div要素を格納
var cards = [];
// 開始時間
var startTime;
// 経過秒数用 タイマーID
var timer;
// カードめくり用 タイマーID
var backTimer;
// 1枚目かどうかのフラグ 1枚目: true 2枚目: false
var flgFirst = true;
// 1枚目のカードを格納
var cardFirst;
// そろえた枚数
var countUnit = 0;
window.onload = function(){
// 数字格納 一時配列
var arr = [];
for (var i = 0; i < 10; i++){
// ペアの数字を10組
arr.push(i);
arr.push(i);
}
// シャッフル
shuffle(arr);
var panel = document.getElementById('panel');
// div要素作成
for (i = 0; i < 20; i++){
var div = document.createElement('div');
div.className = 'card back';
div.index = i;
div.number = arr[i];
div.innerHTML = '';
div.onclick = turn;
panel.appendChild(div);
cards.push(div);
}
// 開始時刻を取得
startTime = new Date();
// タイマー開始
startTimer();
}
// シャッフル用関数
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;
}
// クリック時の処理
function turn(e){
var div = e.target;
// カードのタイマー処理が動作中は return
if (backTimer) return;
// 裏向きのカードをクリックした場合は数字を表示する
if (div.innerHTML == ''){
div.className = 'card';
div.innerHTML = div.number;
}else{
// 数字が表示されているカードは return
return;
}
// 1枚目の処理
if (flgFirst){
// cardFirst は2枚目の処理のときに使う
cardFirst = div;
// フラグ変更
flgFirst = false;
// 2枚目の処理
}else{
// 数字が1枚目と一致する場合
if (cardFirst.number == div.number){
countUnit++;
// 見えない状態にする
backTimer = setTimeout(function(){
div.className = 'card finish';
cardFirst.className = 'card finish';
backTimer = NaN;
if (countUnit == 10){
clearInterval(timer); // timer終了
}
}, 500)
// 一致しない場合
}else{
// カードを裏側に戻す
backTimer = setTimeout(function(){
div.className = 'card back';
div.innerHTML = '';
cardFirst.className = 'card back';
cardFirst.innerHTML = '';
cardFirst = null;
backTimer = NaN;
}, 500);
}
flgFirst = true;
}
}
// タイマー開始
function startTimer(){
timer = setInterval(showSecond, 1000);
}
// 秒数表示
function showSecond(){
var nowTime = new Date();
var elapsedTime = Math.floor((nowTime - startTime) / 1000);
var str = '経過秒数: ' + elapsedTime + '秒';
var re = document.getElementById('result');
re.innerHTML = str;
}
コード解説
カードの並べ方
カードの並べ方は、div要素を20個作成し、それをfloat: leftで並べています。 tableタグは使っていませんが、tebleタグで配置をコントロールしてもいいと思います。
#panel {
overflow: hidden;
}
.card {
float: left;
}
カードの状態は3種類
カードの状態は3種類あり、それぞれクラスを設定します。
裏向きの状態 | class="card back" |
数字が表示されている状態 | class="card" |
数字がそろって非表示の状態 | class="card finish" |
.card {
}
/* 裏の状態 */
.back {
}
/* 終了時 */
.finish {
}
JavaScriptの処理は大きく分けて6つ
JavaScriptのコードは大きく分けて次の6つになります。
一番重要な部分はクリック時の処理 turn()です。
グローバル変数設定 | |
初期設定 | window.onload |
配列シャッフル | shuffle() |
クリック時の処理 | turn() |
タイマー開始 | startTimer() |
経過秒数表示 | showSecond() |
turn()のif文構造
turn()のif文の構造だけを抜き出したものです。
めくられたカードが1枚目か2枚目かで処理がわかれ、 さらに2枚目の場合は、数字が1枚目と一致するかどうかに処理がわかれます。
この条件分岐がこのプログラムの重要な骨組みとなります。
// 1枚目の処理
if (flgFirst){
// 2枚目の処理
}else{
// 数字が1枚目と一致する場合
if (cardFirst.number == div.number){
// 一致しない場合
}else{
}
}