RPGツクールと数学のブログ

RPGツクールと数学についてのブログです。

アクションRPGの基礎(RPGツクールMV)(応用編 敵が弾を放つ)

↓前回の記事によって、敵に行動パターンを持たせられるようになりました。

fermiumbay13.hatenablog.com

今回は、敵が弾を放ってくるイベントを作成してみます。以下の流れになります。

1. 敵の弾イベントを新規作成する
2. 敵の弾を放つコモンイベントを新規作成する
3. 敵の行動パターンにそれを組み込む

敵の弾イベントを新規作成する

敵の弾は、指定された向きに一直線に進み、主人公に当たったら主人公がダメージを受け、どこかにぶつかったら(=これ以上弾が進まなくなったら)消える、というものです。今回は、弾の向きを表すためのスクリプト用変数として、新しくbulletDictという変数を追加します。コモンイベント「初期化」に以下の◇の行を追加します。

スクリプト:enemyDamage = new Array(999);
:     :for(var i = 0; i < 999; i++){
:     : enemyDamage[i] = 0;
:     :}
スクリプト:enemyTime = new Array(999);
:     :for(var i = 0; i < 999; i++){
:     : enemyTime[i] = 0;
:     :}
スクリプト:bulletDict = new Array(999);
:     :for(var i = 0; i < 999; i++){
:     : bulletDict[i] = 0;
:     :}
スクリプト:for(var eventID = 1; eventID <= 999; eventID++){
:     : var mapID = this._mapId;
:     : $gameSelfSwitches.setValue([mapID, eventID, "A"], false);
:     : $gameSelfSwitches.setValue([mapID, eventID, "B"], false);
:     :}
◆変数の操作:#0006 ため量 = 0
◆スイッチの操作:#0001 キー入力受付 = ON
◆スイッチの操作:#0003 主人公被ダメージ無敵 = OFF

これは、下が2、左が4、右が6、上が8、を表す変数です。後で使うので、前回のenemyTimeと同様に初期化イベントで初期化するようにしておきます。

次に、敵の弾イベントを作成します。敵の弾は一つではなく、放たれる度にどんどん新規生成されていくものですから、新しいイベントをどんどん生成するような処理が必要になります。トリアコンタンさんの以下のプラグインを利用させていただいて、イベントを動的生成する方法で実装します。

triacontane.blogspot.com

なお、プラグインの利用には別途、テンプレートイベントプラグインも使用します。これは本講座のサンプルプロジェクトでも使用しているので、それを参考に利用いただいて構いません。

triacontane.blogspot.com

二つのプラグインを導入しておきます。

テンプレートマップと呼ばれる、テンプレートイベントを配置するマップに、今回新規作成する敵の弾イベントを作成しておきます。

敵の弾イベントは、以下のように並列処理で動くイベントとして作成します。指定された方向に向けて移動し続け、主人公に当たったら主人公がダメージ、弾がこれ以上移動できないときに消滅、という動作をします。名前を「敵の弾」としておきます。(グラフィックは明らかに、弾じゃなくて岩だけど気にしないでね^^;)

イベントの実行内容は以下です。けっこう行数があります……

◆変数の操作:#0021 前回x = このイベントのマップX
◆変数の操作:#0022 前回y = このイベントのマップY
◆条件分岐:スクリプト:bulletDict[this.character(0)._eventId - 1] == 2
  ◆移動ルートの設定:このイベント (飛ばす, ウェイト)
  :        :◇下に移動
  ◆
:分岐終了
◆条件分岐:スクリプト:bulletDict[this.character(0)._eventId - 1] == 4
  ◆移動ルートの設定:このイベント (飛ばす, ウェイト)
  :        :◇左に移動
  ◆
:分岐終了
◆条件分岐:スクリプト:bulletDict[this.character(0)._eventId - 1] == 6
  ◆移動ルートの設定:このイベント (飛ばす, ウェイト)
  :        :◇右に移動
  ◆
:分岐終了
◆条件分岐:スクリプト:bulletDict[this.character(0)._eventId - 1] == 8
  ◆移動ルートの設定:このイベント (飛ばす, ウェイト)
  :        :◇上に移動
  ◆
:分岐終了
スクリプト:this.character(0).unlock();
◆変数の操作:#0023 今回x = このイベントのマップX
◆変数の操作:#0024 今回y = このイベントのマップY
◆条件分岐:前回x = 今回x
  ◆条件分岐:前回y = 今回y
    ◆イベントの一時消去
    ◆イベント処理の中断
    ◆
  :分岐終了
  ◆
:分岐終了
◆変数の操作:#0002 攻撃x = このイベントのマップX
◆変数の操作:#0003 攻撃y = このイベントのマップY
◆条件分岐:スクリプト:bulletDict[this.character(0)._eventId - 1] == 2
  ◆変数の操作:#0003 攻撃y += 1
  ◆
:分岐終了
◆条件分岐:スクリプト:bulletDict[this.character(0)._eventId - 1] == 4
  ◆変数の操作:#0002 攻撃x -= 1
  ◆
:分岐終了
◆条件分岐:スクリプト:bulletDict[this.character(0)._eventId - 1] == 6
  ◆変数の操作:#0002 攻撃x += 1
  ◆
:分岐終了
◆条件分岐:スクリプト:bulletDict[this.character(0)._eventId - 1] == 8
  ◆変数の操作:#0003 攻撃y -= 1
  ◆
:分岐終了
◆コモンイベント:対象者取得(敵→主人公)

新しい変数をいくつか追加していますが、番号はなんでも構いません。

上記の説明をしていきます。まず、弾の前回座標を表す変数として、変数21番「前回x」、変数22番「前回y」に、それぞれ弾の現在座標を代入します。そして、さっき追加したbulletDict変数が2,4,6,8のときに応じて分岐させ、その方向に一歩移動させます(bulletDict変数に向きを代入する処理は、この後「弾を放つ」イベントを作成するときに実装します)。

this.character(0).unlock(); は、移動の際に止まってしまわないようにするおまじないです。右記の内容をご参照ください:アクションRPGの基礎(RPGツクールMV)(3/4) - RPGツクールと数学のブログ

移動後の座標を、変数23番「今回x」、変数24番「今回y」に、それぞれ代入します。ここで、前回座標と今回座標を比べてみて完全一致する場合、それは弾が移動できなかったことを表わすので、弾イベントを消去します。

消去されなかった場合は、前回作った「剣を振る(敵)」イベント等と同様に、主人公への当たり判定を行います。「攻撃x」「攻撃y」に弾の座標を代入して、向いている方向に一歩進ませたところで当たり判定をします(弾が向かっている方に主人公がいたら衝突、という流れです)。これで、弾のイベントは作成完了です。

「弾を放つ(敵)」を作成する

「剣を振る(敵)」と同様にして、「弾を放つ(敵)」を新規作成しましょう。コモンイベント「弾を放つ(敵)」を以下の内容で作成します。トリガーは「なし」でOKです。

◆変数の操作:#0002 攻撃x = このイベントのマップX
◆変数の操作:#0003 攻撃y = このイベントのマップY
◆変数の操作:#0025 敵の向き = このイベントの向き
◆条件分岐:このイベントが下を向いている
  ◆変数の操作:#0003 攻撃y += 1
  ◆
:分岐終了
◆条件分岐:このイベントが左を向いている
  ◆変数の操作:#0002 攻撃x -= 1
  ◆
:分岐終了
◆条件分岐:このイベントが右を向いている
  ◆変数の操作:#0002 攻撃x += 1
  ◆
:分岐終了
◆条件分岐:このイベントが上を向いている
  ◆変数の操作:#0003 攻撃y -= 1
  ◆
:分岐終了
スクリプト:var eventName = "敵の弾";
:     :var mapId = this._mapId;
:     :var eventId = $gameMap.getEventIdSequence();
:     :var originalEventId = DataManager.searchDataItem($dataTemplateEvents, 'name', eventName).id;
:     :var x = $gameVariables.value(2);
:     :var y = $gameVariables.value(3);
:     :var isTemplate = true;
:     :var event = new Game_PrefabEvent(mapId, eventId, originalEventId, x, y, isTemplate);
:     :$gameMap._lastSpawnEventId = eventId;
:     :$gameMap._events.push(event);
:     :bulletDict[eventId - 1] = $gameVariables.value(25);

変数25番「敵の向き」を追加しました。さっきの「敵の弾」と同様、向きに応じて「攻撃x」「攻撃y」を一歩進ませます。その次はスクリプトの長文があります。スクリプトの部分だけ以下に再掲します。

var eventName = "敵の弾";

var mapId = this._mapId;

var eventId = $gameMap.getEventIdSequence();

var originalEventId = DataManager.searchDataItem($dataTemplateEvents, 'name', eventName).id;

var x = $gameVariables.value(2);

var y = $gameVariables.value(3);

var isTemplate = true;

var event = new Game_PrefabEvent(mapId, eventId, originalEventId, x, y, isTemplate);

$gameMap._lastSpawnEventId = eventId;

$gameMap._events.push(event);

bulletDict[eventId - 1] = $gameVariables.value(25);

これは、イベント動的生成プラグインを用いて「敵の弾」イベントを生成する処理です。生成だけであればプラグインコマンドで済むのですが、敵の向きをbulletDict変数に代入するために、生成したイベントのIDが必要になりますので、プラグインコマンドの代わりに上記のスクリプトで代用しています。

大部分の意味については割愛します。プラグインコマンドの呼び出しをスクリプトで代替しているだけです。

編集する必要がある部分だけ以下に記載していきます(その他の箇所はコピーで構いません)。

【1行目】
var eventName = "敵の弾";

生成するイベント名をここで記入します。「敵の弾」イベントを生成するので、「敵の弾」と記載しています。

【5,6行目】
var x = $gameVariables.value(2);
var y = $gameVariables.value(3);

「攻撃x」が変数2番、「攻撃y」が変数3番なので、上記のかっこの中にそれぞれ2,3と記載しています。変数の番号が異なる場合はここだけ変更ください。

【11行目】
bulletDict[eventId - 1] = $gameVariables.value(25);

生成したイベントのbulletDict変数に、変数25番「敵の向き」の値を代入する処理です。変数の番号が異なる場合は、かっこ内の数値だけ変更ください。

以上で敵の弾を放つ攻撃パターンが完成しました。

敵の行動パターンに組み込む

あとは、作成した「弾を放つ(敵)」を呼び出すよう、敵の1ページ目に加えるだけです。

◆条件分岐:スクリプト:enemyTime[this.character(0)._eventId - 1] == 60
  ◆コモンイベント:弾を放つ(敵)
  ◆
:分岐終了
◆条件分岐:スクリプト:enemyTime[this.character(0)._eventId - 1] >= 60
  ◆スクリプト:enemyTime[this.character(0)._eventId - 1] = 0;
  ◆
:分岐終了
スクリプト:enemyTime[this.character(0)._eventId - 1]++;

上記は、1秒に1回、弾を放つという行動パターンになります。

弾(っていうか岩)を放ってきているのが確認できるでしょう。対象者取得の処理を変えてやれば、逆に主人公が弾を放つ処理も作れると思います。色々できそうですね。