・概要
地形との
接触判定の取得と位置調整に関して解説する。
解説は、以下のような段階に分けて行う。下の段階ほど、難易度が高くなる。
・「接触判定」のみ。
・「接触判定」+「位置調整」。
・「移動量」「地形めり込み量の最大値」に関する処理+「接触判定」+「位置調整」。
接触判定と同時に、「地形の特性」関連の接触判定が付加される場合がある。
地形の出現・消滅の「・地形の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