【javascript】神経衰弱(トランプゲーム)の作り方
カード情報のオブジェクトを作成し、テーブルに表示
オブジェクトを作成
javascript // 全てのカード情報を入れる配列を宣言
const cards = [];
// s : スペード, d : ダイヤ, h : ハート, c : クローバー
const suits = ["s", "d", "h", "c"];
// オブジェクトをつくる関数
function Card(suit, num) {
this.suit = suit;
this.num = num;
}
// カード情報を配列に格納
for (let i = 0; i < suits.length; i++) {
for (let j = 1; j <= 13; j++) {
let card = new Card(suits[i], j);
cards.push(card);
}
}
オブジェクトが生成されました。デベロッパーツールで確認してみてください。
テーブルに表示
HTML <!-- ここに生成されます -->
<table class="table" border="1"></table>
javascript
const table = document.querySelector(".table");
// テーブルに表示
for (let i = 0; i < suits.length; i++) {
const tr = document.createElement("tr");
table.appendChild(tr);
for (let j = 0; j < 13; j++) {
const td = document.createElement("td");
// 1行目 0 * 13 + j = 0 ~ 12
// 2行目 1 * 13 + j = 13 ~ 25
// 3行目 2 * 13 + j = 26 ~ 38
// 4行目 3 * 13 + j = 39 ~ 51
td.innerHTML = cards[i*13+j].suit + "
" + cards[i*13+j].num;
tr.appendChild(td)
}
}
以下のようになります。
スペードからクローバーまで、1~13が順番通り並びました。
カードをシャッフル
先ほどは1から順番に並んでいたので、それをシャッフルさせます。
配列の中身をシャッフルする方法は以下を参照してください。
// シャッフルする関数
function shuffle(arrays) {
const array = arrays.slice();
for (let i = array.length - 1; i >= 0; i--) {
const randomIndex = Math.floor(Math.random() * (i + 1));
[array[i], array[randomIndex]] = [array[randomIndex], array[i]];
}
return array;
}
// シャッフルし、HTML生成
function shuffleCard(){
const shuffled = shuffle(cards);
for (let i = 0; i < suits.length; i++) {
const tr = document.createElement("tr");
table2.appendChild(tr);
for (let j = 0; j < 13; j++) {
const td = document.createElement("td");
td.innerHTML = shuffled[i*13+j].suit + "
" + shuffled[i*13+j].num;
tr.appendChild(td);
}
}
}
shuffleCard();
トランプ(画像)に置き換える
先ほどは文字だけでしたが、以下はトランプ画像を表示させたいと思います。
画像を準備
以下のように、トランプの画像を準備。フォルダ(img)に保存し、HTMLファイルと同じ階層におきます。
カード情報の追加
カード情報に、画像のURLを追加します。
テーブルに表示するために、先ほどのコードの一部を書き換えます。
function Card(suit, num) {
// this.suit = suit;
// this.num = num;
this.front = `${this.suit}${('0'+this.num).slice(-2)}.gif`;
}
function shuffleCard() {
// const shuffled = shuffle(cards);
// for (let i = 0; i < suits.length; i++) {
// const tr = document.createElement("tr");
// table3.appendChild(tr);
// for (let j = 0; j < 13; j++) {
// const td = document.createElement("td");
td.style.backgroundImage = `url(img/${shuffled[i * 13 + j].front})`;
// tr.appendChild(td);
// }
// }
}
参考
以下のように表示できました。
さらに一行加えて、カードの裏面を表示させます。 また、カードをクリックしたときの関数(flip)も記述しておきましょう。
function shuffleCard() {
// const shuffled = shuffle(cards);
// for (let i = 0; i < suits.length; i++) {
// const tr = document.createElement("tr");
// table3.appendChild(tr);
// for (let j = 0; j < 13; j++) {
// const td = document.createElement("td");
td.classList.add("card", "back");
td.onclick = flip; // カードをクリックしたときの関数
// td.style.backgroundImage = `url(img/${shuffled[i * 13 + j].front})`;
// tr.appendChild(td);
// }
// }
}
CSSは以下の通り。
tdにクラス card back がついていたら、裏が表示され、そのクラスを除けば、 カードの表が表示されます。
td.card.back {
background-image: url(img/z01.gif) !important;
}
以下は、カードをクリックしたときの関数です。 とりあえず、クリックしたら、クラス削除で表になり、 1.3秒後にクラスが追加され、裏返ります。
function flipTest(e) {
let filipedCard = e.target;
filipedCard.classList.remove("back"); //カードを表にする。
flipTimerId = setTimeout(function () {
filipedCard.classList.add("back");
}, 1300);
}
クリックしてみてください。
正誤の処理
あとは正誤判定をし、二枚の数字があっていたら、カードを裏返さないようにします。 正誤処理のコードは思ったより長くはないです。
// 1枚目のカードの変数を宣言 最初はnull
let firstCard = null;
// setTimeoutを格納する変数
let flipTimerId = NaN;
// カードをめくった時の処理
function flip(e) {
let filipedCard = e.target;
// カードにクラスbackがついていないか、flipTimerIdが動作しているとき
if (!filipedCard.classList.contains("back") || flipTimerId) {
return; //表のカードをクリックしても何も反応させない。
}
filipedCard.classList.remove("back"); //backを取り除いて、カードを表にする。
// めくるのが1枚目の時
if (firstCard === null) {
firstCard = filipedCard; // めくったカードをfirstCardに設定
} else {
//2枚目だったら1枚目と比較して結果を判定する。
if (firstCard.num === filipedCard.num) {
//2枚が同じだった時、firstCardを初期値に戻す
firstCard = null;
} else {
// 2枚が違う数字だった時の処理
flipTimerId = setTimeout(function () {
// 2枚のカードを裏返す
firstCard.classList.add("back");
filipedCard.classList.add("back");
// 初期値に戻す
flipTimerId = NaN;
firstCard = null;
}, 1300); // 1.3秒後に処理を完了
}
}
}