Reactで神経衰弱アプリを作ってみた（フロントエンド編）

Reactを使って神経衰弱アプリを作ろう！ 全6回のうち、今回はフロントエンド構築編です！

　・[決起編](https://qiita.com/ntc-suzuki/items/713ee53825e833ab2a19)
　・[フロント環境構築編](https://qiita.com/ntc-arai/items/06344ef8522205c9936d)
　・フロントエンド構築編　★本記事
　・[コンポーネント作成編](https://qiita.com/ntc-arai/items/d2a1bb152b5a0859ac9e)
　・[バックエンド編](https://qiita.com/ntc-suzuki/items/34eb7ff436326b2c88b7)
　・[リファクタリング編](https://qiita.com/ntc-saito/items/6af683fd7ee936c23ac2)

前回の記事は上記リンクよりご覧いただけます。シリーズ通して読んでいただけたら嬉しいです。 


今回は神経衰弱アプリのフロントエンドの構築ということで、
デザイン面で工夫した点も交えて記事を書いていきたいと思います。


## 画面の簡単なワイヤーフレームを作成する。
神経衰弱のゲームを作成するということで、画面は最低限以下の2画面が必要になります。
まずはミニマムスタートで、この2画面についてワイヤーフレームを作成していきたいと思います。

・ゲームのTOP画面
・ゲームのプレイ画面

といっても、いきなりワイヤーフレーム作成は始められないのでツール検討から始めていきます。
今回のツール選定の基準・条件は以下と設定しました。

**■今回の条件**
　・無料で使用できる
　・すぐに利用開始できる
　・複数人が同時に参照できる
 
ワイヤーフレームのツールを検索すると幾つか候補が出てきますが、
今回はその中でもすべての条件に合致する「Figma」を選びました！(皆さんご存じの人気ツールです)

#### Figmaについて少し解説
Figmaは操作が簡単であることと、誰でも無料で使用することが出来る点で今一番と言っていいほど人気のツールです。

神経衰弱ゲームについてはPC版のみを作成しますが、Figmaではスマホ版など様々なデバイスに対応したデザインカンプを作成することが出来ます。
様々なサイズのデザインカンプを作成しておくことで、レスポンシブデザインに対応したアプリの画面設計も可能となります。

また、Figmaには様々なプラグインが存在しておりアイコンの追加や日本語フォントの追加なども簡単に行えます。
皆さんも是非触ってみて下さい。結構面白いです。


少し話がそれましたが…Figmaには様々な機能がありますが今回はミニマム実装ということもあり、
なるべくシンプルなデザインでワイヤーフレームを作成してみました。(少しシンプルにしすぎたかもしれません)


## 完成したワイヤーフレームはこちら
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881599/d69054c4-db20-7747-0af6-ea60f76d850c.png" width=70% >
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881599/35ec5615-0c27-6fa8-b5c9-991635bb8c48.png" width=70% >

「神経衰弱」ということで、頭脳/記憶といったキーワードから連想される色の「青」をキーカラーにしてみました。
また、先頭のMの部分には記憶＝「巡る・循環・さかのぼる」のイメージで、円のオブジェクトを入れてみました。
(実装に入れるかは別ですが、チーム内でのコンセプトやイメージ共有のため)

Game画面については、最終的にはコンピューターと対戦ができるようにしたいと考えているので各プレイヤーの点数が表示されるようにしてみました。
今回の実装ではまずは個人プレイまでをスコープとしていますが、志は高く…


## フロントエンドを実装する
**①TOP画面を作る**
　後半にリファクタリング編も待ち構えていますので、あえてざっくり実装してみました。
　「\<Link to="/game"\>」で指定しているのは、別ファイルで作成したgame画面のパスです。

　TOP画面はシンプルなので難しい実装などは特にありませんが、使用したReactの代表的なMUIライブラリについてご紹介します。

・Button：　画面上にボタンを生成するためのMUIです。ボタンのデザイン(輪郭付き/背景色付き等)も指定することが出来ます。
・Stack：　要素を縦や横に整列させるためのMUIです。今回は細かい感覚調整は入れていませんが、今後調整できるようこちらを使用しています。
```js
const Top = () => {
  return (
    <div>
      <div
        style={{
          display: "flex",
          justifyContent: "center",
          marginTop: "200px",
        }}
      >
        <Typography sx={{ fontSize: "4rem", color: "#65BBE9" }}>M</Typography>
        <Typography sx={{ fontSize: "4rem" }}>emory</Typography>
        <Typography sx={{ fontSize: "4rem", color: "#65BBE9" }}>T</Typography>
        <Typography sx={{ fontSize: "4rem" }}>racer</Typography>
      </div>
      <div
        style={{
          display: "flex",
          justifyContent: "center",
        }}
      >
        <Typography sx={{ fontSize: "2rem", fontWeight: "bold" }}>
          神経衰弱
        </Typography>
      </div>
      <div
        style={{
          display: "flex",
          justifyContent: "center",
          marginTop: "150px",
        }}
      >
        <Stack>
          <Link to="/game">
            {" "}
            <Button
              variant="outlined"
              sx={{ width: "200px", fontSize: "19px" }}
            >
              Game Start
            </Button>
          </Link>
        </Stack>
      </div>
    </div>
  );
};
```



***②Game画面を作る***
Game画面では、実際に画面上にカードを並べる見た目の部分の実装をしました。
カードの生成ロジックや、めくったカードを判定するゲームの中核となるロジックについては、「バックエンド編」でご紹介していますのでぜひそちらもご覧ください！

まずはカードを８枚×３行で表示する部分を作成します。
カードの生成関数で作成したランダムなカードを順番に並べていき、
「onClick={handleCardClick}」でイベントハンドラーを設定しカードがクリックされた場合にめくったカードを判定する関数が起動するようにしておきます。

```js
   // カードを並べるためのレイアウトを設定
  const rows = [];
  for (let i = 0; i < 3; i++) {
    rows.push(
      <div key={i} style={{ display: "flex", justifyContent: "center" }}>
        {cards.slice(i * 8, (i + 1) * 8).map((card) => (
          <Card
            key={card.id}
            id={card.id}
            value={card.value}
            // 以下評価結果がtrueだと裏になる。
            isFlipped={
              flippedCards.includes(card.id) || matchedCards.includes(card.id)
            }
            onClick={handleCardClick}
          />
        ))}
      </div>
    );
  }
```
return以降に実際に画面に出力される部分を記載していきます。
先ほど作成したカードを並べた「rows」もこちらに記述することで画面上に表示させることができます。
また、Game画面では「<Link to="/">」の部分で「Home」ボタンからTOP画面に戻れるようにしています。

```js

  return (
    <div
      style={{
        marginTop: "50px",
      }}
    >
      {rows}
      <div
        style={{
          marginTop: "50px",
          display: "flex",
          justifyContent: "center",
        }}
      >
        <Link to="/">
          {" "}
          <Button variant="outlined" sx={{ justifyContent: "center" }}>
            HOMEへ戻る
          </Button>
        </Link>
      </div>
    </div>
  );
};
```

## 実際に完成した画面がこちら
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881599/d374d566-7f6b-7be9-a0ab-89f6c0a34821.png" width=70% >
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881599/4739c819-a72b-e420-1560-83751bad2fbf.png" width=70% >


ほぼほぼFigmaで設計した通りに実装ができました！

コンピューターとの対戦は今回実装から外しましたが、ゆくゆくはアプリをブラッシュアップし追加していきたいと思います！
Figmaを使ったワイヤーフレーム/デザインカンプの作成や、それを基にした画面実装に挑戦予定の方の参考になれば幸いです。

 

次回、「コンポーネント作成編」の記事も[こちら](https://qiita.com/ntc-arai/items/d2a1bb152b5a0859ac9e)からぜひご覧ください。