2点間の距離を算出するのだ

だ〜いぶ間があいてしまったんで、題材がすっとんじゃってますけど、あんま気にしないで下さい(^^ゞ

今作成中の『Distance』というシューティングゲームのメインコンセプトは「自機から近い位置で倒すほど得点倍率が高い」というもの。ということは、必然的に自機と敵との間の距離を算出しなきゃいけなくなってくる。ちょっと下の図を見ていただきたい。

要は、(mx,my)〜(ex,ey)の距離を出したいのである。ここで数学の知識が必要となってくるわけだが、直角三角形の場合dxとdyの長さがわかってれば斜め辺の長さは求めることができる。それがいわゆる三平方の定理である(すっかり忘れてた^^;)。

2=dx2+dy2


つまり、(dx2+dy2)の平方根を求めれば、2点間の距離が算出できるというわけだ。しかし、これには致命的な問題点がある。HSP2.4には標準状態のままだと平方根を求める命令がないのである。もちろん拡張dllなんかでその命令を追加することはできるが、別にそこまでして正確な平方根を求めようと思わないのなら、基本命令だけでもなんとかできちゃうのである。もちろんけっこう値はいいかげんなんで、正確に求めたいなら拡張dllを使いましょう。


; 三平方の定理を利用した距離算定スクリプト

	screen 0,640,480,1,50,0 : title "2点間のだいたいの距離"
	mx=320 : my=240


; ■■■■■ 要素番号の2乗を格納
*start
	dim y,900
	repeat 900
	x=cnt : y.cnt=x*x
	loop
goto *main


; ■■■■■ メイン
*main
	redraw 2
	color 255,255,255 : boxf 0,0,640,480

	gosub *dotmove
	gosub *measure

	redraw 1
	await 16
goto *main


; ■■■■■ 距離の算出
*measure
	dx=320-mx : if dx<0 : dx=-dx
	dy=240-my : if dy<0 : dy=-dy
	dst=(dx*dx)+(dy*dy)
	repeat 900
	if dst<y.cnt : dst=cnt : break
	loop
return


; ■■■■■ 点の移動と画面描写
*dotmove
	stick pat,79
	if pat&128>0 : end
	if pat&64>0 : move=4 : else : move=1
	mxv=(pat>>2&1)-(pat&1)
	myv=(pat>>3&1)-(pat>>1&1)
	mx=mxv*move+mx : my=myv*move+my
	if mx<0   : mx=0
	if mx>640 : mx=640
	if my<0   : my=0
	if my>480 : my=480

	color 192,192,192
	pos 320,0 : line 320,480
	pos 0,240 : line 640,240
	color 0,0,0
	pos 320,240 : line mx,my
	boxf 319,239,321,241
	boxf mx-1,my-1,mx+1,my+1
	cx=mx-320 : cy=-my+240
	pos 0,0  : color 0,0,0 : mes "座標:("+cx+","+cy+")"
	pos 0,20 : mes "距離:"+dst+"pt"
return

※CTRLを押しながらだと、点が素早く動く。

このスクリプトのポイントは3点。
  1. あらかじめ2乗の値を配列に格納しておく
  2. 2点のx,y座標の差(dx,dyの絶対値)を求め、その2乗を足す( → dst )
  3. dstと格納しておいた配列とを比較し、配列がdstより大きくなったらその要素番号が距離になる
要は、用意しておいた値と比較するっていうところが今回のミソ。この方法だと正確な値を求めることはできないけど、だいたいの距離を把握したいのなら必要にして充分。拡張dll使って平方根求めると、特に必要のない(と言うよりむしろ邪魔)な小数点以下まで出てきちゃうしね。

ちなみに乗数を900個用意したのは、640x480の斜めの長さは約832だから。つまり、これだけ用意しておけば640x480のウィンドウをややはみ出すような2点間の距離も求められるってわけ。今回のスクリプトの場合中心からの距離を求めてるから、本当は400個も用意しておけば充分。例えば10段階程度で距離を求めたいなら、10個用意すれば充分なわけで、処理速度にもそれほど影響はない。

前のページへ戻る 奮闘記のメニューへ戻る 次のページへ進む