We Blog Weblog

ズキュウウウウン

神経衰弱

Web

2024年4月25日

みなさんこんにちは。
ケミストのWeb担当みやのです。

今回は「神経衰弱ゲーム」の作成に挑戦してみました。スペードとハートのA~Kまで、全部で26枚です。

10枚バージョンはこちら

52枚バージョンはこちら

それではさっそく遊んでみてください。

00:00.00

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を使ってみました。

左下のボタンを押すと時よ止まれザ・ワールド!」「そして時は動き出す」ができます。

時間停止中は何枚でもめくることができて、時間停止を解除すると揃ったカードが同時に消える、とかできたらいいなあ(妄想)

だが...今...カードはディオに
全部一度に 同時にめくられた...!?
なぜ!?
なぜ1枚1枚ではなく...
少しの時間差もなく
1万分の1秒の差もなく
26枚のカードは
「同時」にめくられたのか?
なぜ...?

この記事を書いた人
みやの
Web・DTP担当

Contact Us

ご意見、ご相談、料金のお見積もりなど、お気軽にお問い合わせください。

お問い合わせはこちら

TOP