神経衰弱
2024年4月25日

みなさんこんにちは。
ケミストのWeb担当みやのです。
今回は「神経衰弱ゲーム」の作成に挑戦してみました。スペードとハートのA~Kまで、全部で26枚です。
それではさっそく遊んでみてください。
HTML
参考:Kusakar ISM|自作してから遊ぶ「神経衰弱ゲーム」~JavaScriptでプログラミング~
参考:たけちゃんねる プログラミング|【JavaScriptで神経衰弱】この一本でプログラミングができる気分になる動画の次に見て理解を深める動画。
この方はぶっつけ本番で2時間でこの神経衰弱を完成されていました。すごい。
<div id="stop_watch">00:00.00</div>
<div id="field"></div>
時間経過を表示する部分と、カードを表示する部分を用意します。
CSS
.cards {
width: 16.6%;
height: auto;
border: 1px solid #eee;
float: left;
border-radius: 7px;
text-align: center;
font-size: 25px;
font-weight: bold;
aspect-ratio: 57 / 89;
display: flex;
justify-content: center;
align-items: center;
transform: rotateY(0);
transition: all 0.6s;
backface-visibility: hidden;
background-color: rgba(238, 238, 238, 0.1);
cursor: pointer;
}
#field {
width: 100%;
height: auto;
aspect-ratio: 342 / 445;
}
@media(min-width:1200px) {
.cards {
width: 14.28%;
}
#field {
aspect-ratio: 399 / 356;
}
}
.back {
background-image: url("img/card2.svg");
background-size: cover;
transform: rotateY(180deg);
transition: all 0.6s;
backface-visibility: visible;
cursor: pointer;
}
.comp {
opacity: 0;
}
参考元から変えたところは、
・クラス名がcardだとBootstrapのcardと被るのでcardsとした
・カードを横に6枚(PC時は7枚)並べたかったので横幅を16.6%(画面幅1200以上だと14.28%)にした
・トランプは横57mm、縦89mm(ブリッジサイズ)らしいのでaspect-ratio:57/89とした
・くるりんとめくった感を出したかったので、トランプの裏面の画像を表裏逆に作ってrotateY(180deg)→backクラス削除でrotateY(0)としてみたのですが思ったような挙動にならなかったです
JS
const STOP_WATCH = document.getElementById('stop_watch');
let timer, setTimer;
let tryCount = 0;
let firstClick = true;
let firstCard;
let compUnit = 0;
let minutes = 0;
let seconds = 0;
let centiseconds = 0;
let stopWatch = () => {
centiseconds++;
if (centiseconds % 100 === 0) {
seconds++;
centiseconds = 0;
}
if (seconds % 60 === 0 && seconds != 00) {
minutes++;
seconds = 0;
}
STOP_WATCH.innerHTML = ('00' + minutes).slice(-2) + ':' + ('00' + seconds).slice(-2) + '.' + ('00' + centiseconds).slice(-2);
}
let interval;
window.onload = firstScript();
function firstScript(){
let beforeArray = [];
let afterArray = [];
for(let i=0; i<13; i++){
let sub = ["A","2","3","4","5","6","7","8","9","10","J","Q","K"];
beforeArray.push("♠"+sub[i]);
beforeArray.push("<span style='color:red'>♥</span>"+sub[i]);
}
for(let i=0; i<26; i++){
let r = Math.floor(Math.random()*beforeArray.length);
afterArray.push(beforeArray[r]);
beforeArray.splice(r, 1);
}
let field = document.getElementById("field");
for(let i=0; i<26; i++){
let div = document.createElement("div");
div.className = "cards back";
div.cardFace = afterArray[i];
div.innerHTML = "";
div.onclick = turn;
field.appendChild(div);
}
}
let startTime = document.getElementById('field');
function countStart(){
clearInterval(interval);
interval = setInterval(stopWatch, 10);
startTime.removeEventListener('click', countStart, false);
}
startTime.addEventListener('click', countStart, false);
function turn(e){
if(setTimer){return;}
let choiceCard = e.target;
if(choiceCard.innerHTML==""){
choiceCard.className = "cards";
choiceCard.innerHTML = choiceCard.cardFace;
}else{return;}
if(firstClick==true){
firstCard = choiceCard;
firstClick = false;
}else{
tryCount++;
if(firstCard.cardFace.substr(-1)==choiceCard.cardFace.substr(-1)){
compUnit++;
setTimer = setTimeout(function(){
choiceCard.className = "cards comp";
firstCard.className = "cards comp";
if(compUnit==1) confetti();
if(compUnit==2) confetti();
if(compUnit==3) confetti();
if(compUnit==4) confetti();
if(compUnit==5) confetti();
if(compUnit==6) confetti();
if(compUnit==7) confetti();
if(compUnit==8) confetti();
if(compUnit==9) confetti();
if(compUnit==10) confetti();
if(compUnit==11) confetti();
if(compUnit==12) confetti();
if(compUnit==13) confetti();
if(compUnit==13) fireworks();
if(compUnit==13) clearInterval(interval);
setTimer = null;
}, 500);
}else{
setTimer = setTimeout(function(){
choiceCard.className = "cards back";
firstCard.className = "cards back";
choiceCard.innerHTML = "";
firstCard.innerHTML = "";
setTimer = null;
}, 500)
}
firstClick = true;
}
}
動画を見ながら、なんとか途中までは理解できたのですが、setTimeoutのあたりからだんだんわからなくなってきました。
ストップウォッチを自作して、1枚目をめくったらカウントがスタートする感じにしてみましたが独学なので合ってるかどうかはわかりません
13組揃う(全てのカードが消える)と、カウントが停止します。
Canvas Confettiを使って、紙吹雪が舞うようにしてみました。
おまけ

このページはダークモードの切り替えにDarkmode.jsを使ってみました。
左下のボタンを押すと「時よ止まれ!」「そして時は動き出す」ができます。
時間停止→5秒後に時間停止解除、とかできたらいいなあ(妄想)時が止まっているのに5秒と考えるのはおかしいがとにかく5秒ほどだ......フフ
だが...今...カードはディオに
全部一度に 同時にめくられた...!?
なぜ!?
なぜ1枚1枚ではなく...
少しの時間差もなく
1万分の1秒の差もなく
26枚のカードは
「同時」にめくられたのか?
なぜ...?