前回、「剣を振って敵を攻撃する」「敵とNPCを区別する」というアクションRPGの基本をつくりました。
つまり、基本的な近距離攻撃をつくったわけです。
https://donichi-game.com/howto-arpg01/
今回は一歩進んで遠距離攻撃(飛び道具)である「矢」をつくっていきましょう。
画像の用意がラクなので「矢」のような棒を撃つようにしていますが、赤い光の球にして火の魔法と言うのもアリですね。
基本的な「矢」の考え方
イメージをウディタ的表現に置き換える
むずかしい処理に挑むには、やるべきことの整理から入りましょう。
単純に考え直す、と言ってもよいですね。
つまり、脳内イメージ(やりたいこと)を、ウディタで再現するにはどういう手順が必要なのか(実際のイベント処理)に置き換えるのです。
今回の場合は、次のようになるでしょう。
【イメージ】ボタンが押されたら、矢を発射する
↓
【ウディタ的表現】「矢」のイベントを主人公の位置にワープさせ、移動の命令
【イメージ】矢が敵にあたったら、敵がダメージを受ける
↓
【ウディタ的表現】「矢」の座標を監視。敵イベントと同じ座標に入ったらダメージ処理
イメージを上のような「ウディタ的表現」に置き換えられれば、だいたいのコードの流れは見えてくることでしょう。
さらにコモンイベントに置き換える
ウディタ的表現に言い換えられたら、注釈(コメント)としてコモンイベントのなかに箇条書きします。
その項目のひとつひとつを実際のイベント処理に変えていけばよいですね。
シンプルに考えれば、シンプルなコードで実現できましたね。
ちなみに矢イベントの設定はこうです。
シンプルさゆえの留意点
上の画像の座標チェック方法では、矢イベントのIDが敵イベントのIDより大きくないとうまく行きません。
変数操作+で、矢イベントのいる座標にいる座標を調べているわけですから、先に矢イベント自身のIDが出てくると、同座標にいる敵を見つけられなくなるのですね。
〇 矢IDが1、敵IDが0
× 矢IDが1、敵IDが2
変数操作+でのイベントチェックはIDの小さい方が先に出てくる仕様なので、上の例のようにIDによっては想定通りに動かないケースが出てくるのです。
力技で解消するなら、当たり判定コモンを下図のようにいじる感じでしょうか。
回数ループを使って、ID0番から順番に「矢イベントとは違うイベントだけど、矢イベントと同じ座標にいるイベント」を探しています。
ループ回数が100なのは仮です。
1マップに置くイベントが50も行かないなら、ループ回数も50弱でOKですね。
コモンイベントでマップイベントを扱うときの注意点
コモンイベントはすべてのマップで使いまわしが効くものです。
自作システムを作り込めば作り込むほど、「マップイベントはコモンイベントを呼び出すだけ」、なんてことにもなるのではないでしょうか。
そのほうが便利なわけですが、アクションRPGなどの場合は注意が必要。
マップ1で「矢イベント」を動かす際にはうまくいくのに、マップ2になると関係ないイベントが代わりに矢のように動いたりしてしまいます。
おなじ矢イベントのつもりでも、マップごとに「矢イベントのID」が違ってくるので起こる問題ですね。
対策その1:すべてのマップでIDをそろえる
書いたまんまですね。
必ず、すべてのマップで「矢はID1番のイベントにする!」とルールを決めて守ってしまえば、コモンイベントのほうでは「ID1番を動かす」と指示するだけでOK。
対策その2:影番号指定を使う
こちらはARPG講座の第1回とおなじ考え方ですね。
影番号に「矢」というステータスを作ってしまうのです。矢イベントのIDが必要になったとき(矢イベントを動かしたいとき)、マップイベントをざっとサーチして「矢の影番号」を持つイベントを探してくるのです。
対策その1よりは少々処理が増えますが、マップイベントはたびたび増減してID管理がむずかしいものです。処理の重さに余裕があるなら、ある程度の手間(矢イベントの場所探し)はプログラム(コモンイベント)に任せてしまうのもよいかもしれません。
このコモンで取得できた番号のイベントに、移動命令や座標取得をかければOK。
発展編・ピクチャで矢を表現する
マップイベントで矢を管理する場合、「弾数」(矢数)がネックになってきます。
矢のマップイベントを置いた数しか、同時に矢を撃てないわけです。
だからってコピペで矢のマップイベントを10個も20個もおいてしまうと、エディター画面がたいへんなことになってきますね。
そこで出てくるのが、ピクチャによる矢の表現です。
(今回の講座は一度に一射のみ仕様としていますので、複数射ちがしたい場合は各自のアレンジが必要です)
ピクチャで「矢」を表現する場合の長所と短所
ピクチャで矢を表現するのであれば、マップイベントを設置することなく、100個でも200個でも打ち放題です(処理負荷を気にしなければ)。
ひとまず一射だけできるものとして作り直すなら、「矢イベントのワープ(と移動)」を「矢ピクチャの描画(と移動)」に置き換えです。ピクチャなら回転(角度の指定)もできますので、用意する画像も一方向だけでOK。
ひと手間、加える必要があるのは「矢ピクチャと敵マップイベントの重なりの判定」です。
矢ピクチャの座標判定のやり方
数十個以上の矢(弾)を撃つのは、ARPGよりもむしろSTG(シューティングゲーム)ですね。
STGなら、敵キャラもピクチャで表現するほうが合理的っぽいので、ピクチャとピクチャの重なり判定をやっていくことになりそうです。
でも今回はシンプルなアクションRPGですから、シンプルに考えましょう。
画面座標をマス座標に変換すれば、矢ピクチャが今いるマップのX,Y座標(マス座標)がわかります。
・変数操作+で矢ピクチャの座標をチェック(これが画面座標)。
・画面座標をマス座標に変換。
・そのマス座標に攻撃可能なマップイベントが居れば、ダメージ処理。
コモンイベントとして書き起こしてみると、こんな感じに。
発展編なので、かなりのざくっとした説明で通しております。