【次回作】幻想クロスフレイヤ(弾幕脱衣STG)
脱衣STG「幻想クロスフレイヤ」
今作っているものを紹介します。タイトルは「幻想クロスフレイヤ」で、前作に引き続き、東方Projectの二次創作脱衣STGです。
ゲーム内容
地面に◯を3つ撃って円を作り、敵や敵弾を消します。ついでに服も消えます。詳しくは過去記事の「【作品紹介】東方ふくやぶり」と作品ページをご覧ください。
前作「東方ふくやぶり」の反省点として、難易度が固定だったため難しく感じる人がいた、ということがあります。なので、今回は難易度をeasy~lunaticの4種類から選べるようにしています。
脱がす対象は早苗さん(れいさな)、パチュリー(さくぱちゅ)、ルナチャイルド(ルナスタ)です。三月精の二次創作ももっと増えるといいですね。
まだ作成中ですが、おいおい内容を紹介していきたいと思います。とりあえず今日は内部的な話を。
内部スクリプト (DSL) の話
前々回の記事で、ステージ作成には Tiled を使っていると書きました。今回も引き続き Tiled を使っていますが、細かい制御が面倒だったため、シナリオの起動やBGMの再生などのイベントは内部スクリプトで制御するように改めました。Tiled では敵キャラの発生位置を指定するだけになっています。
(ここにTiledの画像……を載せたいが、絵描きさんに絵を使用してよいか確認することを忘れていたので載せられないのだった。残念!)
そもそもSTGの構造を考えてみると、大体のゲームでは、ステージ内に敵集団 (wave) がいて、さらに各 wave を構成する敵キャラがいます。また敵キャラは、指定されたルーチンで移動したりいろいろな弾を発射する、という形になっています。
そこで本作では、wave を制御する WaveScript
、敵を制御する EnemyScript
、敵弾を制御する BulletScript
の三種類のDSLを使い分けることにしました。三種類と言うと多いようですが、実際には WaveScript
と EnemyScript
はほとんど同じものです。
WaveScript
まず WaveScript
について。敵集団とステージ内のイベントを制御するスクリプトです。イベントというのは、シナリオの実行やBGMの再生のことです。
パーサ、インタプリタともにTJSで作成しています。大したことをするわけではないので、どちらも簡単な実装で済ませています。というか、文法を変えてコマンドを追加しただけで、前作のコードを大部分使いまわしています。
EnemyScript
次に、敵キャラの制御スクリプトです。弾を発射したりキャラを動かしたりします。WaveScript
と EnemyScript
はコマンドが異なるだけで文法は同じにしたので、パーサとインタプリタは使いまわしです。手抜きって大事ですよね。
BulletScript
最後に、敵弾の制御スクリプトです。前作ではJSONにTJSを手書きするという、我ながら正気を疑う方法で設定していました。例えば、↓はひじりんのスクリプトで、東方星蓮船の超人「聖白蓮」っぽい動きをするところです。左の画像が今回で言う EnemyScript
で、右の画像が敵弾の設定をしているところ。
右の画像の"st"
にTJS式がありますが、これを function() { ... } incontextof Math
で包んで eval
することで生成した関数を毎フレーム実行していました。
このJSONでの設定が本当に辛かったのと、並列処理ができず処理が重いという問題があったため、今回は設定方法を一新して、敵弾を制御するためのインタプリタをネイティブプラグインで実装しています。
↑こんな感じで、各時刻 t における敵弾の位置を、極座標系 (r, angle) で指定するようにしました。パーサジェネレータには caper を使っています。
半端ですが、今日はここまで。ゲームの内側の話でした。
次回から、絵のことなんかにも触れていきたいと思います。
何かあればコメント欄でどうぞ。
よろしくお願いします。