第28回【シューティング制作.8】


まずは動画を見てくださいね!
JavaScriptでシューティング制作です!
敵を動かす、敵が弾を出すという所をやってます・・・動かすのはともかく、弾の発射に三角関数を使ってますので、その辺りを重点的に解説しています・・・数学は苦手です!
今回はソースコード自体はそんなに追加していません。

敵の移動部分

敵クラスのupdateメソッドをいじります。
teki.js/Teki class
	update()
	{
		super.update();
		
		if( jiki.x > this.x ) this.vx+= 4;
		if( jiki.x < this.x ) this.vx-= 4;
	}
X方向について自機と敵を比較します。
自機の方が大きかったら、移動量を+方向に加算
自機の方が小さかったら、移動量を-方向に減算しています。

結果、横方向の移動量が多すぎる。
	if( jiki.x > this.x && this.vx<120 ) this.vx+= 4;
	else if( jiki.x < this.x && this.vx>-120) this.vx-= 4;
なので、リミッターをつけて移動量は最大120にする。

次に近づいた時に上に逃げる様にします。
	this.flag = false;
	...
	...
	if( Math.abs( jiki.y-this.y ) < (100<<8)  )
	{
		this.flag = true;
	}
プロパティにflagを追加して、自機に近づいたらフラグを立てます。
Math.absは絶対値を取得するメソッドでマイナスだったらプラスにするだけです。
abs( 100) → 100
abs(-100) → 100

	if( this.flag && this.vy>-800) this.vy-=30;
そして、フラグが立っている時は、縦方向の移動量(vy)を減算します。
一応-800をリミットとしています。


	if( !this.flag )
	{
		if( jiki.x > this.x && this.vx<120 ) this.vx+= 4;
		else if( jiki.x < this.x && this.vx>-120) this.vx-= 4;
	}
	else
	{
		if( jiki.x < this.x && this.vx<400 ) this.vx+= 30;
		else if( jiki.x > this.x && this.vx>-400) this.vx-= 30;
	}
逃げる時は横方向の移動を逆にして、また加減算の量、リミットも多くしました。
これでとりあえず敵の動きは完了です。

弾クラスと発射

敵が弾を発射できるように弾クラスを作ります。
//敵弾クラス
class Teta extends CharaBase
{
	
}
と言っても特にやることもないので、CharaBaseそのままで中身は空です。

敵がflagをtrueにする時に発車することとします。
まだ作っていませんが、teta[]配列にpushします。
	if( Math.abs( jiki.y-this.y ) < (100<<8)  )
	{
		teta.push( new Teta( 15,this.x, this.y, 0, 1200 ) );
	}
スプライト番号は15を使用しました。
ベクトルはとりあえず下方向に1200としてます。

メイン側でupdate,drawメソッドを呼ぶようにします。
main.js
...
let teta=[];
...
	updateObj(teta);
...
	drawObj( teta );
...
これで敵が弾を発射するようになりました。レーザーの様に。


角度の計算について



始点から見て目標への角度を取得するにはアークタンジェントを使います。
角度=atan(高さ/底辺)で求まります。
高さは、jiki.y(目標)-this.y(始点)
底辺は、jiki.x(目標)-this.x(始点)
アークタンジェントはatanではなく、Math.atan2を使います。
	an= Math.atan2( jiki.y-this.y, jiki.x-this.x );
これで簡単に角度が求められました。
尚、三角関数にはラジアンという単位が使われるため、普通の0°~360°にするには、(180/π)で掛ける必要があります。


角度からのベクトル計算について



角度からベクトルを計算する場合はサイン・コサインを使います。
x座標=cosθ
y座標=sinθ
で簡単に求まります。
尚、この場合は半径は1として、cos,sinはそれぞれ0~1までの間を返しています。
なので、移動量は別途掛ける必要があります。
	dx = Math.cos( an )* 1000;
	dy = Math.sin( an )* 1000;
今回は移動スピードとして1000を掛けました。実際は1000/256ピクセルで、1フレームに約4ピクセル動く速度です。


ピタゴラスの定理(三平方の定理)



移動量は、ピタゴラスの定理(三平方の定理)で求める事もできます。
この場合は角度を求めません。
c2 = a2 + b2
(2は二乗と見てください)
つまり、
c = √a2 + b2
JavaScriptではsqrtを使います。
c = Math.sqrt( (jiki.y-this.y)**2 , (jiki.x-this.x)**2 ); これで斜めの辺の長さが求められます。
この長さを1としますので、x,yのベクトルは
vx = a/c;
vy = b/c;
で求める事ができます。

以上、数学の話(?)でした・・・。
次回に続く・・・



akichon/あきちょん
Youtubeでプログラミング講座やってるゲーム好きの(元?)プログラマ...
>>open profile...
■Twitter始めました
https://twitter.com/ak1chon
■Youtubeチャンネルはこちら
akichon(Youtube)