TypeScript（フルスクラッチ）で脳トレゲームを作ってみた。

# TypeScript（フルスクラッチ）で脳トレゲームを作ってみた。

![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87695/293790c3-97a7-2cf0-dc80-ffd7aaf7133f.gif)


約半年ほど前に、自分自身の学習を目的に作成したアプリです。
せっかく作成したので、少しでも人の目に触れて楽しんでいただき供養したいと思います。

## アプリ概要

- ５文字の数字が上部に表示されるので、下部に表示されるテンキーで入力します。
- ５文字の入力が終わる度に、テンキーの数値の順序が変更されます。
- ３０秒以内にどれだけ多く入力できるか競うゲームです。

### アプリの URL

https://brain-training-ac1bd.web.app/

※ 是非、遊んでみてください。

### Github リポジトリ

https://github.com/AkiUnleash/number_game

## 背景

### 開発者のスキル

私は 16 年間 VBA で事務効率化及び開発の仕事をしていましたが、Web アプリの開発に憧れ、独学で学び始めました。
随分昔に、Wordpress のテーマを個人開発で作成したことがあり、HTML 及び CSS の知識はある程度ありました。しかし、JavaScript の知識は皆無に等しい状態でのスタートです。

2020 年 12 月中旬〜2021 年 2 月中旬まで、以下のスキルを学び、このゲームアプリ開発に望みました。

- Webpack
- Javascript
- TypeScript
- React
- Firebase

#### 学習教材

https://www.udemy.com/course/webpack-crash-course/

https://www.udemy.com/course/javascript-essence/

https://www.udemy.com/course/understanding-typescript-jp/

https://www.udemy.com/course/react-application-development/

### 開発期間

- 作業時間 56h
- 作業期間 約２週間

## 技術

### 言語／ライブラリ

- TypeScript
- PUG
- SCSS
- Webpack
- Firebase(Hosting / Store)
- [nes.css](https://nostalgic-css.github.io/NES.css/)

### 設計

事前に設計はしませんでした。
頭の中にあるものを、そのままコーディングです。

※ 風呂の中でアプリのアイディアを思いつき、桶に湿気で画面設計をしましたが、お湯で流れてしまいました。

### ディレクトリ構成

以下が、ディレクトリ構成となっています。（一部省略しています。）

```
src/
├── app.ts                          エントリーポイント
├── assets                          装飾系
│   ├── font                         フォント
│   ├── images                       画像
│   ├── mp3                          音楽
│   └── scss                         Sass
├── components                      コンポーネント
│   ├── abstract-component.ts         抽象クラス
│   ├── button-credit.ts              ボタン｜クレジット
│   ├── button-mode.ts                ボタン｜モード切替
│   ├── button-number.ts              ボタン｜テンキー
│   ├── button-ranking.ts             ボタン｜ランキング異動
│   ├── button-sound.ts               ボタン｜音声オン／オフ
│   ├── button-start.ts               ボタン｜ゲームスタート
│   ├── button-top.ts                 ボタン｜トップ画面へ移動
│   ├── display-gamepoint.ts          ラベル｜プレイ画面右上のポイント
│   ├── display-gametimer.ts          ラベル｜プレイ画面上部のタイマー
│   ├── display-question.ts           ラベル｜プレイ画面中央部の入力する数値
│   ├── display-username.ts           ラベル｜プレイ画面左上のユーザー名
│   ├── screen-credit.ts              画面｜クレジット画面
│   ├── screen-gameover.ts            画面｜ゲーム終了時画面
│   ├── screen-gameplay.ts            画面｜プレイ中の画面
│   ├── screen-gamestart.ts           画面｜トップ画面
│   ├── screen-ranking.ts             画面｜ランキング画面
│   └── screen-standby.ts             画面｜プレイ前のカウントダウン画面
├── state                           状態管理
├── templates                       Index.html(Pug)
└── util                            その他、汎用的な関数
```

## 画面及び機能詳細

### トップ画面
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87695/46d25d01-8d51-13c7-7b61-069c6d31978b.png)

基本的な行動ができるよう、ボタンを並べています。
ボタンの内容は以下の通りです。

#### ボタン｜スタート
- ニックネームのバリデーション（未入力／文字数 確認）
- カウント画面への遷移

#### ボタン｜ランキング
- ランキング画面へ遷移

#### ボタン｜モード切り替え
- ノーマルモード／イージーモードの切り替え

#### ボタン｜クレジット
- クレジット画面の画面遷移

#### ボタン｜スピーカー
- 音声のオンオフの切り替え

##### ※イージーモードについて
  ３０秒間テンキーが固定された状態でプレイができます。
  クライアント（５歳の甥）から「ランキングに入れない！」と、泣きながらご要望をいただいた為、急遽増設しました。


### カウントダウン画面

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87695/99005d15-eb7f-9147-3ca1-30a04ddbeae3.png)

３秒間カウントダウンを行い、強制的に画面遷移を行います。

### ゲーム画面

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87695/5f5483b9-a893-dfdf-6ffd-ffabef8cbc0c.png)

- 問題やポイント、ニックネームなどは、[状態管理](https://github.com/AkiUnleash/number_game/blob/main/src/state/state.ts)にデータをもたせておき、処理をしています。
- ３０秒が経過したら、強制的に画面が遷移されます。

### ゲームオーバー画面

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87695/e8358f86-78b6-62f6-0bae-21744928de8c.png)

- [状態管理](https://github.com/AkiUnleash/number_game/blob/main/src/state/state.ts) からデータを読み出し、ポイントを表示しています。
- ランクは、FireStore Databaseにポイントを保存し、ランキングを算出しています。
- リスタートをすると、ニックネームのみ引き継ぎ、再開します。
- トップページに戻ると、すべての状態管理が初期状態に戻ります。（サウンドオンオフ以外）

### ランキング画面

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87695/13a5b472-01c8-9f05-c692-aa87c78213f2.png)


- FireStore Databaseから、上位１０レコードを取得し表示しています。

### クレジット画面

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87695/c279f841-a474-ec0b-9885-0dc99b74d480.png)

- 使用させていただいた音源等の情報を記載しています。


## 開発して良かったと思えた点

React.js、Vue.js、 更には進化した Next.js や Nuxt.js では、Dom を操作する必要はおろか、Webpack の調整もあまり必要ではありません。便利な機能やサービスがあふれる昨今、学習方法も２段３段はおろか、自分が気がついて無い間に１００段ほど飛ばして進んでいく世の中です。フルスクラッチでこのようなアプリを作成するのは、正気無駄な手間でしかないと思います。

しかし、「どのように動いているのか？」という内部の動きはこのアプリ開発を通して少し理解できました。一つ一つ段階を踏みながら理解することで、見えてくるものもあるのだなと感じています。

この記事が誰かの参考になれば幸いです。