定数
機関銃から発射される弾丸を描画するために次の定数を定義しました。
1 2 3 4 5 6 7 |
var BULLET_KAZU=500; //弾丸数 var BULLET_ON=0; //弾丸未発射 var BULLET_SHOT=1; //弾丸発射 var BULLET_OFF=-1; //弾丸終了 var BULLET_SPEED=5; //弾丸スピード var BULLET_WIDTH=3; //弾丸横幅 var BULLET_HEIGHT=10; //弾丸縦幅 |
弾丸の描画だけでもこのように多くの情報が必要です。
変数定義
スペースキーが押されている間に連続して発射します。そのためキーが押されているかのフラグを用意します。
そして弾丸を管理するための二次元配列を定義します。まず搭載できる弾丸数の一次元配列を定義します。
1 2 |
var bullet=Array(BULLET_KAZU); //弾丸用変数 var bullet_flg = false; //発射フラグ |
次に定義した一次元配列に弾丸情報の一次元配列を格納します。これで二次元配列になります。(二次元配列の初期化については初期値が無い二次元配列が参考になります)
1 2 3 |
for(let i = 0; i < bullet.length; i++) { //弾丸管理変数初期化 bullet[i] = [0,0,0]; } |
スペースキーが押された時
スペースキーが押された時にフラグをON(true)にします。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* キーが押された時 */ function keyDown(e){ if(e.key == "ArrowRight") { //右矢印 my_houkou = MY_SPEED; }else if(e.key == "ArrowLeft") {//左矢印 my_houkou = MY_SPEED * -1; } if(e.keyCode==32){ //スペースキー bullet_flg = true; } } |
スぺスキーの判定を「e.keyCode==32」としています。本来は他キーと同様に「e.key == “Space”」としたいのですが、キー値が取得できませんでした。そのため「e.keyCode」を利用しコードで判定しています。(その他コードは「MDN web docs」をご覧ください)
弾丸描画
弾丸の描画は描画処理(draw())から弾丸描画処理(bulletMove())を呼び出します。
1 2 3 4 5 6 7 8 |
/* 描画処理 */ function draw(){ ctx.clearRect(0, 0, canvas.width, canvas.height); myMove(); //自機を描画 bulletMove(); //弾丸描画 } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/* 弾丸描画 */ function bulletMove(){ if(bullet_flg==true){ //スペースキーが押されているか shot(my_x+my_x_size/2,canvas.height-my_y_size-10);//発射 } for(var i=0;i<bullet.length;i++){ //発射されている全弾丸を描画 if(bullet[i][0] == BULLET_SHOT ){ ctx.fillStyle = "yellow"; ctx.lineWidth = 1; ctx.fillRect(bullet[i][1]-BULLET_WIDTH/2,bullet[i][2]-BULLET_HEIGHT,BULLET_WIDTH,BULLET_HEIGHT); bullet[i][2] = bullet[i][2] - BULLET_SPEED; //弾丸を進める if(bullet[i][2]<0){ //弾丸が一番上に達したか bullet[i][0] = BULLET_OFF; //弾丸終了 } } } |
6行目~8行目でスペースキーが押されているなら後述する発射処理(shot())を呼び出しています。
10行目~20行目では全弾丸の中から「発射中」を探し描画しています。そして描画後に弾丸を進めています。ここで弾丸が画面上に達したなら状態を「弾丸無し」にしています(16行~18行)
発射処理
発射処理は全弾丸の中から「未発射」を検索し「発射中」にしています。その際に弾丸の座標を設定しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* 発射 */ function shot(x,y){ for(var i=0;i<bullet.length;i++){//発射されていない弾丸を探す if(bullet[i][0] == BULLET_ON){ bullet[i][0] = BULLET_SHOT; bullet[i][1] = x; bullet[i][2] = y; break; } } } |
弾丸の座標は発射処理呼び出し時に引数で設定しています。
1 |
shot(my_x+my_x_size/2,canvas.height-my_y_size-10);//発射 |
戦闘機の機首に機関銃があるので、真ん中から弾丸が発射されないといけません。X、Y座標の計算式が複雑なので下記に図示します。
スペースキーが離されたら
スペースキーが離されたら発射を止めます。そのためフラグをOFF(false)にします。その処理が10行目~12行目です。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* キーを離した時 */ function keyUp(e){ if(e.key == "ArrowRight") { //右矢印 my_houkou = 0; }else if(e.key == "ArrowLeft") {//左矢印 my_houkou = 0; } if(e.keyCode==32){ //スペースキー bullet_flg = false; } } |
実行
実行し動作を確認します。
実行画面へ
スペースキーを押し続けると弾丸がつながって見えます。描画処理が呼び出される度に発射されるので、このように見えてしまいます。リアル感が無いので次回は発射間隔を設けます。