第24回【シューティング制作.4】


まずは動画を見てくださいね!
JavaScriptでシューティング制作です!
自機の移動と微アニメ、カメラの移動をしています。
ちょっと長くなってしまいました。。

自機クラスを作ります

//自機クラス
class Jiki
{
	constructor()
	{
		this.x = (FIELD_W/2)<<8;
		this.y = (FIELD_H/2)<<8;
	}
}
let jiki = new Jiki();
自機を移動させるためには自機の情報(とりわけ座標)が必要なので、自機クラスを作ります。
初期位置はフィールドの中心にしました。


//自機クラス
class Jiki
{
	constructor()
	{
		this.x = (FIELD_W/2)<<8;
		this.y = (FIELD_H/2)<<8;
		this.anime = 0;
	}
	
	//自機の移動
	update()
	{
		
	}
	
	//描画
	draw()
	{
		drawSprite(2 + this.anime, this.x, this.y );
	}
}
Jikiクラスには、移動用のupdate()メソッドと、描画用のdraw()メソッドを作り、前回使ったdrawSprite()関数で自機を表示しました。


//ゲームループ
function gameLoop()
{
	//移動の処理
	
	for(let i=0;i<STAR_MAX;i++)star[i].update();
	jiki.update();
	
	
	//描画の処理
	
	vcon.fillStyle="black";
	vcon.fillRect(0,0,SCREEN_W,SCREEN_H);
	
	for(let i=0;i<STAR_MAX;i++)star[i].draw();
	jiki.draw();
	
	//仮想画面から実際のキャンバスにコピー
	
	con.drawImage( vcan ,camera_x,camera_y,SCREEN_W,SCREEN_H,
		0,0,CANVAS_W,CANVAS_H);
}
メインループ内で、jiki.update()と、jiki.draw()メソッドを呼びます。
これで自機スプライトの描画は完了です。


キーボードイベントの受け取り

//キーボードの状態
let key=[];

//キーボードが押されたとき
document.onkeydown = function(e)
{
	key[ e.keyCode ] = true;
}

//キーボードが離されたとき
document.onkeyup = function(e)
{
	key[ e.keyCode ] = false;
}
キーボードが押されたときに、押されたキーを覚えて起くためtrueにして、離された時に覚えたキーをfalseにします。
これで常にkey[ xxx ]で押されているかどうかが確認できます。
当然、使うキーだけ覚えれば良いのですが...手抜きです。
キーボードだけじゃなく、ゲームパッドとかの対応をするにはもうちょっと工夫した方がいいですね。



キーボードを見て自機を移動する

...
	this.speed = 512;
...
//自機の移動
	update()
	{
		if( key[37] )this.x-=this.speed;
		if( key[38] )this.y-=this.speed;
		if( key[39] )this.x+=this.speed;
		if( key[40] )this.y+=this.speed;
	}
自機のプロパティーに移動スピードを持たせて、押されたキーによって移動スピード分だけ座標を加減します。


//自機の移動
	update()
	{
		if( key[37] && this.x>this.speed )
		{
			this.x-=this.speed;
			if(this.anime>-8 )this.anime--;
		}
		else if( key[39] && this.x<= (FIELD_W<<8)-this.speed )
		{
			this.x+=this.speed;
			if(this.anime<8  )this.anime++;
		}
		else
		{
			if(this.anime>0) this.anime--;
			if(this.anime<0) this.anime++;
		}
		
		if( key[38] && this.y>this.speed )
			this.y-=this.speed;
		
		if( key[40] && this.y<= (FIELD_H<<8)-this.speed)
			this.y+=this.speed;
	}
	
	//描画
	draw()
	{
		drawSprite(2 + (this.anime>>2), this.x, this.y );
	}
横に移動した時に傾くアニメーションを入れました。
同時に範囲外へは行かない様にしています。
移動後に範囲外の時は戻すような処理でもいいですね。
	//これは動画とは別パターンの例
	//(動作未確認)
	
	//自機の移動
	update()
	{
		if( key[37] )
		{
			this.x-=this.speed;
			if(this.anime>-8 )this.anime--;
		}
		else if( key[39] )
		{
			this.x+=this.speed;
			if(this.anime<8  )this.anime++;
		}
		else
		{
			if(this.anime>0) this.anime--;
			if(this.anime<0) this.anime++;
		}
		if( key[38] )this.y-=this.speed;
		if( key[40] )this.y+=this.speed;
			
		//ここで範囲チェックする
		if(this.x<0)this.x=0;
		if(this.x>=(FIELD_W<<8))this.x=(FIELD_W<<8)-1;
		if(this.y<0)this.y=0;
		if(this.y>=(FIELD_H<<8))this.y=(FIELD_H<<8)-1;
	}
こっちの方がシンプルかも??



カメラを自機に合わせて移動させる

//ゲームループ
function gameLoop()
{
	//移動の処理
	
	for(let i=0;i<STAR_MAX;i++)star[i].update();
	jiki.update();
	
	
	//描画の処理
	
	vcon.fillStyle="black";
	vcon.fillRect(camera_x,camera_y,SCREEN_W,SCREEN_H);
	
	for(let i=0;i<STAR_MAX;i++)star[i].draw();
	jiki.draw();
	
	// 自機の範囲 0 ~ FIELD_W
	// カメラの範囲 0 ~ (FIELD_W-SCREEN_W)
	
	camera_x = (jiki.x>>8)/FIELD_W * (FIELD_W-SCREEN_W);
	camera_y = (jiki.y>>8)/FIELD_H * (FIELD_H-SCREEN_H);
	
	//仮想画面から実際のキャンバスにコピー
	
	con.drawImage( vcan ,camera_x,camera_y,SCREEN_W,SCREEN_H,
		0,0,CANVAS_W,CANVAS_H);
}
カメラの位置をなるべく自機に合わせるようにしました。
基本カメラは中心で、ある程度端っこにいったらスクロールとかでもいいかもしれません(おこのみで)
画面クリアもカメラ部分をクリアするように修正しました。


次回は自機から弾を発射します。
続く...



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