・概要

 地形との接触判定の取得と位置調整に関して解説する。

 解説は、以下のような段階に分けて行う。下の段階ほど、難易度が高くなる。
・「接触判定」のみ。
・「接触判定」+「位置調整」。
・「移動量」「地形めり込み量の最大値」に関する処理+「接触判定」+「位置調整」。

 地形移動に関連する処理は、地形移動を参照。

 接触判定と同時に、「地形の特性」関連の接触判定が付加される場合がある地形の出現・消滅の「・地形のMCの構造」も参照。

・地形の端の位置・勾配

 地形の端の位置・勾配の取得に関して解説する。

 ここでは、傾斜床を例にする。「該当する地形のMCの参照先」を変数(「landform」)に保存していることに注意。

ASのファイル:landform_position_gradient_movement.txt
 
//landformの端の位置
landform_xmin=landform.getBounds(_root.board).xMin;landform_xmax=landform.getBounds(_root.board).xMax	//左,右
landform_ymin=landform.getBounds(_root.board).yMin;landform_ymax=landform.getBounds(_root.board).yMax	//上,下
 
//landformの勾配
landform_gradient=landform._height/landform._width	//勾配
 

↓地形の端の位置。

・①:「landform_xmin」。地形の左端の位置。
・②:「landform_xmax」。地形の右端の位置。
・③:「landform_ymin」。地形の上端の位置。
・④:「landform_ymax」。地形の下端の位置。
・⑤:「landform._width」。地形の幅。
・⑥:「landform._height」。地形の高さ。
・「landform_gradient」。地形の勾配。⑥/⑤。

・「接触判定」のみ

・・概要

 ここでは、例として、フルチャージバスターと壁(右)との接触判定に関して解説する。

↓フルチャージバスターと壁(右)との接触判定。接触判定がある場合は、消滅判定が付加され、バスターが消滅する。

・・接触判定

 ”単純”な接触判定(hitTest)がある場合は、接触判定を付加する

↓”単純”な接触判定がない場合。

↓”単純”な接触判定がある場合。

ASのファイル:hit_wall_right.txt
 
hit_wall_right=0	//判定をリセットしておく
for(i=1;i<=_root.i_wall_right;i++){
	landform=_root.board["wall_right_"+i]	//参照先を変数に保存
	if(this.hitTest(landform)){if(hit_buster_through==0){hit_wall_right=i}	//接触判定
	}
}
 
・「hit_wall_right=0」:壁(右)との接触判定をリセットしておく
・「this」:フルチャージバスターのhitrectを指す。
・「_root.board["wall_right_"+i]」:ボードに配置されている壁(右)のMC。インスタンス名は「wall_right_1」「wall_right_2」「wall_right_3」…となる。記述の簡略化などのために、ここでは参照先を「landform」という変数に保存している。
・「if(this.hitTest(landform))」:「フルチャージバスターのhitrect」と「壁(右)」との”単純”な接触判定がある場合。
・「if(hit_buster_through==0){hit_wall_right=i}」:「バスター貫通」との接触判定がない場合、壁(右)との接触判定を付加する(接触判定に、該当する地形の番号を代入する)。「バスター貫通」に関しては、バスター貫通を参照。

・「接触判定」+「位置調整」

・・概要

 「・「接触判定」のみ」において解説した内容を前提とする。

 ここでは、例として、アイテムと床との接触判定と、アイテムの位置調整に関して解説する。

↓アイテムと床との接触判定。接触判定がある場合、アイテムは床の上に位置調整される。

・・接触判定

 「・「接触判定」のみ」とほぼ同様の処理を行っている。

ASのファイル:hit_floor.txt
 
hit_floor=0	//判定をリセットしておく
for(i=1;i<=_root.i_floor;i++){
	landform=_root.board["floor_"+i]	//参照先を変数に保存
	if(this.hitTest(landform)){if(hit_buster_through==0){hit_floor=i}	//接触判定
	}
}
 

・・地形めり込み量

 アイテムのhitrectの床に対する「地形めり込み量」は、以下の図の通りとなる。

「地形めり込み量」。内部的な処理の段階であり、実際のゲーム画面では表示されない。

・①:「landform_ymin」。
・②:「this.getBounds(_root.board).yMax」。アイテムのhitrectの下端の位置。
・③:「hit_y_floor」。地形めり込み量。②-①。

ASのファイル:hit_floor.txt
 
		hit_y_floor=this.getBounds(_root.board).yMax-landform_ymin	//地形めり込み量
 

・・位置調整

 「・・地形めり込み量」において計算した値を用いて、位置調整を行う。

↓位置調整。

ASのファイル:item.txt
 
			if(hit_floor!=0){_parent._y-=hit_y_floor	//位置調整
			}
 
・「if(hit_floor!=0)」:アイテムと床との”単純”な接触判定がある場合
・「_parent._y-=hit_y_floor」:アイテムの位置調整。「地形めり込み量」の値だけ上方向に移動させる。

・「移動量」「地形めり込み量の最大値」に関する処理+「接触判定」+「位置調整」

・・概要

 「・「接触判定」のみ」「・「接触判定」+「位置調整」」において解説した内容を前提とする。

 ここでは、例として、ゼロと壁(右)との接触判定に関して解説する。

↓ゼロと壁(右)との接触判定。

・・移動量

 「移動量」は、「現在の位置」と「1フレーム前の位置」との差分である。「変位」とも表現できる。

↓ゼロの移動量(ゼロが右下に移動した場合)。

・①:「_parent._x」。ゼロの現在の位置(地形による位置調整前、x方向)。
・②:「MC_x_old」。ゼロの1フレーム前の位置(x方向)。
・③:「MC_dx」。ゼロの移動量(x方向)。①-②。
・④:「_parent._y」。ゼロの現在の位置(地形による位置調整前、y方向)。
・⑤:「MC_y_old」。ゼロの1フレーム前の位置(y方向)。
・⑥:「MC_dy」。ゼロの移動量(y方向)。④-⑤。

ASのファイル:initial_hit_max.txt
 
MC_dx=_parent._x-MC_x_old;MC_dy=_parent._y-MC_y_old
 

・・地形めり込み量の最大値(初期値)

・・・概要

 「地形めり込み量の最大値」は、各方向における、1フレームでの、「地形へめり込む可能性がある量」の最大値のことである
 この値は、「移動量」や「地形移動」により変動する

↓地形めり込み量の最大値。

・①、②:「MC_dx」。ゼロの移動量(x方向)。
・③:「initial_hit_x_max_right」:地形めり込み量の最大値(初期値)。「MC_dx+1」としている。

 上の図の通り、基本的には、ゼロは壁(右)に、最大で「MC_dx」の値だけめり込むことになる。ただし、ここでは、「+1」としている。

ASのファイル:initial_hit_max.txt
 
initial_hit_x_max_right=MC_dx+1	//右
 

 「+1」としている理由は、壁(右)と床・天井の配置は重なっておらず、「1」だけ間隔を設けていること、となる。

↓壁(右)と床・天井の配置。左上と左下に間隔がある。

 間隔がない場合は、例えば、以下のような不具合が生じる。

↓このような地形では、間隔がない場合は、「壁ずり落ち」→「落下・着地」→「ジャンプ」で、天井との接触判定が付加されることになる。

・・・hitrectの変化を考慮した補正

 ゼロのhitrectは、ダッシュ・エアダッシュの場合に変化する。よって、hitrectの変化を考慮した補正を行う必要がある

hitrectの変化(ダッシュした瞬間)。

・①:「MC_width_right」。ゼロのhitrectの幅(右)。
・②:「MC_width_right_old」。ゼロの1フレーム前のhitrectの幅(右)。
・③:「MC_width_right-MC_width_right_old」。ゼロのhitrectの幅(右)の差分。①-②。

ASのファイル:initial_hit_max.txt
 
if(MC_width_right-MC_width_right_old>0){initial_hit_x_max_right+=MC_width_right-MC_width_right_old}	//右
 
・「if(MC_width_right-MC_width_right_old>0)」:ゼロのhitrectの幅(右)の差分が正の場合。
・「initial_hit_x_max_right+=MC_width_right-MC_width_right_old」:地形めり込み量の最大値(初期値)に、ゼロのhitrectの幅(右)の差分を加算して補正する。

↓hitrectの変化を考慮した補正を行わない場合。ダッシュした瞬間に貫通する。

・・・算出するタイミング

 地形めり込み量の最大値(初期値)の算出は、壁との接触判定の取得の前後に行っている(つまり、2回行っている)。
 2回目において、壁によるx方向の位置調整の結果が反映されることになる。

 2回目を行わない場合は、以下のような不具合が生じる。

↓2回目を行わない場合。壁によるx方向の位置調整の結果が反映されないため、壁付近においてダッシュをすると傾斜床を貫通する。

↓2回目を行う場合。

ASのファイル:zero_hit_landform_enemy.txt
 
#include "zero_AS/hit_landform/initial_hit_max.txt"
 
#include "zero_AS/hit_landform/zero_hit_wall_right.txt"
 
#include "zero_AS/hit_landform/zero_hit_wall_left.txt"
 
#include "zero_AS/hit_landform/initial_hit_max.txt"
 

・・接触判定

・・・概要

 「・「接触判定」のみ」「・「接触判定」+「位置調整」」の例とは異なり、”単純”な接触判定(hitTest)がある場合においても、必ずしも接触判定を付加するとは限らない

・・・地形めり込み量の最大値(初期値)の代入

 「地形めり込み量の最大値」に「地形めり込み量の最大値(初期値)」を代入する。この処理により、「地形めり込み量の最大値」が、ループ毎にリセットされることになる。

ASのファイル:zero_hit_wall_right.txt
 
		hit_x_max_right=initial_hit_x_max_right	//地形めり込み量の最大値
 

・・・地形めり込み量が最大値以下の場合

 「地形めり込み量」が「地形めり込み量の最大値」以下の場合に、接触判定が付加される

↓地形めり込み量。

・①:「this.getBounds(_root.board).xMax」。ゼロのhitrectの右端の位置。
・②:「landform_xmin」。
・③:「hit_x_wall_right」。地形めり込み量。①-②。
・④:「hit_x_max_right」。地形めり込み量の最大値。③<=④の条件が満たされるため、接触判定が付加される

ASのファイル:zero_hit_wall_right.txt
 
		hit_x_wall_right=this.getBounds(_root.board).xMax-landform_xmin	//地形めり込み量
 
		if(hit_x_wall_right<=hit_x_max_right){	//地形めり込み量が最大値以下の場合
			hit_wall_right=i	//接触判定}
 

 「break(ループを離脱)」の処理は行わない。その理由は、地形移動と関連する。

・・・地形めり込み量が最大値より大きい場合

 地形めり込み量が最大値より大きい場合は、接触判定は付加されず、位置調整は行われない

↓地形めり込み量が最大値より大きい場合の例。

・垂直ジャンプの場合は、移動量が0となり、接触判定が付加されない。ただし、地形めり込み量が「1」以下の場合は、接触判定が付加される。
・「既にめり込んだ状態」での右方向へのジャンプの場合は、地形めり込み量が最大値より大きくなり、接触判定が付加されない。
・左方向へのジャンプの場合は、移動量がマイナスとなり、接触判定が付加されない。

 「既にめり込んだ状態」での右方向へのジャンプの場合は、以下の通りとなる。

↓「既にめり込んだ状態」での右方向へのジャンプ。

・①:「hit_x_wall_right」。
・②:「hit_x_max_right」。①<=②の条件が満たされないため、接触判定が付加されない。

 左方向へのジャンプの場合は、以下の通りとなる。

↓左方向へのジャンプ。

・①:「hit_x_wall_right」。
・②:「hit_x_max_right」(マイナスの値)。①<=②の条件が満たされないため、接触判定が付加されない。

・・位置調整

 「・「接触判定」+「位置調整」」の「・・位置調整」と同様の処理を行う。

↓位置調整の例。

ASのファイル:zero_hit_wall_right.txt
 
			_parent._x-=hit_x_wall_right	//位置調整
 

最終更新:2020年12月19日 10:58