はじめに
今年、初音ミク「マジカルミライ 2025」プログラミング・コンテストに初めて応募し、入賞は逃してしまいましたが、入選することができました。
せっかくなので、アプリを作るにあたって考えたことや苦労したことなど、記事にまとめようと思います。
この記事は、自分の製作過程や応募後の振り返りを記録するために書いたので、技術解説というよりは体験記として読んでいただけたら嬉しいです。
このコンテストでは、TextAlive APIを利用し、楽曲にあわせて、歌詞などの演出が動くWebアプリケーションを作り、応募することができます。
応募資格も特になく、応募のきまりを守れる方であれば誰でも応募することができるコンテストです。
アプリ概要
私が作ったのは、入選作品エントリーNo.8のResonance Starsです。
主な機能としては、以下を実装してあります。
- TextAlive APIを利用した曲の再生に合わせた歌詞の表示
- 曲の再生に合わせた、楽曲のFFT結果と連動した星の瞬き
- 歌詞から星座名を選び、星をつないで星座を作る機能
FFT解析をWebアプリの機能に組み込むのは、実現方法が見つからなかったため、事前にPythonで解析して、解析結果ファイルをアプリに組み込む形を取っています。
ソースコードはこちらで公開しています。
使用したライブラリやアピールポイントはREADMEに記載してあります。
私がこの作品を作る間も、過去のコンテスト応募者のソースコードを参考にさせていただいていたので、私のソースコードが誰かの役に立てばうれしいです。
製作期間は、5月のGW明けからのおよそ2ヵ月です。
初めの1ヵ月はアプリのコンセプトや機能の決定、JavaScriptの学習、TextAliveの使い方調査、楽曲分析方法の調査などを行い、後の1ヵ月で実際のアプリ実装を行いました。
社会人のため、仕事終わりの数時間や休日に開発を行っています。
アプリのコンセプトの決め方
最初に、「何かを創作するためのアプリを作りたい」というコンセプトを決めていました。
VOCALOID文化の大きな魅力は「誰でも参加できる創作文化」ですが、イラストも、音楽も得意でない私は、創作に参加するハードルが高いと感じていました。
そこで、「特別なスキルがなくても」「上手い・下手を気にせず」創作体験ができるアプリを目指すことにしました。
昔Project DIVAが大好きで、ゲームに入っていたエディットモードで、特別なスキルがない自分でもPVを作ることができたという体験に影響を受けていると思います。
また、マジカルミライ2025のテーマ「星河一天」や、私の地元、仙台でも開催されるということで、これらの要素を絡めようとも考えました。
仙台要素を盛り込むことは難しく諦めてしまいましたが、「星河一天」に関連した星空の要素を入れたアプリを作ることにしました。
加えて、アプリの技術面のアピールポイントを増やすために、「曲の再生に合わせて星が瞬く」演出を取り入れています。
昔から音楽のビジュアライズ化にぼんやりと興味があり、過去に、現在鳴っている音に合わせて図形が表示されるツールを作っていたことがあるので、この経験を活かすことができました。
苦労した、工夫したところ
楽曲の終了判定
曲の終了時に自動でリザルト画面に遷移させたかったのですが、楽曲の終了を検出する方法が分からず、苦労しました。
結局、楽曲の再生中に呼ばれる'onTimeUpdate'の中で、'現在の楽曲再生位置 > 曲の長さ - 0.5秒'であれば楽曲の再生が終了したと判定する処理を入れ、これで楽曲の終了判定を実現しました。
しかし、環境によっては、楽曲の再生開始時に一瞬だけ、'現在の楽曲再生位置 == 曲の長さ'となることがありました。
これにより、楽曲再生開始直後に「楽曲の再生が終了した」と判定されてしまうことがあったため、楽曲の終了判定に、楽曲の再生開始時刻から10秒以上経過していること、をAND条件として追加して解決しています。
画面レイアウト
Webアプリは端末によって画面サイズ、比率が変わってしまうため、どんな端末でも表示を崩さないための工夫が必要でした。
しかも、私のアプリは、なるべく多くのユーザーに触れてもらうために、PCにも、スマートフォンにも対応させたかったので、画面の縦横比が変わっても表示が崩れないようにすることも必要でした。
これらを解決するために、画面の中央でなるべく大きく9:16の領域を取得し、アプリの要素はその中にのみ描画するようにしています。
フォントサイズの自動調整
歌詞は、TextAliveで定義されているPhraseごとに1行で表示していますが、曲によっては、文字数の多いPhraseがあります。
これを他の文字と同じフォントサイズで表示しようとすると、歌詞の表示領域に収まらず、表示が崩れてしまいます。
この問題は、歌詞の表示時に、Phraseが1行に収まる大きさになるまで、文字サイズを小さくする処理を入れて解決しました。
URLバーの表示/非表示
AndroidのChromeでは、Webサイトの表示中に画面をスクロールすると、URLバーの表示/非表示が切り替わってしまいます。
これにより画面の表示領域が変わり、表示が崩れてしまうことがありました。
この問題を回避するために、画面表示時にURLバーを除く表示領域を取得して、その領域内に収まるサイズでアプリを表示し、スクロール自体ができないようにしています。
SafariでCSSアニメーションがカクつく
歌詞の表示は、下から上へスライドするアニメーションをつけていましたが、Safariではこれが正常に動作せず、ほんの少し振動するだけのアニメーションになってしまいました。
検索すると、SafariではCSSアニメーションが正常に動かないことが多いらしく、多くのトラブルシューティングがありました。
しかし、どの対応策でも私のアプリで発生していた問題は解決せず、CSSアニメーションはメイン機能ではないので解決は諦めています。
私はiOS端末を持っていないので、Safariでの動作確認をできたのが提出直前で、この問題に気が付いたときにはかなり焦ってしまいました。
もっと早い段階で、様々な端末での動作確認をしておくべきでした。
アプリ操作時のエフェクト作成
星をタップして星座を作るときと、「星座を作る」ボタンを押したときには画面上にエフェクトが表示される仕様になっています。
これは一から自分で作ったわけではなく、Github Copilotに「タップエフェクトを作って」などとお願いして仮のエフェクトを作ってもらい、そのエフェクトを自分の好みになるまで修正して作りました。
エフェクトを一から作成しようとすると、デザイン面でも、実装面でも、かなり大変だったと思うので、Copilotに大変助けられました。
特に星座作成時に表示される魔法陣のようなエフェクトは、どんなデザインにするかかなり悩みながら作ったので思い入れがあります。
コンテスト終了後の反省点
訴求力不足
UIデザインをシンプルにまとめてしまったので、他の入選作品と並んだ時に地味に見えたと感じています。
特に、ボタンや、曲に合わせて表示される星は、もっとはっきりとした色にした方がよかったと思いますし、UIデザインももう少し工夫できたかもしれません。
「星座を作る」というアプリのメイン機能も、他の人が遊んでいるのを見て満足してしまう面があり、「自分もやってみたい」と思わせるのが難しかったと感じています。
また、アプリタイトル「Resonance Stars」も、「星座を作れる」、「誰でも創作に参加できる」という意味を押し出したタイトルにした方が、アプリの魅力が伝わりやすかったもしれません。
入選までは技術的なアピールが必要だと思いますが、一般投票ではユーザー向けに、「自分も遊んでみたい」と思えるアプリの魅力が必要だと感じました。
リザルト画面のSNS投稿機能
開発中にも、余裕があったら作りたいと思っていたのですが、リザルト画面に表示される星座を自動で画像化して、SNSに投稿できる機能がつけられればよかったです。
この機能が技術的に実現可能かは分かりませんが、もし実装できれば、自分のアプリの知名度向上、マジミラプロコン自体の盛り上がりに貢献できたと思います。
アプリに合った曲を選ぶ
私のアプリは「歌詞に含まれる単語から星座名を選ぶ」という特徴がありますが、物体の名前があまり出てこない楽曲を選択してしまうと、星座を考えるのが難しく、十分に楽しめないと感じました。
全ての課題曲に対応したアプリのほうが、印象が良いのではと思い、課題曲6曲から再生する曲を選択できるようにしたのですが、アプリに合った曲のみを実装するか、おすすめ曲を表示する仕組みがあれば良かったと思います。
まとめ
自分の作品が入選できたのは本当に幸運だったと思います。
製作中は、これだけ頑張って作ったのに入選できなかったら……と何度も不安になったので、入選の連絡が来たときは安心しましたし、少し泣いたくらいには嬉しかったです。
イラストでの協力を引き受けてくれたbotanさん、テストプレイに協力してくれた友人、プロコンの運営の方々、Text Aliveの開発者等、関わってくださった人には本当に感謝しています。
今回のコンテストを通して、物を作ることの大変さを身にしみて感じ、その分、いま世界に出ている作品やクリエイターのことをもっとリスペクトしようと思うようになりました。
来年もまた挑戦したいですし、来年のコンテストまでの間も、作品を作り続けてレベルアップしていきたいと思います。