この文章は、 Akashic Engine Advent Calendar 2019 の 10 日目です。
Akashic Engine と RPG アツマール
Akashic Engine は、ニコニコ生放送上で配信者と視聴者が遊べるゲーム、いわゆる ニコ生ゲーム の作成に利用できます。作成したニコ生ゲーム (ニコニコ新市場対応コンテンツ) の登録は、
- HTML5 ゲーム投稿サイト RPGアツマール に投稿し、
- そこからニコニコ新市場に「登録申請」する
というステップで 行われます 。そのためニコ生ゲームは、特に非公開にしなければ自動的に RPG アツマール上でも遊べるものになります。公式が投稿しているものだと『ゴミをゴミ箱に入れるだけのゲーム』 なんかがあります。
RPG アツマールにはゲーム投稿サイトとしていろいろな機能がありますが、Akashic Engine には特段それを意識したツールサポートはまだまだないのが現状です。そのため、普通にニコ生ゲームを作成して投稿すると、 RPG アツマールでは少々「浮く」部分が出てきてしまいます。
そこでここでは、Akashic Engine を RPG アツマール上で動かす時の細かな Tips をいくつかご紹介します。
アツマールでのみ背景色をつける
ニコニコ生放送上で実行される場合、ゲーム画面は配信に重なって表示されます。
そのため画面の一部を透明や半透明にしたいことがよくあります。しかし同じゲームが RPG アツマールで実行される時は、後ろに配信画面は当然ないので、この透明部分は真っ黒になってしまいます。PRG アツマールでは投稿時にゲーム画面の「枠外」の色を選べますが、これはゲーム画面の部分には適用されません。
この問題は、 akashic export html
コマンドのオプション --inject
を使うことで回避できます。
--inject <filepath>
は、出力される HTML の head
要素の末尾に <filepath>
のファイルの内容を書き込むオプションです。この HTML は、アツマール (や Web サーバに置いた時) でのみ利用され、ニコニコ生放送上では使われません。
そこで次のような内容のテキストファイル injectdata.txt
を準備します。
<style>
body {
background: silver;
}
</style>
export html コマンドを次のように実行すると、
akashic export html --atsumaru -o ./game.zip --inject ./injectdata.txt
生成される HTML にはこの style
要素が含まれるため、アツマール上では透明部分が灰色になります。 background
の色だけ指定していますが、要するに単なる HTML/CSS なので、任意の記述ができます。
アツマールでのみ特定の動作を行う
たとえば「RPG アツマール上でのみ "もう一度プレイ" ボタンを出す」など。
ニコニコ生放送の、特にランキング形式のゲームは「一度起動して時間いっぱいプレイ→結果発表して終了」というフローを辿ります。しかし RPG アツマール上で同じゲームを遊ぶ場合は、単にもう一度プレイするボタンが欲しくなることがあります。
"もう一度プレイ" ボタン自体は、Akashic Engine で普通に作成すればよいはずです (ゲームの内部状態を初期状態にリセットしまくる処理になるでしょう)。
問題はそのボタンを「RPGアツマールでのみ」表示することですが、別に難しいことはありません。RPG アツマール環境では、アツマール独自の機能を提供する変数 RPGAtsumaru
が存在します。この変数の存在をチェックをすれば、コンテンツが RPG アツマール上で実行されているかを判定できます。
if (typeof window !== "undefined" && window.RPGAtsumaru) {
// RPG アツマール上でのみ実行されるコード
var returnToStartButton = new Sprite({ // 最初に戻るボタン
// ...
});
scene.append(returnToStartButton);
}
まあ、見たまんまですね。
一点だけ、 Akashic Engine のコンテンツは必ずしもブラウザ環境で実行されているとは限らないため、 window
がないかもしれないことに気をつけてください。存在チェックは typeof window
から始める必要があります。
なおゲームを以下のコマンドで生成した、いわゆる「新市場ランキング対応コンテンツテンプレート」の場合は、
akashic init -t javascript-shin-ichiba-ranking
main()
の引数 param
に param.isAtsumaru
がついています。アツマール環境でのみ true
になっているので、これを利用することもできます。
アツマールのスコアボードに対応する
ランキング対応ゲームの場合、ゲーム中ではスコアがあります。RPG アツマールにもハイスコアを記録してランキング形式で表示してくれる「スコアボード」機能がありますが、両者はそのままでは連動してくれません。
これはゲーム部分が終わってスコアが確定した時点で、次のコードを実行することで対応できます。
if (typeof window !== "undefined" && window.RPGAtsumaru) {
var scoreboards = window.RPGAtsumaru.experimental.scoreboards;
scoreboards.setRecord(1, g.game.vars.gameState.score).then(function () {
scoreboards.display(1);
});
}
setRecord()
でスコアを記録し、 .then()
で書き込みの完了を待ってから display()
でスコアボードを画面に表示させます。setRecord()
と display()
の 1
はスコアボード ID で、両方で同じ値なら 1 から 10 までどれでも構いません。(おそらく複数のランキングのスコアボードを作るための機能ですが、ニコ生ゲームのスコアは一種類しかないので 1 だけ使えば済みます)
……と書きましたが、実はこのコードは akashic init -t javascript-shin-ichiba-ranking
で生成したゲームには最初から書き込まれています。
もちろんこのコード自体は一例で、「ボタンを押したらスコアボードが表示される」などの実装も可能でしょう。ただし .then()
に渡した関数が呼ばれるまでは、 setRecord()
の呼び出しが反映されていない可能性があるので注意してください。このへんの仕組みに明るくない方は "JavaScript Promise" とかでぐぐってください……。
アツマールのスクリーンショットシェア機能を使えるようにする
RPG アツマールの実験的な API に、ゲーム画面のスクリーンショットを Twitter でシェアする機能があります。このスクリーンショット機能は RPG ツクール MV のゲームなら自動的に対応されていますが、Akashic Engine の場合は自力でスクショを作ってあげる必要があります。
これは次のコードで実現できます。(ゲーム冒頭で一度実行するだけで動作します)
if (typeof window !== "undefined" && window.RPGAtsumaru) {
window.RPGAtsumaru.experimental.screenshot.setScreenshotHandler(function () {
const pngData = document.getElementsByTagName("canvas")[0].toDataURL("image/png");
return Promise.resolve(pngData);
});
}
ブラウザ環境での Akahsic Engine は canvas 要素に描いていること、またその canvas が一つしかないことに当て込んで、無理やりゲーム画面の canvas を取得して PNG にしています。まったく 公式の API ではない ので、将来の互換性の保証は全然ないのですが、他に方法がなく……。
g.Util.createSpriteFromE()
で作成した g.Sprite
の surface
プロパティから内部データを引っこ抜けば「ゲーム画面の一部」だけスクショにできるなど、関連する小ネタは他にもありますが、いずれにせよ現時点では Akashic Engine の公開 API の外側を触らざるを得ません。
まとめ
RPG アツマールでの見栄えを良くする Tips をご紹介しました。
アツマールは API リファレンス を眺めるといろいろな機能があって、本当はボリューム調整やコメントもある程度制御できるはずです。現状では公式の API 外の動作に依存せねばならないことも含めて、将来的には akashic-cli が自動的にうまいことしてくれるようにしたいですね……。