【ウディタ】「直線的に往復・巡回移動するキャラ」を作る

メタルメサイアの制作の合間にウディタを使ってドットイートゲームを作っています。ドットイートゲームでは敵や仕掛けの移動アルゴリズムが肝になりますが、まず基本的な動きとしてタイトルのような動きを実現するコモンを作りました。今回はそれについて書きます。

※注:この記事は「本当は怖い並列実行」の前に書いた記事ですが、都合上今回掲載することにしました。先の記事に書いた通り並列実行が絡むとバグが頻発したので、今作っているドットイートゲームではこのコモンイベントを使わず、イベントのカスタム移動ルートを使って作っています。下記の内容は参考程度にご覧ください。

イベントとコモンイベントの仕様

  • 実装する移動方法は「直線往復移動」「巡回移動(右回り・左回り)」の2種類
  • このコモンは並列実行イベントから呼び出して利用する。
  • 直線往復移動は、壁に当たるまで直線移動し、壁に当たったら向きを反転して移動を続ける。往復の方向(上下または左右)はキャラの最初の向きにより決定する。
  • 巡回移動は、壁に当たるまで直線移動し、壁に当たったら向きを右または左に方向転換して移動を続ける。
  • 壁に当たったかどうかの判定は、移動の前後にキャラの座標を取得し、それを比較して変化があったかどうかで判定する(変数操作+の「移動中?」だと、壁に当たって動いていなくても移動コマンドが実行中なら移動中扱いになるため、うまくいかない)。

移動のイメージは次の図の通りです。

直線往復移動

直線往復移動

巡回移動

巡回移動(右回り)

なお、今回作ったコモンでは、地形によっては巡回移動が直線往復移動になってしまう場合があります。

コモンイベントの内容

このコモンイベントのコードは下記のとおりです。

▼ 移動速度を指定
■条件分岐(変数): 【1】 CSelf1[移動速度] が 0 と同じ 【2】 CSelf1[移動速度] が 1 と同じ 【3】 CSelf1[移動速度] が 2 と同じ 
-◇分岐: 【1】 [ CSelf1[移動速度] が 0 と同じ ]の場合↓
 |■動作指定:このイベント / 移動速度を設定 => 0
 |■
-◇分岐: 【2】 [ CSelf1[移動速度] が 1 と同じ ]の場合↓
 |■動作指定:このイベント / 移動速度を設定 => 1
 |■
-◇分岐: 【3】 [ CSelf1[移動速度] が 2 と同じ ]の場合↓
 |■動作指定:このイベント / 移動速度を設定 => 2
 |■
-◇上記以外
 |■条件分岐(変数): 【1】 CSelf1[移動速度] が 3 と同じ 【2】 CSelf1[移動速度] が 4 と同じ 【3】 CSelf1[移動速度] が 5 と同じ 
 |-◇分岐: 【1】 [ CSelf1[移動速度] が 3 と同じ ]の場合↓
 | |■動作指定:このイベント / 移動速度を設定 => 3
 | |■
 |-◇分岐: 【2】 [ CSelf1[移動速度] が 4 と同じ ]の場合↓
 | |■動作指定:このイベント / 移動速度を設定 => 4
 | |■
 |-◇分岐: 【3】 [ CSelf1[移動速度] が 5 と同じ ]の場合↓
 | |■動作指定:このイベント / 移動速度を設定 => 5
 | |■
 |-◇上記以外
 | |■動作指定:このイベント / 移動速度を設定 => 6
 | |■
 |◇分岐終了◇
 |■
◇分岐終了◇
▼ 
▼ 一歩進む前と後の座標を取得し、進めたかどうかを判断する
■変数操作+: CSelf10[元のX座標] = このマップイベント の X座標(標準)
■変数操作+: CSelf11[元のY座標] = このマップイベント の Y座標(標準)
▼ 
■動作指定:[ウェイト] このイベント / 一歩前進
▼ 
■変数操作+: CSelf12[後のX座標] = このマップイベント の X座標(標準)
■変数操作+: CSelf13[後のY座標] = このマップイベント の Y座標(標準)
▼ 
■条件分岐(変数): 【1】 CSelf0[モード] が 1 と同じ 【2】 CSelf0[モード] が 2 と同じ 【3】 CSelf0[モード] が 3 と同じ 
-◇分岐: 【1】 [ CSelf0[モード] が 1 と同じ ]の場合↓
 |▼ 往復
 |■条件分岐(変数): 【1】 CSelf10[元のX座標] が CSelf12[後のX座標] と同じ 
 |-◇分岐: 【1】 [ CSelf10[元のX座標] が CSelf12[後のX座標] と同じ ]の場合↓
 | |■条件分岐(変数): 【1】 CSelf11[元のY座標] が CSelf13[後のY座標] と同じ 
 | |-◇分岐: 【1】 [ CSelf11[元のY座標] が CSelf13[後のY座標] と同じ ]の場合↓
 | | |■動作指定:このイベント / 右に1つ回転 / 右に1つ回転
 | | |■
 | |◇分岐終了◇
 | |■
 |◇分岐終了◇
 |■
-◇分岐: 【2】 [ CSelf0[モード] が 2 と同じ ]の場合↓
 |■
-◇分岐: 【3】 [ CSelf0[モード] が 3 と同じ ]の場合↓
 |▼ 右回り
 |■条件分岐(変数): 【1】 CSelf10[元のX座標] が CSelf12[後のX座標] と同じ 
 |-◇分岐: 【1】 [ CSelf10[元のX座標] が CSelf12[後のX座標] と同じ ]の場合↓
 | |■条件分岐(変数): 【1】 CSelf11[元のY座標] が CSelf13[後のY座標] と同じ 
 | |-◇分岐: 【1】 [ CSelf11[元のY座標] が CSelf13[後のY座標] と同じ ]の場合↓
 | | |■動作指定:このイベント / 右に1つ回転
 | | |■
 | |◇分岐終了◇
 | |■
 |◇分岐終了◇
 |■
-◇上記以外
 |■条件分岐(変数): 【1】 CSelf0[モード] が 4 と同じ 
 |-◇分岐: 【1】 [ CSelf0[モード] が 4 と同じ ]の場合↓
 | |▼ 左回り
 | |■条件分岐(変数): 【1】 CSelf10[元のX座標] が CSelf12[後のX座標] と同じ 
 | |-◇分岐: 【1】 [ CSelf10[元のX座標] が CSelf12[後のX座標] と同じ ]の場合↓
 | | |■条件分岐(変数): 【1】 CSelf11[元のY座標] が CSelf13[後のY座標] と同じ 
 | | |-◇分岐: 【1】 [ CSelf11[元のY座標] が CSelf13[後のY座標] と同じ ]の場合↓
 | | | |■動作指定:このイベント / 左に1つ回転
 | | | |■
 | | |◇分岐終了◇
 | | |■
 | |◇分岐終了◇
 | |■
 |-◇上記以外
 | |▼ 停止
 | |■動作指定:このイベント / 移動速度を設定 => 0
 | |■
 |◇分岐終了◇
 |■
◇分岐終了◇

この仕組みの問題点

イベントの実行条件を並列実行にするので、このままではプレイヤーに接触したときの処理が実行できません。そこで、イベントの接触条件を使うのではなく、自前で接触判定コモンを作ることで対処します。これについては次回「ウディタでイベント同士の接触判定コモンを作る」で紹介したいと思います。