年末まで毎日webサイトを作り続ける大学生 〜53日目 JavaScriptでタイピングゲームを作る〜

##はじめに
こんにちは！@70days_jsです。

英単語のタイピングゲームを作りました。
特に何も見ずに作ったので自分流の書き方になっています。
が、動作はちゃんと動きますのでぜひ遊んでみてください。

今日は53日目。(2019/12/10)
よろしくお願いします。

##サイトURL
https://sin2cos21.github.io/day53.html

##やったこと
英単語のタイピングゲームを作りました。↓
![test3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516248/585435ed-b5f8-eb96-3e1c-7f59d7356f49.gif)

こだわった部分
1. 問題は毎回ランダムに出題する
2. 正解した文字の色を薄くする


今回も昨日に引き続きほとんどJavaScriptでの実装です。

html（全文)↓

```html
  <body>
    <div id="allWrapper">
      <h1>タイピングゲーム</h1>
      <div id="wrapper"></div>
      <div id="enterChar">入力した文字: <span id="beforeEnter"></span></div>
    </div>
  </body>
```

JavaScript（全文）↓

```javascript
let dictionary = {
  "65": "A",
  "66": "B",
//省略...
  "90": "Z"
};
//タイピング練習問題の単語
let moji = [
  "animal",
  "cat",
//省略...好きな単語を入れていく
  "passion"
];
let array = [];
let count = 0; //現在の正解数
let flag = true; //ゲーム終了の判定
let charOpacity = 0; //どの文字を透明にするかの判定
let wrapper = document.getElementById("wrapper");
let beforeEnter = document.getElementById("beforeEnter");
document.addEventListener("keydown", logKey);

window.onload = function() {
  shuffle();
  console.log(moji);
  charCount();
};

//moji配列の変数を、配列に入れていく
function charCount() {
  for (var i = 0; moji[count].length > i; i++) {
    array.push(moji[count].charAt(i));
    let charspan = document.createElement("span");
    charspan.innerHTML = array[i];
    charspan.setAttribute("id", i);
    wrapper.appendChild(charspan);
  }
}

function logKey(e) {
  if (flag) {
    if (typeof dictionary[e.keyCode] === "string") {
      beforeEnter.innerHTML += dictionary[e.keyCode].toLowerCase() + " ";
    }
    // 単語の1文字目と入力文字が同じか判定する
    if (array[0].toUpperCase() == dictionary[e.keyCode]) {
      let getCharSpan = document.getElementById(charOpacity);
      getCharSpan.style.opacity = 0.5;
      charOpacity++;
      array.shift();
      if (array.length === 0) {
        wrapper.innerHTML = "";
        charOpacity = 0;
        if (count === moji.length - 1) {
          alert("終わり");
          flag = false;
        } else {
          count++;
          charCount();
        }
      }
    }
  }
}

function shuffle() {
  for (var i = moji.length - 1; i > 0; i--) {
    let random = Math.floor(Math.random() * (i + 1));
    let tmp = moji[i];
    moji[i] = moji[random];
    moji[random] = tmp;
  }
}
```

では説明していきます。

###1. 問題は毎回ランダムに出題する

問題はmoji配列にある単語群から出題しています。↓

>//タイピング練習問題の単語
let moji = [
  "animal",
  "cat",
//省略...好きな単語を入れていく
  "passion"
];

ランダムな出題は、このmoji配列内の順番をshuffle()関数でごちゃごちゃに入れ替えてやることで実現しています。↓

> function shuffle() {
  for (var i = moji.length - 1; i > 0; i--) {
    let random = Math.floor(Math.random() * (i + 1));
    let tmp = moji[i];
    moji[i] = moji[random];
    moji[random] = tmp;
  }
}

こうすることで、mojiの先頭から順に値を取り出してもランダムに見えるという仕組みです。


###2. 正解した文字の色を薄くする
ここが今回一番悩みました。
結局、moji配列に入っている一つ一つの変数を、一つずつ取り出して、その中身を一文字ずつ新たな配列に入れて、出題する際に一文字ずつspanで囲むということをしました。
spanのidに文字の位置を値として入れてやることで、それぞれ一文字ずつ一意なidをつけています。
その後、入力された文字が1文字目と同じなら、配列の1つ目（1文字目）を削ります。
その際、styleでopacityの値を低くすることで文字の色を薄くしています。↓

> //moji配列の変数を、配列に入れていく
function charCount() {
  for (var i = 0; moji[count].length > i; i++) {
    array.push(moji[count].charAt(i));
    let charspan = document.createElement("span");
    charspan.innerHTML = array[i];
    charspan.setAttribute("id", i);
    wrapper.appendChild(charspan);
  }
}

##感想
今日作ったゲームは、今まで作ったものの中で一番ちゃんと動いている感じなのでちょっと嬉しいです。
昨日の神経衰弱や、お絵かきアプリはちょっと予期せぬ動作があるとおかしな挙動になっていたので...。
ちなみに今日はJavaScriptがちょうど100行ぐらいでした。
単語やkeycodeの配列や連想配列が長くて、それを除くと50行ぐらいです。
その50行の中身も、要素をあれこれしている部分が大半なので、コア部分はせいぜい20~30行ぐらいだと思います。
なんというか、そんな短いコードでゲームが作れるというのが面白くてワクワクしてます。
やっぱりプログラミングはすごい！

最後まで読んでいただきありがとうございます。明日も投稿しますのでよろしくお願いします。