爆発
敵機が撃墜されても消えるだけなのでリアル感が無いです。そこで爆発のアニメーションを付けます。対象は味方機と敵機の衝突、機関銃による敵機の撃墜、戦闘機(自機)と敵機や味方機との衝突です。
画像
爆破の画像は次のモノを利用します。1つ画像に3つの爆発場面があり、時間の経過に応じ切抜きながら利用します(ハンドリング方法は「drawImage」を参照してください)。
画像のハンドリングを行うため<img>タグで読み込み、IDを利用してJavaScriptで要素を取得します。
1 2 3 4 5 |
<div style="display:none"><img src="./images/bakuha_2.png" id="bakuha"></div> ・ ・ ・ var bakuha = document.getElementById("bakuha"); |
爆破場面(シーン)は3つありますので、これを定数で定義しておきます。
1 |
var BAKUHA_SCENE = 3; //爆破シーン数 |
画像を切抜く際にはこれを多用することになります。
爆破アニメーション管理
敵機、味方機の爆発状態を管理するため敵機管理している変数を利用します。
敵機や味方機が爆破されると敵機情報[0]を「爆破」にします。そして時間の経過に応じて前述画像を切抜いて表示します。
時間の経過は敵機情報[1]を流用します。ここに描画処理が呼ばれる度に1加算し時間経過を測定します。時間が下記に定義した定数より大きければ次のシーンに切り替えます。
1 |
var BAKUHA_INTER = 30; //爆発シーン間隔 |
爆発処理
5行目で表示する爆発シーンを時間の経過数(te[j][1])からシーン切替数で除算することにより求めています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* 爆破処理 */ function fire(j){ var step = Math.floor(te[j][1] / BAKUHA_INTER);//爆発シーン算出 //爆発画像を敵機の中心に表示する ctx.drawImage(bakuha,(bakuha.width/BAKUHA_SCENE)*step,0, bakuha.width/BAKUHA_SCENE,bakuha.height, te[j][2]+bakuha_width_teki,te[j][3]+bakuha_height_teki, bakuha.width/BAKUHA_SCENE,bakuha.height); te[j][1] = te[j][1] + 1; if(te[j][1]>BAKUHA_INTER * BAKUHA_SCENE){//爆発シーンが全て表示 te[j][0] = TEKI_ON; } te[j][3] = te[j][3] + BAKUHA_SPEED;//爆発画像を下に移動する } |
爆発画像は敵機座標の中心に表示する必要があります。しかし画像サイズが違うため敵機座標で爆発画像を描画すると中心からズレてしまいます。
中心に表示するため事前に縦横サイズ差の1/2を計算します。
1 2 |
var bakuha_width_teki = (teki_x_size - bakuha.width/3)/2; var bakuha_height_teki =(teki_y_size - bakuha.height)/2; |
このサイズ差を用いて爆発画像の座標を求めます。
7 8 9 10 |
ctx.drawImage(bakuha,(bakuha.width/BAKUHA_SCENE)*step,0, bakuha.width/BAKUHA_SCENE,bakuha.height, te[j][2]+bakuha_width_teki,te[j][3]+bakuha_height_teki, bakuha.width/BAKUHA_SCENE,bakuha.height); |
敵機描画
戦闘機、味方機、敵機が衝突した時に爆破アニメーションを行います。敵機描画処理を次のように変更します。
機の状態が「爆破」なら前述した爆発処理を呼び出します(5行目~8行目)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
・ ・ ・ for(var i=0;i<te.length;i++){//出撃中の敵機を探す if( te[i][0] == TEKI_BAKUHA){ //爆破処理 fire(i); continue; } ・ ・ if(ret > COLLISION_ANYTHING){ //衝突しているか? if( (te[i][0] != te[ret][0] ) && //味方機と衝突? (te[i][0] == TEKI_FIGHT_MIKATA || te[ret][0] == TEKI_FIGHT_MIKATA)){ te[i][0] = TEKI_BAKUHA; //両機とも爆発 te[i][1] = 0; te[ret][0] = TEKI_BAKUHA; te[i][1] = 0; continue; }else{ //敵機同士、味方機同士 ・ ・ //戦闘機と衝突しているか if(collision(te[i][2],te[i][3],teki_x_size,teki_y_size, my_x,canvas.height-my_y_size-10,my_x_size,my_y_size)){ te[i][0] = TEKI_BAKUHA; te[i][1] = 0; my_die = true; final(); } |
衝突後に味方機、敵機の状態を「待機中」にしていましたが、「爆破」(TEKI_BAKUHA)にし、時間経過を管理するte[x][1]を0にしています(14行~17行、25行~26行)。
弾丸描画
敵機や味方機に弾が当たると爆破アニメーションを行います。弾丸描画処理を次のように変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
・ ・ ・ if( ret > COLLISION_ANYTHING){ // 衝突 bullet[i][0] = BULLET_OFF; if( te[ret][0] == TEKI_FIGHT_MIKATA){ //味方機と衝突? te[ret][0] = TEKI_BAKUHA; te[ret][1] = 0; final(); }else{ //敵機 te[ret][0] = TEKI_BAKUHA; te[ret][1] = 0; } } ・ ・ |
自機描画
戦闘機と敵機や味方機が衝突すると敵機、味方機の爆破アニメションを行います。自機描画処理(myMove())を次のように変更します。
1 2 3 4 5 6 7 8 9 10 11 12 |
・ ・ ・ //敵機と衝突しているか ret = colliTeki(my_x,canvas.height-my_y_size-10,my_x_size,my_y_size); if(ret != COLLISION_NOTHING){ te[ret][0] = TEKI_BAKUHA; te[ret][1] = 0; final(); } ・ ・ |
実行
射撃で敵機を爆破できるか、味方機と敵機が衝突した時、戦闘機と味方機や敵機が衝突した時に爆破されるか確認します。実行画面へ