12
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

qnoteAdvent Calendar 2022

Day 7

Next.jsで文字数制限の無いポケモンワードルを作った話

Last updated at Posted at 2022-12-06

はじめに

本記事はオフィスに猫がいる会社、株式会社qnoteのアドベントカレンダー7日目の記事となります。

いつもポケモンワードルで遊んでいるみなさまへ。

5文字以外のポケモンも登場させてあげたいですよね?

ということでNext.jsを使って文字数制限の無いポケモンワードルを作ります。

ポケモンワードルとは

5文字の英単語を推測して当てるWordleを参考に作られた、5文字のポケモンの名前を推測して当てるゲームです。
無限に遊べる神ゲーです。

本家ポケモンワードル
作者様のTwitter

今回作ったもの

5文字以外のポケモンも含め、全ポケモンが出題対象となるポケモンワードルです。
https://pokemon-wordle.vercel.app/
※本サービスで使用している情報や画像はPokeAPIから取得したデータとなります。

poke.gif

開発工数はトータル30〜40hくらいかかっていると思います。
ただ、初めてNext.js(React)を触った割にはサクサク作れた気がします。

ざっくり解説

環境

Next.js:13.0.2
React:18.2.0
TypeScript:4.8.4
Tailwind CSS:3.2.0
Vercel

仕事ではVue.jsとLaravelをよく触っていますがReactは全く触れたことがなかったので、勉強のためにNext.jsを採用しました。

環境自体は↓から丸っとインストールできます。
https://create.t3.gg/

VercelはWebホスティングサービスで、Githubなどと連携すると自動デプロイまでしてくれる神サービスです。(Vercel Inc.という会社のサービスらしくNext.jsの開発元でもあるそうです)

機能

・シリーズ選択(本家同様)
本家同様にシリーズを選択できるようにしています。

・特定のシリーズから新登場したポケモンのみ出題(オリジナル)
こちらはオリジナルの機能で、初代は大体わかるけどダイパから新登場したポケモンはあまり覚えてないな・・・という人向けに作りました。
(筆者が初代、金銀、剣盾、とプレイしているにわかだったので自分の勉強用に入れたかった...)

・出題文字数ランダム(オリジナル)
全ポケモンを出題対象にして、ランダムに出題されたポケモンの文字数に応じて入力欄を動的に切り替えるようにしました。

・シルエット表示(オリジナル)
こちらもオリジナルの機能で、出題中にシルエット表示をする機能です。
開発中だけ表示するつもりだったのですが、シルエットクイズとしても楽しめるので残しました。
ポケモンマスターの皆様はシルエットを見ただけでほとんどわかってしまうと思いますが、アートワーク画像に切り替えたりするとまた違った楽しみ方ができると思います。
ちなみにCSSで通常の色付き画像をシルエット化しています。
参考:contrast() - CSS: カスケーディングスタイルシート | MDN

・画像表示切り替え(オリジナル)
おなじみのドット絵とアートワーク画像を切り替えるようにしています。
ドット絵はいわずもがな素晴らしいですが、アートワークは初めて見るものが多くすごく惹かれる絵ばかりです・・・!

所感

・とにかく作っていて楽しかった
初めてNext.jsとReactを触り、これはどうすれば実現できるんだろう→調べる→実装する→動いた!の繰り返しで徐々にゴールに近づいていく感覚がとても楽しかったです。
こんな機能あったら良いな、と思いつきでオリジナルの機能を実装できるのも個人開発の魅力だなと思いました。

・SSR、SSGの切り替えが簡単
ビルド時に一度だけ情報取得する場合とリクエストごとに情報取得する場合と、切り替えがとても簡単でした。
こちらは↓の記事がめちゃくちゃわかりやすかったのでNext.js使いの方は必読です。
参考:Next.jsにおけるSSG(静的サイト生成)とISRについて(自分の)限界まで丁寧に説明する

・オブジェクト、配列、二次元配列のState管理は罠!
Reactの変数の変更検知はHooksのSetStateを使って行うのですが、Object.is()を使って判定している関係で、オブジェクトのアドレスが変わらないと再レンダリングされません。
スプレッド構文などで新しいオブジェクトを生成するとうまく再レンダリングされます。
更に二次元以上の配列になると浅いコピー(シャローコピー)と深いコピー(ディープコピー)を理解する必要があります。
参考:浅いコピーと深いコピー

・文字比較やStyle管理のアルゴリズムが意外とややこしかった
入力された文字の中で緑判定、黄色判定された場合はそれ以降同じ文字があってもグレーになる、など細かい仕様があるので地味にややこしかったです。(正確には存在する文字数分しか色が変わらない)
また、文字入力欄とソフトキー1個1個のStyle管理が意外と大変でした。
こちらは現状二次元配列をいくつか用意して実現していますがもう少しスマートな方法がありそうです。

今後の課題

・コードのリファクタリング
主にコンポーネント設計をしっかりしたいです。
いまはゴリ押しコード満載です。

・UI見直し
他のサービスや本家ポケモンワードルと比べた時に、なんかださいな〜感が拭いきれずWebデザインも勉強しなきゃと思わされました。
なんかださい、のなんかを言語化できるようにしたいです。

・Prismaを使ったDB連携
今回はひとまずTypeScriptの定数でポケモンの情報を保持するようにしました。
今後はPrismaを使ってDBと連携して管理したいと思っています。
(Laravel以外のORMを触るのが楽しみ)

・オンライン対戦の実現方法検討
こちらはリリース予定はないのですが、本家ポケモンワードルはオンライン対戦が可能でどうやって実現しているんだろう、ととても興味があるので色々試行錯誤して作ってみたいと思っています。
→こちら、なんと本家ポケモンワードルの作者様とやりとりさせていただくことがあり、情報交換させていただきました!感謝します!

さいごに

今回初めてReact,Next.jsを触りましたが、書籍を1冊読んだ程度でも比較的扱いやすく、やりたいことが簡単に実現できた印象があります。
コード整理が全くできていないのでコードの公開はしていないのですが、ある程度整理できたら公開しようと思っています。
また、ReactはVue.jsとは異なる書き方が多いですが、モバイルアプリ開発にて触っていたFlutterと、Hooksの考え方が似ていたので扱いやすかったです。

今後もポケモンワードルの改修や、その他個人開発を通して情報発信していきたいと思います!
最後まで読んでいただきありがとうございました!

参考情報

本家ポケモンワードル
PokeAPI
Next.jsにおけるSSG(静的サイト生成)とISRについて(自分の)限界まで丁寧に説明する
もう一度理解する、JavaScriptの配列とコピー

12
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?