この記事は鈴鹿高専Advent Calendar 2024 20日目の記事です。
はじめに
パソコン甲子園 モバイル部門の本選に出場したので、ざっくり振り返ってみます。
アイデア出し
今年のパソコン甲子園のテーマは「Game for Change ゲームが変える世界 ~ゲームのルールで世界を救え~」で、社会課題をゲームで解決することを考えました。
まず、社会課題を一通り挙げてみました。ゴミ問題、食品ロス、地球温暖化、など。
あまり明確なアイデアが出なかったので、先生に相談しました。
この時点で出されていた社会課題は、抽象的で規模の大きい課題であり、こういった課題をターゲットにしてしまっては、多くの立場にとってメリットのあるようなサービスを作ることが難しい、とのことでした。
例えば、食品ロスを解決するようなアプリで、「食品を廃棄してしまうお店がアプリを介して食品を安く販売し、他のユーザに買ってもらう」というものを考えます。食品を買う立場のユーザは食品を安く買えるというアプリを使用する動機があります。しかし、食品を安く売る立場のユーザ、つまりお店側にはアプリを導入する動機がないです。
この例では、食品を買う立場のユーザと、食品を売る立場のユーザの両方の利益を同時に満たすことができないため、サービスが成立しません。
そういった理由から、個人の問題に絞ってそれが社会に繋がることを仮定してアイデアを出すことにしました。
そこで、私はまず自身の問題について考え、過去に「声が相手に届かず、コミュニケーションがとれない」という問題に直面した経験があり、それを課題として設定することにしました。
この課題を背景に、「キャラクターと自分の声を使って対話しながらノベル形式でお話を進めていくゲーム」を作ることにしました。
実装
技術選定
ゲームを作るというのに、バージョン管理が大変という理由でUnityを使わずAndroid NativeなJetpack ComposeというUI構築ツールを用いて実装を行うことになりました。
正直、これは技術選定をやらかしたな、と思っています。Nativeだと割と縛りが多く、またアニメーションの実装が大変で、無駄な部分で時間を使ってしまうことが多かったです。
以下がざっくりとした技術スタック的なやつです。
実装 | 技術 |
---|---|
フロント | Jetpack Compose |
バック (音声認識部分) | SpeechRecognizer |
ローカルDB | SQLite |
ORM | Room |
アニメーション | lottie-compose, After Effects |
実装
- バックエンド (音声認識部分)
声の明瞭さを採点するために、読み上げる文章と入力された文章がどれだけ違うかを判定する必要がありました。
声と実際の文章の比較に編集距離(レーベンシュタイン距離)という基準を用いました。
計算は恐らく動的計画法を用いて$O(mn)$の計算をしていますが、僕はバックエンドを担当していないので深堀りしません。
- バックエンド (データベース部分)
プレイヤーがシナリオをプレイした結果として後から追加されるリザルト用のテーブルと、シードデータとして読み込まれるシナリオ用のテーブルを用意しました。
リザルトのデータ管理では特に問題はなかったです。
フロント側の状態管理で非同期処理を行うのでそこでちょっと苦労したぐらい......?
シナリオはハードコードでぶち込みました。
本当はjsonにシリアライズしたかったので、本選直前になってシリアライズしようとしたのですが、画像などにリソースの扱いがかなり難しかったので諦めました。
↑ 迫真のhardcode came back
- フロントエンド
僕はタイトル画面の作成、ホーム画面の作成、シナリオ選択画面の改善、シナリオ本編画面の作成、リザルト選択画面の作成を行いました。
シナリオ選択画面の改善でかなり綺麗にゲームっぽいUIを組めたことが嬉しかったです。
シナリオ本編画面の作成では、特にライブラリがなかったためノベルゲーム周りのロジックを全部一から組むのに時間を要しました。
文字列が1文字ずつ表示されて、最後まで表示されると左下に逆三角形のアニメーション表示、クリックすると最後まで文章が一気に表示、など全部やりました。本当に大変だったです。
(僕が今回Unity使えばよかったと思った理由です。)
アニメーションですが、lottie composeを使うといい感じに実装できます。
自分が作った絵にアニメーションをつける場合はibis Paint XでPSD出力 → After Effectsでインポートしてアニメーション割り当て → lottieでjson出力の流れでできます。
タイトル画面(アプリエントリ時)では自作絵で自作アニメーションを流せてとてもとても良かったです。
- その他
シナリオ作りと素材作り、素材集めが非常に大変でした。
シナリオに関しては、ざっくりとした流れのアイデアを作るのは難しくなかったですが、台詞や地の文を作るのが非常に難しかったです。特に、読み上げるキャラの文章量を調節することがかなりキツく、この調整にかなり時間を使ってしまいました。
キャラ絵の作成に関しては、ibis Paint Xを使って早くて2時間ぐらいで描いてました。ですが、表情差分などでもっと時間を食って、1シナリオあたりのキャラ数もそれなりに多いので本選の始まる1週間前はなぜかこのリソースに3徹して割いてました。
また、素材集めでは権利関係を調べるのが大変でした。
十分な長さのシナリオと素材が集まらなかったので1分ぐらい遊べるものが3つできました。
プレゼン
徹夜のし過ぎでなんにも覚えていませんが、とりあえずいい感じのスライドを作れたと思ったらプレゼン練習で先生にばちぼこにされました。自分から言えることはどれだけいい感じの絵やアニメーションがあっても流れに論理がなければ理解してもらえないということです。
本番のプレゼンが一番うまくいっててよかったです。
デモ
画面に映すことに全然頭が回っていなかったので、いい感じのツールをChatGPTに聞いたらscrcpyといういい感じのOSSを教えてくれました。使ってみたらデモ会場で爆速Androidミラーリング環境を構築できました。ありがとう、ChatGPT、ありがとう、scrcpy。
デモ審査のときは深夜テンションで楽しそうにプレイしました。自分が頑張った点もたくさんあり、かつこだわりポイントも多かったので、実際楽しかったかも。
やらかしたこと
GitHubで間違えてdevelop <- mybranchをmaster <- mybranchでPRしてマージしました。
Revertをしようとしましたが、git revertはかなり仕様が非直感的で、Revert先も間違えて、Revertをして、やらかしました。
反省
- ゲーム作るならゲームエンジン
- ハードコードはやめましょう
- PRはレビューしてもらおう
- 早く動け!
おわりに
本当にどたばたした開発でしたが、いい経験になったと思います。
これを踏み台にどんどん開発力を上げていきたいと思います。