DenoとFreshではじめてのWebアプリ個人開発(みんなであそべるすごろくメーカー)

# みんなであそべるすごろくメーカー🎲

「みんなであそべるすごろくメーカー」というWebアプリを作ったのでよろしければ遊んでみてください！

https://everyone-sugoroku-maker.deno.dev

## 経緯📅
2024年8月後半に「せっかく長期休みだし新しい技術を使って何かWebアプリを作ってみたい！」と思ったことが発端です。
 
 現在も新機能などの開発が継続中なのでこの記事に追記予定です。

https://github.com/poeMoon0416

## コンセプト🫧
**「すごろくを書いたノートの周りに集まって、みんなでサイコロを振って遊んだ経験はありませんか？このアプリはそんな体験をWeb上で手軽に再現できます！」**

何を作ろうか考えていたところ、ふと昔ノートにすごろくを書いて遊んだのが割と楽しかったなということを思い出しました。

そこで、すごろくを遊べるWebアプリはあってもすごろくを作って遊ぶWebアプリは見かけなかったのでこのコンセプトに決定しました。

## 機能⚙️

機能は色々と考えましたが、ひとまず最低限の「つくってあそぶ」という部分をコア機能として完成させ、公開してから機能追加していくという方針を立てました。

#### コア機能

- 「つくる」🔧
ノーマル、スタート、ゴール、1すすむ、もう1回といったマスをツールバーから選び、ボードをクリックしてマスを配置する。
　
- 「あそぶ」🎲
プレイ人数を1～4人の中から選ぶ。
各プレイヤーがサイコロを振ると出た目の数と止まったマスの効果に応じてプレイヤーのコマが進む。
だれか1人がゴールしたらランキングを表示する。

#### 追加機能

- 「あそびかた」📚
テストプレイの結果、いきなりすごろくのボードが出てきても遊び方が分からないから、遊び方のページが欲しいという意見が出たので優先的に実装しました。

:::note info
随時追加予定
:::

## デザイン🎨
**サイコロっぽいイメージ**

- プライマリ: 水色っぽい白 (slate-100) `#f1f5f9`

- セカンダリ: 紺色っぽい黒 (slate-900) `#0f172a`

- アクセント: 1の目っぽい赤 (red-600) `#dc2626`

## 技術選定🛸

| 技術スタック        | 名前           |
|:------------------:|:--------------:|
| 開発言語            | TypeScript     |
| Webフレームワーク   | Fresh          |
| Webライブラリ       | Preact        |
| ランタイム          | Deno          |
| クラウドホスティング | Deno Deploy   |
| CSSフレームワーク   | Tailwind CSS  |

さて、何を作るかは決まりましたが、私はWebアプリを作ったことがないので何が必要なのかも分かりません。

Webフレームワークが何なのかもよく分からないので、公式ドキュメントやそのチュートリアルでまず何を使えばどんなことができるのかを調べていきます。

公式ドキュメントの英語はブラウザの翻訳機能を使って、崩れるような部分は原文と見比べながらなんとかしていきます。

紆余曲折ありましたが、調べたところ、開発言語、Webフレームワーク、Webライブラリ、ランタイム、クラウドサービス、CSSフレームワークを決めれば、ある程度スムーズにいきそうだという結論に落ち着きました。

#### Deno🦕

技術選定の方針として、せっかく自分で技術を選べるのだから最新技術で固めたいと考えた私は、Node.jsの次世代のランタイムといわれているDenoに興味を惹かれました。
 
Denoについて調べてみると、リンターやHMR等のエコシステムが統合された状態から開発を開始でき、TypeScriptにネイティブ対応であるというメリットがあるようだということが分かりました。

また、Denoを起点に相性の良いクラウドホスティングサービスとしてDeno Deploy、WebフレームワークとしてFreshを使うことにしました。

#### TypeScript🟦

JavaScriptに静的型付けを導入し、分かりやすくバグの出にくいコードを書けるとされているTypeScriptを開発言語としました。

#### Deno Deploy🦕

Deno Deployは無料枠があり、その名の通りDeno環境構築済みなのでデプロイすればそのまま動きます。

また、GitHubのmainブランチにコミットすると自動的にデプロイできるGitHub ActionsのCI/CDの設定がすでに用意されているというのも快適です。

#### Fresh🍋

Freshについては基本的にSSRで、onClick等が必要なインタラクティブ部分だけをCSRされるislandsに切り出すというアイランドアーキテクチャが特徴で、いろんな技術があるんだなと改めて思いました。

#### Preact⚛️

Freshを使う場合、より軽量なReactというコンセプトのPreactというWebライブラリがセットになっているようです。

#### Tailwind CSS🥏

Freshが対応するCSSフレームワークとして、ユーティリティファーストでCSSクラス名の乱立を防げると巷で噂のTailwind CSSというものが使えるみたいです。

## 開発🖥️

ようやっと開発開始です！
選んだ技術の公式ドキュメントやChatGPTに吐いてもらったコード例を参考にどうにかして作っていきます。

``` :ディレクトリ構成
play-everyone-sugoroku-maker
├ components
├ islands
├ routes
├ static
└ utils
```

- ヘッダーとフッター
![ヘッダーとフッター.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852276/c04f3712-b604-31a8-52f8-9395bc09e3c6.png)
各ページに共通の部分は`_layout.tsx`にまとめて共通化し、ナビゲーションなどの変更の際はこのファイルのみ変更すればよいようにしました。
微妙に動いているサイコロのドット絵がチャームポイントです。
　
- つくってあそぶ画面(つくるモード)
  ![つくる.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852276/e8987969-12a6-0913-8ebe-0d0a4118d317.png)
  この画面の開発はグリッドですごろくボードを表現するアイデアからスタートしました。 
途中で変な挙動をしそうになったので、スタートとゴールを1か所に制限したのが工夫した点です。
　
- つくってあそぶ画面(あそぶモード)
  ![ランキング.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852276/b425e6d9-2850-1e78-e6cc-4d30fe7e17c9.png)
  プレイヤーが進んだマス数でランキングを表示しています。
  「1すすむ」を反映し忘れたり、TSのソートの書き方が独特だったりで苦労しましたが`console.log()`で地道にトレースしながら捌きました。
  こういったバグの修正は特にリンターやHMRがあってよかったなと感じました。 
　
 - あそびかた画面
  ![あそびかた.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852276/30619871-71e0-5587-544f-b1e3c14a5904.png)
  なるべく文章を減らして画像(スクショとマーカー)で説明するよう心掛けました。
　
- レスポンシブ対応
  ![レスポンシブ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852276/c3555403-73a6-ffdc-125f-6be00f8f7763.jpeg)
  モバイルテストはデスクトップPCとiPhoneを家のwi-fiにつないで、`ipconfig`で出てきたPCのipアドレスをスマホから直打ちして行いました。

  途中すごろくボードがスマホだと消滅する事態が発生しましたが、Tailwind CSSの`md:`ディレクティブで対応しました。

  PCだと画面が横に広いのでサイコロをボードの左右に表示していますが、スマホだと縦に長いのでボードの上下に表示するようにちょっとしたこだわりをいれました。

## まとめ💫

  色々と大変でしたがどうにか2週間ほどでコア機能を完成して公開できたのでよかったです。

  今後も楽しく開発を続けていく予定なので、今後の展望を残しておきます。

  読んでくださりありがとうございました！

#### 今後の展望✨

  - すごろくマップのバリデーション🔎
　
  - websocketでのオンラインプレイ対応⚡
　
  - DenoKVによるすごろくマップの保存と公開🌐
　
  - Google AdSense☕

## 参考👀

- ファビコンドット絵とico=>gif変換サイト🎲
サイコロのドット絵の画像作成
https://www.favicon.cc/
https://www.aconvert.com/jp/image/ico-to-gif/
　
- MDN Web Docs🟨
JavaScript, Web API等
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted
　
- Fresh🍋
TypeScript, routesやislands等
https://fresh.deno.dev/
　
- Preact⚛️
useSignal等
https://preactjs.com/guide/v10/signals/
　
- React⚛️
コンポーネント, チュートリアル等
https://ja.react.dev/learn
　
- Deno🦕
Deno自体のインストール等
https://docs.deno.com/runtime/
　
- Deno Deploy🦕
Deno Deployの始め方等
https://docs.deno.com/deploy/manual/
　
- Tailwind CSS🥏
Tailwind CSSの書き方等
https://tailwindcss.com/docs/installation