RPGツクールMZでFC版ウルティマ3風の影を再現する
はじめに
ファミコン版の「ウルティマ3恐怖のエクソダス」には、プレイヤーの位置によって視界がひらけていく独特の影システムがありました。
FC「ウルティマ 恐怖のエクソダス」
パーティの移動に伴い、視界が開けていく。ドラクエにない、凝った仕様。#ウルティマ pic.twitter.com/3aIMRaPuZA— S_YT (@kky_a1b2) July 27, 2020
この影システム、フィールドやダンジョンでやるだけならまだしも、街や城の安全エリアで有効なため、あまり操作性の良くない機能ではあったのですが、かっこいいのでいずれ自作品でも実装したいと思っていました。
(続編のファミコン版「ウルティマ4聖者への道」ではドラクエ風の仕様(屋根の下に入ると視界が切り替わるアレ)に切り替わってしまいました)
「Elona」にもプレイヤーを起点にマス目ごとに段階的に影がかかっていく表現がありますが、ああいった表現も良いですよね。
今回、RPGツクールMZを使ってあれこれやっていたところでしたので、「特にメリットはないけどかっこいいからヨシ!」の精神でいよいよ実装してみようとした次第です。
ツクールMZにて実装しているものの、ウディタとかSteam版RPGツクール2003とかでも同じことはできると思います。むしろウディタのほうが楽まである。
思考あれこれ
よく見ていくと、判定エリアを上下左右+斜め4方向に分け、
中心のプレイヤーから見て壁がある以降のマスを影としている(だろう)ということが何となく分かりました。
(ここにたどり着くまでに既に数週間悩む)
こういう基準で判定しているような気がしてきた(画像2枚目)。 pic.twitter.com/giEjpHrlCr
— sep (@Spare_Blade) July 4, 2021
処理のイメージ
そして考えたのが下記。
最初は画面内の全マスを判定して各マスごとに1つずつ影を置いていく覚悟をしていたのですが、縦横斜めのに伸びた影ピクチャをそれぞれ用意して、壁があるマス以降にその長い影ピクチャを貼り付けていく感じの処理で考えました。
プレイヤーを中心に、エリアをA~Hに分ける。
・A~D:直線の影の判定エリア
・E~H:斜めの影の判定エリア
図のマス目内の数字の順番で判定を行っていく。
(※画面サイズはMZデフォルトから20x15に変更しています。またツクール2000時代のノリで「20x15の時はプレイヤー位置は中央にならずに左に1個ずれるだろう」と当初思っていたので、右方向に1列多くなっています(実際は中央配置でかつ左右の端は0.5マスずつ表示となる))
A~Dエリアの処理
▼矢印の方向に、プレイヤーから遠ざかっていく形で1マスずつ判定。
▼対象マスが壁だった場合、以降を影とする。
(壁マスを基準に影ピクチャを表示)
▼影を表示するか、判定対象が画面外に行ったところ(→対象方向に壁なし)で処理終了。
E~Hエリアの処理
▼矢印の方向に、プレイヤーから遠ざかっていく形で1マスずつ判定。
(ex.エリアEのNo.5のマスなら5を起点に左上のマスを1つずつ判定)
▼対象マスが壁だった場合、以降を影とする。
(壁マスを基準に影ピクチャを表示)
▼影を表示するか、判定対象が画面外に行ったところ(→対象方向に壁なし)で処理終了。
▼次の数字のマスに対象を移し、上記を繰り返す。
ただし、上記の処理だけだと下図のような不都合が出るため、斜めの影判定の際には追加で処理を入れています。
(追加する処理)
▼斜め方向に判定していく際の一番最初のマス(→数字が記載されているマス)を判定する際、対象が壁だった場合、そのマスの座標を記録する。
▼次の上記マスを判定する際、対象よりもプレイヤー寄りに壁があった場合(→対象マス>壁マス>プレイヤー位置)、以降はすべて影とする。
▼それ以外の場合、通常の斜め用判定処理を行う。
この追加処理を入れると、影の付き方が微妙にウルティマ3とは違ってきてしまうのですが、2週間考えてこれ以外の処理を思いつかなかったので断念します。
事前準備
◆ピクチャの上限を増やす
80枚近く使うことになるので。
MZのデフォルトである上限100枚の中でなんとかするのは嫌なので、ピクチャ表示上限を増やします。
ツクール2000を使っていた側からすると当時は50枚が上限だったので倍の100枚使えるだけでも大変ありがたい訳ではあるのですが。。
→「rmmz_objects.js」内の「Game_Screen.prototype.maxPictures」の値を変更する。
(今回は100→200へ変更)
なお、エディター上からはデフォルトの100までしか入力を受け付けてくれないので、101以降を使用する場合はスクリプトから直接ピクチャの表示を行う必要があります。
◆「VisuMZ_0_CoreEngine.js」を追加する
表示したピクチャをマップスクロールに連動させるために必要。
何か他にも色々機能があるみたいですけれど私には調べてもよくわかりませんでした(いかがでしたか?)。
上記を導入することで、ファイル名戦闘に「!」を付けたピクチャはマップのスクロールに連動することができるようになります。
◆影用の画像を作る
↓こんな感じで、8方向分の影ピクチャを作成します。
素材化はしないので、真似する場合は自分でいい感じになんとかしてください。
実装したイベント(ベタ貼り)
あれこれイメージを記載するより、実際に組んだイベントを貼り付けたほうが早いという。。
記事の構成的に最後になりましたが、最初にこれだけ貼り付けておくのでも良かったかも。
【メイン処理】
◆注釈:================================================== ◆注釈:【初期処理】 ◆注釈:================================================== ◆変数の操作:#0132 影用・壁地形ID = 6 ◆変数の操作:#0135 影用・ピクチャ不透明度 = 50 ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = OFF ◆変数の操作:#0145 ◆↑-1壁だったY = 0 ◆変数の操作:#0146 ◆←-1壁だったX = 0 ◆変数の操作:#0147 ◆↑+1壁だったY = 0 ◆変数の操作:#0148 ◆→-1壁だったX = 999 ◆変数の操作:#0149 ◆↓-1壁だったY = 999 ◆変数の操作:#0150 ◆←+1壁だったX = 0 ◆変数の操作:#0151 ◆↓+1壁だったY = 999 ◆変数の操作:#0152 ◆→+1壁だったX = 999 ◆注釈:================================================== ◆注釈:【↑】 ◆注釈:================================================== ◆注釈:(共通設定) ◆変数の操作:#0128 影用・ピクチャID = 101 ◆コモンイベント:┗共通初期処理 ◆注釈:========== ◆変数の操作:#0130 影用・判定対象Y += -1 ◆ループ ◆指定位置の情報取得:影用・判定対象地形ID, 地形タグ, ({影用・判定対象X},{影用・判定対象Y}) ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆ループの中断 ◆ :分岐終了 ◆変数の操作:#0127 影用・ピクチャ座標Y += -48 ◆変数の操作:#0130 影用・判定対象Y += -1 ◆変数の操作:#0134 影用・判定対象画面Y += -1 ◆条件分岐:影用・判定対象画面Y ≤ -1 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆スクリプト:$gameScreen.showPicture($gameVariables.value(128),'!kage_1',0,$gameVariables.value(126),$gameVariables.value(127),100,100,$gameVariables.value(135),0) ◆注釈:================================================== ◆注釈:【↓】 ◆注釈:================================================== ◆注釈:(共通設定) ◆変数の操作:#0128 影用・ピクチャID = 103 ◆コモンイベント:┗共通初期処理 ◆注釈:========== ◆変数の操作:#0130 影用・判定対象Y += 1 ◆ループ ◆指定位置の情報取得:影用・判定対象地形ID, 地形タグ, ({影用・判定対象X},{影用・判定対象Y}) ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆ループの中断 ◆ :分岐終了 ◆変数の操作:#0127 影用・ピクチャ座標Y += 48 ◆変数の操作:#0130 影用・判定対象Y += 1 ◆変数の操作:#0134 影用・判定対象画面Y += 1 ◆条件分岐:影用・判定対象画面Y ≥ 16 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆スクリプト:$gameScreen.showPicture($gameVariables.value(128),'!kage_3',0,$gameVariables.value(126),$gameVariables.value(127),100,100,$gameVariables.value(135),0) ◆注釈:================================================== ◆注釈:【→】 ◆注釈:================================================== ◆注釈:(共通設定) ◆変数の操作:#0128 影用・ピクチャID = 102 ◆コモンイベント:┗共通初期処理 ◆変数の操作:#0126 影用・ピクチャ座標X += 24 ◆注釈:■■■ ↑ここだけこのイベントで座標を追加でずらしておかないと半マス影がずれる :注釈:■■■ :注釈:■■■ :注釈:■■■ :注釈: :注釈:■■■ ◆注釈:========== ◆変数の操作:#0129 影用・判定対象X += 1 ◆ループ ◆指定位置の情報取得:影用・判定対象地形ID, 地形タグ, ({影用・判定対象X},{影用・判定対象Y}) ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆ループの中断 ◆ :分岐終了 ◆変数の操作:#0126 影用・ピクチャ座標X += 48 ◆変数の操作:#0129 影用・判定対象X += 1 ◆変数の操作:#0133 影用・判定対象画面X += 1 ◆条件分岐:影用・判定対象画面X ≥ 22 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆スクリプト:$gameScreen.showPicture($gameVariables.value(128),'!kage_2',0,$gameVariables.value(126),$gameVariables.value(127),100,100,$gameVariables.value(135),0) ◆注釈:================================================== ◆注釈:【←】 ◆注釈:================================================== ◆注釈:(共通設定) ◆変数の操作:#0128 影用・ピクチャID = 104 ◆コモンイベント:┗共通初期処理 ◆注釈:========== ◆変数の操作:#0129 影用・判定対象X += -1 ◆ループ ◆指定位置の情報取得:影用・判定対象地形ID, 地形タグ, ({影用・判定対象X},{影用・判定対象Y}) ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆ループの中断 ◆ :分岐終了 ◆変数の操作:#0126 影用・ピクチャ座標X += -48 ◆変数の操作:#0129 影用・判定対象X += -1 ◆変数の操作:#0133 影用・判定対象画面X += -1 ◆条件分岐:影用・判定対象画面X ≤ -1 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆スクリプト:$gameScreen.showPicture($gameVariables.value(128),'!kage_4',0,$gameVariables.value(126),$gameVariables.value(127),100,100,$gameVariables.value(135),0) ◆注釈:================================================== ◆注釈:================================================== ◆注釈:================================================== ◆注釈:================================================== ◆注釈:================================================== ◆注釈:【↖】 ◆注釈:================================================== ◆変数の操作:#0128 影用・ピクチャID = 105 ◆注釈:↖(上に見ていく) ◆変数の操作:#0136 影用・判定対象ずらすX = 0 ◆変数の操作:#0137 影用・判定対象ずらすY = 0 ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = OFF ◆ループ ◆注釈:(共通設定) ◆コモンイベント:┗共通初期処理 ◆注釈:========== ◆変数の操作:#0129 影用・判定対象X += -1 ◆変数の操作:#0130 影用・判定対象Y += -1 ◆変数の操作:#0129 影用・判定対象X += 影用・判定対象ずらすX ◆変数の操作:#0130 影用・判定対象Y += 影用・判定対象ずらすY ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = OFF ◆ループ ◆指定位置の情報取得:影用・判定対象地形ID, 地形タグ, ({影用・判定対象X},{影用・判定対象Y}) ◆条件分岐:影・斜め用はじめの列フラグがOFF ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆条件分岐:影・斜め用はじめの列初回フラグがOFF ◆変数の操作:#0145 ◆↑-1壁だったY = 影用・判定対象Y ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = ON ◆ :分岐終了 ◆ :分岐終了 ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = ON ◆ :分岐終了 ◆条件分岐:影用・判定対象Y < ◆↑-1壁だったY ◆条件分岐:影用・ピクチャID ≠ 105 ◆変数の操作:#0126 影用・ピクチャ座標X += 48 ◆変数の操作:#0127 影用・ピクチャ座標Y += 48 ◆ループの中断 ◆ :分岐終了 ◆ :分岐終了 ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆ループの中断 ◆ :分岐終了 ◆変数の操作:#0126 影用・ピクチャ座標X += -48 ◆変数の操作:#0127 影用・ピクチャ座標Y += -48 ◆変数の操作:#0129 影用・判定対象X += -1 ◆変数の操作:#0130 影用・判定対象Y += -1 ◆変数の操作:#0133 影用・判定対象画面X += -1 ◆変数の操作:#0134 影用・判定対象画面Y += -1 ◆条件分岐:影用・判定対象画面Y < -1 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆変数の操作:#0138 影用・ピクチャずらすX = 影用・判定対象ずらすX ◆変数の操作:#0139 影用・ピクチャずらすY = 影用・判定対象ずらすY ◆変数の操作:#0138 影用・ピクチャずらすX *= 48 ◆変数の操作:#0139 影用・ピクチャずらすY *= 48 ◆変数の操作:#0126 影用・ピクチャ座標X += 影用・ピクチャずらすX ◆変数の操作:#0127 影用・ピクチャ座標Y += 影用・ピクチャずらすY ◆スクリプト:$gameScreen.showPicture($gameVariables.value(128),'!kage_5',0,$gameVariables.value(126),$gameVariables.value(127),100,100,$gameVariables.value(135),0) ◆変数の操作:#0128 影用・ピクチャID += 1 ◆変数の操作:#0136 影用・判定対象ずらすX += 0 ◆変数の操作:#0137 影用・判定対象ずらすY += -1 ◆条件分岐:影用・ピクチャID = 113 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆変数の操作:#0128 影用・ピクチャID = 113 ◆注釈:↖(左に見ていく) ◆変数の操作:#0136 影用・判定対象ずらすX = 0 ◆変数の操作:#0137 影用・判定対象ずらすY = 0 ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = OFF ◆スイッチの操作:#0008 影・斜め判定重複SKIPフラグ = OFF ◆ループ ◆注釈:(共通設定) ◆コモンイベント:┗共通初期処理 ◆注釈:========== ◆変数の操作:#0129 影用・判定対象X += -1 ◆変数の操作:#0130 影用・判定対象Y += -1 ◆変数の操作:#0129 影用・判定対象X += 影用・判定対象ずらすX ◆変数の操作:#0130 影用・判定対象Y += 影用・判定対象ずらすY ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = OFF ◆ループ ◆指定位置の情報取得:影用・判定対象地形ID, 地形タグ, ({影用・判定対象X},{影用・判定対象Y}) ◆条件分岐:影・斜め用はじめの列フラグがOFF ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆条件分岐:影・斜め用はじめの列初回フラグがOFF ◆変数の操作:#0146 ◆←-1壁だったX = 影用・判定対象X ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = ON ◆ :分岐終了 ◆ :分岐終了 ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = ON ◆ :分岐終了 ◆条件分岐:影用・判定対象X < ◆←-1壁だったX ◆条件分岐:影用・ピクチャID ≠ 105 ◆変数の操作:#0126 影用・ピクチャ座標X += 48 ◆変数の操作:#0127 影用・ピクチャ座標Y += 48 ◆ループの中断 ◆ :分岐終了 ◆ :分岐終了 ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆ループの中断 ◆ :分岐終了 ◆変数の操作:#0126 影用・ピクチャ座標X += -48 ◆変数の操作:#0127 影用・ピクチャ座標Y += -48 ◆変数の操作:#0129 影用・判定対象X += -1 ◆変数の操作:#0130 影用・判定対象Y += -1 ◆変数の操作:#0133 影用・判定対象画面X += -1 ◆変数の操作:#0134 影用・判定対象画面Y += -1 ◆条件分岐:影用・判定対象画面X < -2 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆変数の操作:#0138 影用・ピクチャずらすX = 影用・判定対象ずらすX ◆変数の操作:#0139 影用・ピクチャずらすY = 影用・判定対象ずらすY ◆変数の操作:#0138 影用・ピクチャずらすX *= 48 ◆変数の操作:#0139 影用・ピクチャずらすY *= 48 ◆変数の操作:#0126 影用・ピクチャ座標X += 影用・ピクチャずらすX ◆変数の操作:#0127 影用・ピクチャ座標Y += 影用・ピクチャずらすY ◆条件分岐:影・斜め判定重複SKIPフラグがOFF ◆スイッチの操作:#0008 影・斜め判定重複SKIPフラグ = ON ◆ :それ以外のとき ◆スクリプト:$gameScreen.showPicture($gameVariables.value(128),'!kage_5',0,$gameVariables.value(126),$gameVariables.value(127),100,100,$gameVariables.value(135),0) ◆変数の操作:#0128 影用・ピクチャID += 1 ◆ :分岐終了 ◆変数の操作:#0136 影用・判定対象ずらすX += -1 ◆変数の操作:#0137 影用・判定対象ずらすY += 0 ◆条件分岐:影用・ピクチャID = 123 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆注釈:================================================== ◆注釈:【↗】 ◆注釈:================================================== ◆変数の操作:#0128 影用・ピクチャID = 123 ◆注釈:↗(上に見ていく) ◆変数の操作:#0136 影用・判定対象ずらすX = 0 ◆変数の操作:#0137 影用・判定対象ずらすY = 0 ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = OFF ◆ループ ◆注釈:(共通設定) ◆コモンイベント:┗共通初期処理 ◆注釈:========== ◆変数の操作:#0129 影用・判定対象X += 1 ◆変数の操作:#0130 影用・判定対象Y += -1 ◆変数の操作:#0129 影用・判定対象X += 影用・判定対象ずらすX ◆変数の操作:#0130 影用・判定対象Y += 影用・判定対象ずらすY ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = OFF ◆ループ ◆指定位置の情報取得:影用・判定対象地形ID, 地形タグ, ({影用・判定対象X},{影用・判定対象Y}) ◆条件分岐:影・斜め用はじめの列フラグがOFF ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆条件分岐:影・斜め用はじめの列初回フラグがOFF ◆変数の操作:#0147 ◆↑+1壁だったY = 影用・判定対象Y ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = ON ◆ :分岐終了 ◆ :分岐終了 ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = ON ◆ :分岐終了 ◆条件分岐:影用・判定対象Y < ◆↑+1壁だったY ◆条件分岐:影用・ピクチャID ≠ 123 ◆変数の操作:#0126 影用・ピクチャ座標X += -48 ◆変数の操作:#0127 影用・ピクチャ座標Y += 48 ◆ループの中断 ◆ :分岐終了 ◆ :分岐終了 ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆ループの中断 ◆ :分岐終了 ◆変数の操作:#0126 影用・ピクチャ座標X += 48 ◆変数の操作:#0127 影用・ピクチャ座標Y += -48 ◆変数の操作:#0129 影用・判定対象X += 1 ◆変数の操作:#0130 影用・判定対象Y += -1 ◆変数の操作:#0133 影用・判定対象画面X += 1 ◆変数の操作:#0134 影用・判定対象画面Y += -1 ◆条件分岐:影用・判定対象画面Y < -1 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆変数の操作:#0138 影用・ピクチャずらすX = 影用・判定対象ずらすX ◆変数の操作:#0139 影用・ピクチャずらすY = 影用・判定対象ずらすY ◆変数の操作:#0138 影用・ピクチャずらすX *= 48 ◆変数の操作:#0139 影用・ピクチャずらすY *= 48 ◆変数の操作:#0126 影用・ピクチャ座標X += 影用・ピクチャずらすX ◆変数の操作:#0127 影用・ピクチャ座標Y += 影用・ピクチャずらすY ◆スクリプト:$gameScreen.showPicture($gameVariables.value(128),'!kage_6',0,$gameVariables.value(126),$gameVariables.value(127),100,100,$gameVariables.value(135),0) ◆変数の操作:#0128 影用・ピクチャID += 1 ◆変数の操作:#0136 影用・判定対象ずらすX += 0 ◆変数の操作:#0137 影用・判定対象ずらすY += -1 ◆条件分岐:影用・ピクチャID = 131 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆変数の操作:#0128 影用・ピクチャID = 131 ◆注釈:↗(右に見ていく) ◆変数の操作:#0136 影用・判定対象ずらすX = 0 ◆変数の操作:#0137 影用・判定対象ずらすY = 0 ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = OFF ◆スイッチの操作:#0008 影・斜め判定重複SKIPフラグ = OFF ◆ループ ◆注釈:(共通設定) ◆コモンイベント:┗共通初期処理 ◆注釈:========== ◆変数の操作:#0129 影用・判定対象X += 1 ◆変数の操作:#0130 影用・判定対象Y += -1 ◆変数の操作:#0129 影用・判定対象X += 影用・判定対象ずらすX ◆変数の操作:#0130 影用・判定対象Y += 影用・判定対象ずらすY ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = OFF ◆ループ ◆指定位置の情報取得:影用・判定対象地形ID, 地形タグ, ({影用・判定対象X},{影用・判定対象Y}) ◆条件分岐:影・斜め用はじめの列フラグがOFF ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆条件分岐:影・斜め用はじめの列初回フラグがOFF ◆変数の操作:#0148 ◆→-1壁だったX = 影用・判定対象X ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = ON ◆ :分岐終了 ◆ :分岐終了 ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = ON ◆ :分岐終了 ◆条件分岐:影用・判定対象X > ◆→-1壁だったX ◆条件分岐:影用・ピクチャID ≠ 123 ◆変数の操作:#0126 影用・ピクチャ座標X += -48 ◆変数の操作:#0127 影用・ピクチャ座標Y += 48 ◆ループの中断 ◆ :分岐終了 ◆ :分岐終了 ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆ループの中断 ◆ :分岐終了 ◆変数の操作:#0126 影用・ピクチャ座標X += 48 ◆変数の操作:#0127 影用・ピクチャ座標Y += -48 ◆変数の操作:#0129 影用・判定対象X += 1 ◆変数の操作:#0130 影用・判定対象Y += -1 ◆変数の操作:#0133 影用・判定対象画面X += 1 ◆変数の操作:#0134 影用・判定対象画面Y += -1 ◆条件分岐:影用・判定対象画面X > 22 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆変数の操作:#0138 影用・ピクチャずらすX = 影用・判定対象ずらすX ◆変数の操作:#0139 影用・ピクチャずらすY = 影用・判定対象ずらすY ◆変数の操作:#0138 影用・ピクチャずらすX *= 48 ◆変数の操作:#0139 影用・ピクチャずらすY *= 48 ◆変数の操作:#0126 影用・ピクチャ座標X += 影用・ピクチャずらすX ◆変数の操作:#0127 影用・ピクチャ座標Y += 影用・ピクチャずらすY ◆条件分岐:影・斜め判定重複SKIPフラグがOFF ◆スイッチの操作:#0008 影・斜め判定重複SKIPフラグ = ON ◆ :それ以外のとき ◆スクリプト:$gameScreen.showPicture($gameVariables.value(128),'!kage_6',0,$gameVariables.value(126),$gameVariables.value(127),100,100,$gameVariables.value(135),0) ◆変数の操作:#0128 影用・ピクチャID += 1 ◆ :分岐終了 ◆変数の操作:#0136 影用・判定対象ずらすX += 1 ◆変数の操作:#0137 影用・判定対象ずらすY += 0 ◆条件分岐:影用・ピクチャID = 142 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆注釈:================================================== ◆注釈:【↙】 ◆注釈:================================================== ◆変数の操作:#0128 影用・ピクチャID = 142 ◆注釈:↙(下に見ていく) ◆変数の操作:#0136 影用・判定対象ずらすX = 0 ◆変数の操作:#0137 影用・判定対象ずらすY = 0 ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = OFF ◆ループ ◆注釈:(共通設定) ◆コモンイベント:┗共通初期処理 ◆注釈:========== ◆変数の操作:#0129 影用・判定対象X += -1 ◆変数の操作:#0130 影用・判定対象Y += 1 ◆変数の操作:#0129 影用・判定対象X += 影用・判定対象ずらすX ◆変数の操作:#0130 影用・判定対象Y += 影用・判定対象ずらすY ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = OFF ◆ループ ◆指定位置の情報取得:影用・判定対象地形ID, 地形タグ, ({影用・判定対象X},{影用・判定対象Y}) ◆条件分岐:影・斜め用はじめの列フラグがOFF ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆条件分岐:影・斜め用はじめの列初回フラグがOFF ◆変数の操作:#0149 ◆↓-1壁だったY = 影用・判定対象Y ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = ON ◆ :分岐終了 ◆ :分岐終了 ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = ON ◆ :分岐終了 ◆条件分岐:影用・判定対象Y > ◆↓-1壁だったY ◆条件分岐:影用・ピクチャID ≠ 142 ◆変数の操作:#0126 影用・ピクチャ座標X += 48 ◆変数の操作:#0127 影用・ピクチャ座標Y += -48 ◆ループの中断 ◆ :分岐終了 ◆ :分岐終了 ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆ループの中断 ◆ :分岐終了 ◆変数の操作:#0126 影用・ピクチャ座標X += -48 ◆変数の操作:#0127 影用・ピクチャ座標Y += 48 ◆変数の操作:#0129 影用・判定対象X += -1 ◆変数の操作:#0130 影用・判定対象Y += 1 ◆変数の操作:#0133 影用・判定対象画面X += -1 ◆変数の操作:#0134 影用・判定対象画面Y += 1 ◆条件分岐:影用・判定対象画面Y > 16 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆変数の操作:#0138 影用・ピクチャずらすX = 影用・判定対象ずらすX ◆変数の操作:#0139 影用・ピクチャずらすY = 影用・判定対象ずらすY ◆変数の操作:#0138 影用・ピクチャずらすX *= 48 ◆変数の操作:#0139 影用・ピクチャずらすY *= 48 ◆変数の操作:#0126 影用・ピクチャ座標X += 影用・ピクチャずらすX ◆変数の操作:#0127 影用・ピクチャ座標Y += 影用・ピクチャずらすY ◆スクリプト:$gameScreen.showPicture($gameVariables.value(128),'!kage_7',0,$gameVariables.value(126),$gameVariables.value(127),100,100,$gameVariables.value(135),0) ◆変数の操作:#0128 影用・ピクチャID += 1 ◆変数の操作:#0136 影用・判定対象ずらすX += 0 ◆変数の操作:#0137 影用・判定対象ずらすY += 1 ◆条件分岐:影用・ピクチャID = 150 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆変数の操作:#0128 影用・ピクチャID = 150 ◆注釈:↙(左に見ていく) ◆変数の操作:#0136 影用・判定対象ずらすX = 0 ◆変数の操作:#0137 影用・判定対象ずらすY = 0 ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = OFF ◆スイッチの操作:#0008 影・斜め判定重複SKIPフラグ = OFF ◆ループ ◆注釈:(共通設定) ◆コモンイベント:┗共通初期処理 ◆注釈:========== ◆変数の操作:#0129 影用・判定対象X += -1 ◆変数の操作:#0130 影用・判定対象Y += 1 ◆変数の操作:#0129 影用・判定対象X += 影用・判定対象ずらすX ◆変数の操作:#0130 影用・判定対象Y += 影用・判定対象ずらすY ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = OFF ◆ループ ◆指定位置の情報取得:影用・判定対象地形ID, 地形タグ, ({影用・判定対象X},{影用・判定対象Y}) ◆条件分岐:影・斜め用はじめの列フラグがOFF ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆条件分岐:影・斜め用はじめの列初回フラグがOFF ◆変数の操作:#0150 ◆←+1壁だったX = 影用・判定対象X ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = ON ◆ :分岐終了 ◆ :分岐終了 ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = ON ◆ :分岐終了 ◆条件分岐:影用・判定対象X < ◆←+1壁だったX ◆条件分岐:影用・ピクチャID ≠ 142 ◆変数の操作:#0126 影用・ピクチャ座標X += 48 ◆変数の操作:#0127 影用・ピクチャ座標Y += -48 ◆ループの中断 ◆ :分岐終了 ◆ :分岐終了 ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆ループの中断 ◆ :分岐終了 ◆変数の操作:#0126 影用・ピクチャ座標X += -48 ◆変数の操作:#0127 影用・ピクチャ座標Y += 48 ◆変数の操作:#0129 影用・判定対象X += -1 ◆変数の操作:#0130 影用・判定対象Y += 1 ◆変数の操作:#0133 影用・判定対象画面X += -1 ◆変数の操作:#0134 影用・判定対象画面Y += 1 ◆条件分岐:影用・判定対象画面X < -2 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆変数の操作:#0138 影用・ピクチャずらすX = 影用・判定対象ずらすX ◆変数の操作:#0139 影用・ピクチャずらすY = 影用・判定対象ずらすY ◆変数の操作:#0138 影用・ピクチャずらすX *= 48 ◆変数の操作:#0139 影用・ピクチャずらすY *= 48 ◆変数の操作:#0126 影用・ピクチャ座標X += 影用・ピクチャずらすX ◆変数の操作:#0127 影用・ピクチャ座標Y += 影用・ピクチャずらすY ◆条件分岐:影・斜め判定重複SKIPフラグがOFF ◆スイッチの操作:#0008 影・斜め判定重複SKIPフラグ = ON ◆ :それ以外のとき ◆スクリプト:$gameScreen.showPicture($gameVariables.value(128),'!kage_7',0,$gameVariables.value(126),$gameVariables.value(127),100,100,$gameVariables.value(135),0) ◆変数の操作:#0128 影用・ピクチャID += 1 ◆ :分岐終了 ◆変数の操作:#0136 影用・判定対象ずらすX += -1 ◆変数の操作:#0137 影用・判定対象ずらすY += 0 ◆条件分岐:影用・ピクチャID = 160 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆注釈:================================================== ◆注釈:【↘】 ◆注釈:================================================== ◆変数の操作:#0128 影用・ピクチャID = 160 ◆注釈:↘(下に見ていく) ◆変数の操作:#0136 影用・判定対象ずらすX = 0 ◆変数の操作:#0137 影用・判定対象ずらすY = 0 ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = OFF ◆ループ ◆注釈:(共通設定) ◆コモンイベント:┗共通初期処理 ◆注釈:========== ◆変数の操作:#0129 影用・判定対象X += 1 ◆変数の操作:#0130 影用・判定対象Y += 1 ◆変数の操作:#0129 影用・判定対象X += 影用・判定対象ずらすX ◆変数の操作:#0130 影用・判定対象Y += 影用・判定対象ずらすY ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = OFF ◆ループ ◆指定位置の情報取得:影用・判定対象地形ID, 地形タグ, ({影用・判定対象X},{影用・判定対象Y}) ◆条件分岐:影・斜め用はじめの列フラグがOFF ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆条件分岐:影・斜め用はじめの列初回フラグがOFF ◆変数の操作:#0151 ◆↓+1壁だったY = 影用・判定対象Y ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = ON ◆ :分岐終了 ◆ :分岐終了 ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = ON ◆ :分岐終了 ◆条件分岐:影用・判定対象Y > ◆↓+1壁だったY ◆条件分岐:影用・ピクチャID ≠ 160 ◆変数の操作:#0126 影用・ピクチャ座標X += -48 ◆変数の操作:#0127 影用・ピクチャ座標Y += -48 ◆ループの中断 ◆ :分岐終了 ◆ :分岐終了 ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆ループの中断 ◆ :分岐終了 ◆変数の操作:#0126 影用・ピクチャ座標X += 48 ◆変数の操作:#0127 影用・ピクチャ座標Y += 48 ◆変数の操作:#0129 影用・判定対象X += 1 ◆変数の操作:#0130 影用・判定対象Y += 1 ◆変数の操作:#0133 影用・判定対象画面X += 1 ◆変数の操作:#0134 影用・判定対象画面Y += 1 ◆条件分岐:影用・判定対象画面Y > 16 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆変数の操作:#0138 影用・ピクチャずらすX = 影用・判定対象ずらすX ◆変数の操作:#0139 影用・ピクチャずらすY = 影用・判定対象ずらすY ◆変数の操作:#0138 影用・ピクチャずらすX *= 48 ◆変数の操作:#0139 影用・ピクチャずらすY *= 48 ◆変数の操作:#0126 影用・ピクチャ座標X += 影用・ピクチャずらすX ◆変数の操作:#0127 影用・ピクチャ座標Y += 影用・ピクチャずらすY ◆スクリプト:$gameScreen.showPicture($gameVariables.value(128),'!kage_8',0,$gameVariables.value(126),$gameVariables.value(127),100,100,$gameVariables.value(135),0) ◆変数の操作:#0128 影用・ピクチャID += 1 ◆変数の操作:#0136 影用・判定対象ずらすX += 0 ◆変数の操作:#0137 影用・判定対象ずらすY += 1 ◆条件分岐:影用・ピクチャID = 168 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆変数の操作:#0128 影用・ピクチャID = 168 ◆注釈:↘(右に見ていく) ◆変数の操作:#0136 影用・判定対象ずらすX = 0 ◆変数の操作:#0137 影用・判定対象ずらすY = 0 ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = OFF ◆スイッチの操作:#0008 影・斜め判定重複SKIPフラグ = OFF ◆ループ ◆注釈:(共通設定) ◆コモンイベント:┗共通初期処理 ◆注釈:========== ◆変数の操作:#0129 影用・判定対象X += 1 ◆変数の操作:#0130 影用・判定対象Y += 1 ◆変数の操作:#0129 影用・判定対象X += 影用・判定対象ずらすX ◆変数の操作:#0130 影用・判定対象Y += 影用・判定対象ずらすY ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = OFF ◆ループ ◆指定位置の情報取得:影用・判定対象地形ID, 地形タグ, ({影用・判定対象X},{影用・判定対象Y}) ◆条件分岐:影・斜め用はじめの列フラグがOFF ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆条件分岐:影・斜め用はじめの列初回フラグがOFF ◆変数の操作:#0152 ◆→+1壁だったX = 影用・判定対象X ◆スイッチの操作:#0007 影・斜め用はじめの列初回フラグ = ON ◆ :分岐終了 ◆ :分岐終了 ◆スイッチの操作:#0006 影・斜め用はじめの列フラグ = ON ◆ :分岐終了 ◆条件分岐:影用・判定対象X > ◆→+1壁だったX ◆条件分岐:影用・ピクチャID ≠ 160 ◆変数の操作:#0126 影用・ピクチャ座標X += -48 ◆変数の操作:#0127 影用・ピクチャ座標Y += -48 ◆ループの中断 ◆ :分岐終了 ◆ :分岐終了 ◆条件分岐:影用・判定対象地形ID = 影用・壁地形ID ◆ループの中断 ◆ :分岐終了 ◆変数の操作:#0126 影用・ピクチャ座標X += 48 ◆変数の操作:#0127 影用・ピクチャ座標Y += 48 ◆変数の操作:#0129 影用・判定対象X += 1 ◆変数の操作:#0130 影用・判定対象Y += 1 ◆変数の操作:#0133 影用・判定対象画面X += 1 ◆変数の操作:#0134 影用・判定対象画面Y += 1 ◆条件分岐:影用・判定対象画面X > 22 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し ◆変数の操作:#0138 影用・ピクチャずらすX = 影用・判定対象ずらすX ◆変数の操作:#0139 影用・ピクチャずらすY = 影用・判定対象ずらすY ◆変数の操作:#0138 影用・ピクチャずらすX *= 48 ◆変数の操作:#0139 影用・ピクチャずらすY *= 48 ◆変数の操作:#0126 影用・ピクチャ座標X += 影用・ピクチャずらすX ◆変数の操作:#0127 影用・ピクチャ座標Y += 影用・ピクチャずらすY ◆条件分岐:影・斜め判定重複SKIPフラグがOFF ◆スイッチの操作:#0008 影・斜め判定重複SKIPフラグ = ON ◆ :それ以外のとき ◆スクリプト:$gameScreen.showPicture($gameVariables.value(128),'!kage_8',0,$gameVariables.value(126),$gameVariables.value(127),100,100,$gameVariables.value(135),0) ◆変数の操作:#0128 影用・ピクチャID += 1 ◆ :分岐終了 ◆変数の操作:#0136 影用・判定対象ずらすX += 1 ◆変数の操作:#0137 影用・判定対象ずらすY += 0 ◆条件分岐:影用・ピクチャID = 179 ◆ループの中断 ◆ :分岐終了 ◆ :以上繰り返し
【コモンイベント「┗共通初期処理」】
◆変数の操作:#0126 影用・ピクチャ座標X = プレイヤーのマップX ◆変数の操作:#0127 影用・ピクチャ座標Y = プレイヤーのマップY ◆変数の操作:#0126 影用・ピクチャ座標X *= 48 ◆変数の操作:#0127 影用・ピクチャ座標Y *= 48 ◆変数の操作:#0126 影用・ピクチャ座標X -= 504 ◆変数の操作:#0127 影用・ピクチャ座標Y -= 384 ◆変数の操作:#0129 影用・判定対象X = プレイヤーのマップX ◆変数の操作:#0130 影用・判定対象Y = プレイヤーのマップY ◆変数の操作:#0133 影用・判定対象画面X = 10 ◆変数の操作:#0134 影用・判定対象画面Y = 8
終わりに
誰得機能「ファミコン版ウルティマ3の風の影」をMZで実装できた。
本家と微妙に動作が異なるけどこれが限界。
そして想定通りかなり重い。
この影処理、続編のFC版ウルティマ4では方式が変わっているので、あまり評判良くなかったのかなーと感じている。 pic.twitter.com/N35esLHN85— sep (@Spare_Blade) July 17, 2021
というわけで、完全再現ではなく「風」になってしまったものの、場所によって視界が開けていく処理を実装することが出来ました。
本家と違って影を半透明にしているため尚更ゲーム性には繋がらないのですが、かっこよさを求めて実装しただけなので良いこととしたいと思います。
好みだけで好きなように盛り込めるのがフリーゲーム制作の良さだと思っています。
仕事としてやっていたら間違いなく「それの実装は費用対効果が薄いので、今回は見送りましょう。。。」とか言っているはず。
こういう影処理に関して言及しているサイトがなかったのと、実装にかなり悩んだことから今回記事としてまとめてみました。
もっといい方法があったらTwitterとかで教えて下さい。