はじめに
この記事は 「MM2025 開発記」 シリーズ第6回です。
前回の記事では、ローディング画面の重要性と画像の読み込み処理について解説しました。
今回はTextAlive App API の導入~実際の実装方法などについて紹介します。
利用の流れ
TextAlive App API を利用するには、
- スクリプトの読み込み
-
Playerの生成 - 楽曲・歌詞データの取得
という段階を踏む必要がある。
TextAlive App API読み込み
今回のコードでは、TextAlive App APIを外部スクリプトとして以下のようにHTMLで読み込んでいる。
<script src="https://unpkg.com/textalive-app-api/dist/index.js"></script>
そのため、読み込みが完了していることを確認してからJavaScriptを実行する必要がある。ここで必要となるのが、waitForTextAliveApp()という関数である。
function waitForTextAliveApp(callback) {
if (window.TextAliveApp && window.TextAliveApp.Player) {
callback();
} else {
setTimeout(() => waitForTextAliveApp(callback), 50);
}
}
-
window.TextAliveApp.Playerが使える状態か(読み込みが完了しているか)をチェック - まだだった場合、50ms 待って再チェック
- 使えるようになったらコールバック関数を実行
前回の記事では画像やフォントの読み込みを待つコードについて紹介したが、これはそのTextAlive App API版である。
※ TextAlive App API は外部スクリプトのため、前回使用したawait では直接待てず、このように別の「使えるようになったか」を確認する処理が必要になる。
Playerインスタンス生成
Playerとは
簡単に言うと、音楽・歌詞・再生時間などをまとめて管理するもののこと。
つまり、TextAlive App APIではこれを作らないと何も始められない。
TextAlive App APIが利用できる状態になったら、Playerを生成する。
ただし、この時のPlayerは生成しただけでまだ使える状態ではなく、楽曲情報・歌詞情報などが準備されていない。
waitForTextAliveApp(() => {
const Player = window.TextAliveApp.Player;
//...省略...
const mainApp = new Main();
});
そのため、楽曲などの準備(初期化)は生成後にMainクラス内で行っている。
taPlayer = new Player({
app: { token: "xxxx APIトークン xxxx" },
mediaElement: document.querySelector("#media"),
});
-
app.token:TextAlive App APIの利用に必要なトークン。誰のアプリかを示す。 -
mediaElement:実際に音声を再生する<audio>要素
楽曲・歌詞データをどう取得しているか
イベントリスナー構成は以下のようになっている。
※イベントリスナーとは
「特定のイベントが起こった際、それに対応して特定の関数を実行する」という仕組み
taPlayer.addListener({
onAppReady: (app) => this._onAppReady(app),
onVideoReady: (v) => this._onVideoReady(v),
onTimeUpdate: (pos) => this._onTimeUpdate(pos),
onPlayEnd: () => this.onPlayEnd()
});
-
onAppReady:アプリ準備完了後、再生する楽曲を指定 -
onVideoReady:歌詞データの取得 -
onTimeUpdate:再生位置進行
onAppReady:アプリ準備完了後、再生する楽曲を指定
_onAppReady(app) {
if (!app.songUrl) {
this._player.createFromSongUrl(
"https://piapro.jp/t/ULcJ/xxxxxxx",
{
video: {
beatId: xxxxx,
chordId: xxxxx,
repetitiveSegmentId: xxxxx,
lyricId: xxxxx,
lyricDiffId: xxxxx
}
}
);
}
}
ここでは再生楽曲が未指定の場合、TextAliveに登録されている楽曲を指定している。
onVideoReady:歌詞データの取得
_onVideoReady(v) {
const lyrics = [];
if (v.firstChar) {
let c = v.firstChar;
while (c) {
lyrics.push(new Lyric(c));
c = c.next;
}
}
}
歌詞を1文字ずつ繋がった構造(連結リスト)として受け取る。
ここで、楽曲情報・歌詞などのゲームで使用する要素がすべて揃う。つまり、ここの処理まで完了すればゲーム開始できるので、以下のコードを追加しローディング画面が消えるようにする。
_onVideoReady(v) {
// 歌詞データの取得
//...省略...
// ローディング画面を消す
const loadingScreen = document.getElementById("loadingScreen");
if (loadingScreen) {
setTimeout(() => {
loadingScreen.style.display = "none";
}, 2000);
}
}
onTimeUpdate:再生位置進行
_onTimeUpdate(position) {
this._position = position;
if (
position >= this._player.video.duration - 7000 &&
goalX === null
) {
goalX = scrollX + canvas.width - 200;
gameStarted = true;
gameLoop();
}
}
毎フレームごとに呼ばれ、現在の再生位置を取得する。
ゴール設定などに利用する。
さいごに
今回の記事では、TextAlive App APIの具体的な利用方法について解説しました。
次回は、一旦コード本体から離れ、ゲームで使うドット絵作成について紹介します。