[PR]看護師の好条件な求人情報満載:「夜勤は嫌!」など希望の転職が実現♪

  すり抜け現象を回避する

 すり抜け現象というのは衝突するはずが何事もなかったかのようにすり抜けていってしまう現象です。例えばSTGゲームで間違いなく敵に当たるはずの弾がそのまま貫通して通り過ぎてしまうなどです。今回はこの現象を回避する手段を考えてみます。これにも方法が幾つかありますが、環境、技術、状況に応じて使い分けたいものです。

すり抜け現象のメカニズム
 まずは何故すり抜けてしまうのかが分からなければ話になりません。すり抜けるという言葉は人間から見たときの言葉ですが、プログラム的には単に「衝突判定が働いていない」ということです。

 キャラクターが動くというのは時間ごとに絵の位置をずらしていくと、あたかもそれが動いているように見えるという事です。人間の目には連続的に見える動きの線も実際には不連続な点の集まりです。キャラクターは一度に数ドット動きますがこの動く距離が大きいと稀に上図のように衝突判定しないまま「すり抜けて」しまうのです


衝突しやすくなる工夫をする
 最も手軽で簡単な方法です。なるべくすり抜けをしないようにキャラクターの大きさを大きくしたり、一度に移動する距離を短くするなどです。この方法で大抵は解決しますが、副作用としてあまりスピード感ある動きが出来なくなってしまうという問題があります。
 大抵は妥協すればいいのですが、弾速が速い、遅いなどは少なからずゲームバランスにも影響してきます。妥協ばっかでいいというわけにもいかないものです。


内部計算を倍にする
 ほとんどのゲームにおいて最も処理に時間のかかる部分は画面表示に関する部分です。一般にゲームは秒間60フレームで作られますが、それを二倍の秒間120フレームで行い、時間のかかる画面表示は二回に一回、つまり見た目的にはあたかも60フレームでやってるように見せかけるというものです。これなら普通に120フレームで作るよりずっと処理が軽くなります。そして倍のフレーム数ですからキャラクターの移動距離は60フレームのときに比べて半分になります。これですり抜け現象を回避(減少)させようというものです。
 しかしこの方法で絶対回避できる保証はありませんし、そもそも60フレームの計算で限界ギリギリなパソコンを使っている人たちはどうなってしまうのでしょうか


移動線分が交差したかで判断する
 キャラの大きさや移動距離を変更する方法よりは手間がかかりますが最も正確に判定でき、確実にすり抜け現象をを回避できます。その方法とは移動中のキャラクターの移動前座標と移動後の座標を繋いだ線分が対象となるキャラクターの判定領域を貫通しているかで判断します。

 まず、最も単純な矩形を線分が貫通する場合を考えます。矩形を貫通しているかと言うと複雑に聞こえるかもしれませんが、実際には2本の対角線のどちらか一方でも線分と交われば矩形内を貫通していることが確認できるはずです。ということは問題は2本の線分が交差しているかどうかということになりますね。
 では実際に線分の交差判定をコードで書いてみましょう。それにはまず直線で結ばれた3点が時計回りか反時計かを判断する関数が必要になります。詳しく知りたい人は補講:回転方向と線分交差を参照してください。ではこの関数をClock_Directionと名付けます。
//3点の並びが時計方向か反時計かを判断
//時計回りなら1、反時計なら-1、点が同一直線状にあるときは0を返す
int Clock_Direction(int x1,int y1,int x2,int y2,int x3,int y3){
	int dx1,dy1,dx2,dy2,cl_d=0;
	
	dx1 = x2-x1;
	dy1 = y2-y1;
	dx2 = x3-x1;
	dy2 = y3-y1;
	
	if( (dx1*dy2) > (dx2*dy1) ){
		cl_d=-1;
	}elseif( (dx1*dy2) < (dx2*dy1) ){
		cl_d=1;
	}
	return cl_d;
}

 これで線分交差の判定をする準備が整いました。では線分交差のコードを書いてみます。線分AとBがあり、線分Aの始点を(x1,y1)、終点を(x2,y2)として線分Bの始点を(x3,y3)、終点を(x4,y4)とします。
if( Clock_Direction(x1,y1,x2,y2,x3,y3)
*Clock_Direction(x1,y1,x2,y2,x4,y4) < 0

&& Clock_Direction(x3,y3,x4,y4,x1,y1)
*Clock_Direction(x3,y3,x4,y4,x2,y2) < 0 ){
	
	交差しています
}else{	
	交差していません
}
 ものすごい長さの条件式で恐縮ですが、これで線分交差の判定ができます。詳しくは補講:回転方向と線分交差を参照してください。
 あとはこれを使って移動中のキャラの線分と判定対象の矩形の対角線2本とをそれぞれ判定してやればOKです。ただしこれには端点が重なってた場合を除くという条件があります。なので交差判定が終わった後に通常の矩形判定を行ってやるとより確実でしょう

 ここで疑問に思った方も居ると思います。それは移動しているキャラクターも矩形なのだから太さのある線分になるんじゃないかと。まったくそのとおりですが、これに関してはかなり簡単に対処できます。判定対象の矩形領域を移動キャラの領域分上下左右にさらに広げて計算するだけです。


 さて、最後に線分が円形領域を貫通する場合について軽く触れておきます。円形の場合は中心点と線分の最短距離が半径より小さければ貫通になります。点と直線の距離公式を使えばすぐに実現できそうです。




  <・戻る>




[PR]大人気!看護師単発アルバイト:看護師の単発のアルバイトを手軽に検索!