相変わらず、RPGツクールVXAceをちまちま作業。さすがに近頃飽き始め、昨日は気分転換に本編と関係無い(シナリオ上必須でない)シューティングのミニゲームを作った。シューティングと言っても、イベントコマンドで組んだちょっとしたもので、所謂スクリプトを用いるような弾幕系や、ステージクリア型のものではない。たとえ頑張って作るとしても、俺自身が全くシューティングゲームをやらない(RPGとシミュレーション以外に興味が無い)ため、テストプレイが不可能になる。ゆえにこれは、射的ゲームだ。イメージとしては、昔よくゲームセンターなどに置いてあった、西部劇を意識した射的で、悪人のパネルが出てきたらそれを撃ち、たまに市民のパネルも起き上がるが、それを撃つと得点がマイナスされる、といった懐かしいもの。だから敵は動かないし、攻撃してくることもない。一応、画面下部に得点と自己ベストを表示させることにした。やはり、目に見えて得点が推移するほうが、やる気が出るというもの。今回の射的においては、弾丸は同時に3発まで、パネルも最大3枚まで同時に現れる。つまりイベントに関しても、弾丸3つとパネル(敵あるいは市民)3つは必須となる。こんなふうに作ったので、よかったら以下の作り方をどうぞ。(ネット上にもっと効率のいい組み方なり講座なりあると思うけどね)
!!下準備!!
まず必要な数だけ空のイベントを作成。名称は【イニシャライズ(自動実行)】【射的弾丸管理(並列処理)】【射的タゲ管理(並列処理)】【弾丸1(並列処理)】【弾丸2(並列処理)】【弾丸3(並列処理)】【ターゲットA(決定ボタン)】【ターゲットB(決定ボタン)】【ターゲットA(決定ボタン)】今回はこれだけ。細かく処理を分ける理由は、こちらで管理し易くするためだけなので、必須ではない。ちなみに弾丸は全てすり抜け属性を指定。
!!イニシャライズ!!
マップに入った時、【自動実行】のイベントを作る。メニュー禁止にしたり、主人公の向きを固定したりした後、【射的スタート】のスイッチを入れ、イベント一時消去。このミニゲームでは、主人公の移動速度を2倍にした。あと、忘れてはならないのがタイマーの開始。1~3分くらいが丁度良さそうに思うが適宜。カウントが早いほうが臨場感があるため、個人的にはスクリプトを弄ってカウントを6倍速にした。
!!射的弾丸管理!!
【射的スタート】のスイッチが入ると、並列処理イベントの【射的弾丸管理】が始動する。まずプレイヤーのX座標とY座標を取得する。そして発射ボタン(今回はBボタン)が押されている状態という【条件分岐】を作る。その中でさらに条件分岐【弾丸残りが1以上】の場合。これは【弾丸残り】という変数を作り、最初の自動実行イベントで予め3を代入しておく。ここに代入した数が、同時にマップに出現可能な弾丸の最大数となる。
そしてスイッチを3つ、【弾丸1】【弾丸2】【弾丸3】を用意。先の条件が揃った際、それぞれのスイッチが入っているか否かを条件に、どの弾丸を発射するか決める。発射位置は、初めに取得したプレイヤーのY座標のみ1減算する。イベントの位置設定を変数【プレイヤーX】【プレイヤーY】で指定すれば、プレイヤーの前方(1マス上方向)に弾丸イベントが設定される。最後に弾丸のスイッチを入れると、イベントが出現する。弾丸発射になった時に、変数の【弾丸残り】を減算1する。
!!弾丸1~3!!
弾丸の並列処理イベントは、【このイベントのマップX及びY】をそれぞれの変数に代入する処理を最上部に設定。つまり弾丸の数が3つなら最低6つは座標用の変数を用意する。同時にターゲット用の座標変数についても、ターゲット数の2倍(つまり今回は同様に6つ)用意する。そして条件分岐を入れ子で指定。まずスイッチ【タゲAアニメーション中】でない時、次に【ターゲットA】が入っている(ターゲットAがマップ上に出現している)時、最後に変数【この弾丸座標とターゲットA座標】が一致する時。座標の確認は長くなるが条件分岐タブ4つ目のスクリプトに「$game_variables[77] == $game_variables[112] && $game_variables[78] == $game_variables[113]」と書けば、一つに収まる。
上記の3条件が満たされた段階で、コモンイベント【タゲA命中】を発動。内容は、スイッチ【タゲAアニメーション中】を入れ、【タゲAの属性】という変数により点数を加算あるいは減算させる。たとえば属性が10以下だとオーク、11~15はゴースト、20以上は市民、という具合に判定させている。次にアニメーションの表示をターゲットAにウエイト指定で実行。最後に、【タゲAアニメーション中】と【ターゲットA】のスイッチをそれぞれ解除する。
このコモンイベントの後、弾丸は変数【弾丸残り】に1を加算し、件の【弾丸(1~3のどれか)】スイッチを解除する。同じように【タゲBアニメーション中】【タゲCアニメーション中】についても、同様の手順を踏む。
その後、その弾丸の座標のタイルID(Layer3)を取得する。初めに載せた画像の場合、プレイヤーの前にある柵は、ID481番である。そのため、【タイルIDが481でない時】の条件分岐をつくり、更に条件分岐のスクリプト【!$game_player.passable?($game_variables[77], $game_variables[78], 8)】を設定。このスクリプトは、プレイヤーがその座標を移動可能かどうかを調べるもので、この場合だとX座標が変数77、Y座標が変数78の上方向が、「プレイヤーにとって」移動可能かどうかを判別する。
※イベントを基準に調べると、すり抜けのために全箇所移動可能になり、タイルID481を除外しないと弾丸を発射した瞬間に条件が満たされてしまう。
上記2条件が満たされている場合も、ターゲットに命中した時と同様、【弾丸残り】に1を加算し、該当する弾丸のスイッチを解除する。
以上の条件文の後に、【移動ルートの指定】このイベント上に移動(ウエイト無し)を設定。
!!射的タゲ管理!!
今度は、ターゲット(的、パネル)が画面の何処に出現するかを指定するためのイベント。まず条件分岐のスイッチ【タゲAアニメーション中】でない時、更に条件スイッチで【ターゲットA】が入っていない時。
この2条件が満たされている場合、変数【タゲA属性】に乱数0~25を代入。これにより、これから出現するターゲットAのグラフィックが決まる。次にラベル【タゲA座標】を設定。他のターゲットと同じ座標に表れるのを防ぐためだ。そして変数にターゲットAのX座標、Y座標をそれぞれ乱数で指定する。この乱数の範囲が、出現する可能性のある範囲となる。もし射的のステージが複数ある場合、変数【射的ステージ】を用いてそれぞれの場合に座標を指定する。
条件分岐タブ4つ目のスクリプトに【$game_variables[112] + $game_variables[113] == $game_variables[114] + $game_variables[115]】と指定する。これは、変数112(タゲAのX座標)と変数113(タゲAのY座標)を足した数字が、変数114と115(タゲBのXY座標)を足した数字とイコール(同じ)時、という条件。これが満たされる場合、ターゲットAとBが、重なって現れてしまう可能性があるので、ラベルジャンプ【タゲA座標】を指定し、座標を再計算させる。
※あくまで座標の合算を比較しているため、「x,y」で言うと例えば「4,12」と「12,4」は、マップ上で違う場所だが、上記の例では同じになる。しかし、なるべく簡略化したかった(条件文を1行で済ませたかった)ため、このような記述にした。
さて、先の条件分岐に当て嵌まらなければ、スイッチ【ターゲットA】を入れ、【イベントの位置設定】でターゲットAを先ほど代入した変数の位置に指定する。
同様の処理を、【ターゲットB】【ターゲットC】の分も作成する。
!!ターゲットA~C!!
出現条件はスイッチ【ターゲットA】が入っている時、足踏み無し、すり抜け任意、向き固定任意で設定。イベントページは、変数【タゲA属性】に依存する。今回の場合だと、スイッチ【ターゲットA】及び変数【タゲA属性】がxx以上という指定で、ターゲット毎に9ページ使用している。例えばその属性の数値が10以上だと悪魔にしているので、2ページ目には変数10以上という指定がされる。属性の数値は0~25にしたため、26分の10の確率(0~9)で、オークが選ばれる。
ページ毎に、自律移動のタイプをカスタムにし、移動ルートを設定する。ウエイト60、スイッチ【ターゲットA】OFF、スイッチ【タゲAアニメーション中】OFFにすれば、1秒(60フレーム)経過すると自動的に消え、再び別の場所にターゲットが現れるようになる。もちろん、消える前に弾丸を当てることが出来たら、その時も強制的に消えて別の場所に出現する。
得点の高いグラフィックは、この移動ルートのウエイト時間を短く設定すればいい。ちなみにゴーストをウエイト30にしたら、結構運ゲーになった。かといって60だと、そこそこ余裕を持って倒せるので、参考までに。
!!終了!!
とりあえずこんな感じ。もっと手を加えれば、弾丸の消える判定をプレイヤーの移動可否にしていることから、射的コースによって、弾丸を阻害する岩がランダムで出現する、というギミックは作りやすそう。ただ一回組んだものをまた作り直すのが面倒なので、俺はやらない。写真右のマップが上級コースということにして、マップを少し広くしてある。あとは何も変化無し。そうそう、得点などのウインドウに関しては、スクリプトのWindow_Goldを改変したWindow_Shatekiを作り、射的スタートのスイッチが入った時に並列処理で$windowに指定している。ウインドウに関しては、faida様のブログ「点線上の文字の羅列」のこのページに、詳しい作り方が載っている。俺の環境だと「$window.dispose」の直後に「$window = nil」を実行している。
それにしてもあれだなぁ。飽きてきたなぁ。もうそろそろドラクエ10のバージョンアップだし、また戻ろうかなぁ。なんて思い始めている今日この頃、暑いね。
※コメント投稿者のブログIDはブログ作成者のみに通知されます