衝突パターン
味方機の衝突パターンは次の通りです。
敵機との違いは敵機と衝突すると両機とも爆発、弾丸と衝突するとゲーム終了となることです。これらを実装していきます。
敵機衝突
味方機と敵が衝突した場合は両機とも爆発させるので衝突機の情報が必要です。しかし敵機同士の衝突判定を行っている関数colliTekivsTeki()は、衝突有の時にtrueを返すだけです。そこで戻り値を変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
/* 敵機同士の衝突確認 引数: j 判定機の配列インデックス 戻り値: COLLISION_NOTHING 衝突無し COLLISION_ANYTHING以上 衝突有り 配列インデクスが戻る */ function colliTekivsTeki(j){ for(var i=0;i<te.length;i++){//出撃中の敵機を探す if( i==j){ //同じ機なら判定しない continue; } if(te[i][0]==TEKI_FIGHT_TEKI || te[i][0] ==TEKI_FIGHT_MIKATA){ if(collision(te[i][2],te[i][3],teki_x_size,teki_y_size, te[j][2],te[j][3],teki_x_size,teki_y_size)){ return i; //衝突した配列インデックスを戻す } } } return COLLISION_NOTHING; } |
衝突があった場合に衝突した配列のインデックスを返すようにします。
定数として次の内容を定義しました。衝突無しの時は-2。衝突有の時は配列のインデックスが返るので-1以上の数値が返ります。これを判断するための定数「COLLISION_ANYTHING」も定義しています。
1 2 |
var COLLISION_NOTHING = -2; //衝突なし var COLLISION_ANYTHING = -1; //衝突有り |
敵機描画処理の衝突判定を次のように変更します。
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
/* 敵機描画 */ function tekiMove(){ teki_count++; if(teki_count>TEKI_INTER){//出撃間隔に達した? fight(); teki_count = 0; } for(var i=0;i<te.length;i++){//出撃中の敵機を探す if(te[i][0] == TEKI_FIGHT_TEKI || te[i][0] == TEKI_FIGHT_MIKATA){ if( te[i][0]==TEKI_FIGHT_MIKATA){//味方機描画 ctx.drawImage(mikata,te[i][2],te[i][3],teki_x_size,teki_y_size); }else{ //敵機描画 ctx.drawImage(teki,te[i][2],te[i][3],teki_x_size,teki_y_size); } tmp_x = te[i][2]; //横座標保管 tmp_y = te[i][3]; //縦座標保管 tmp_houkou=-1; //衝突時方向変数 switch(te[i][1]){ case H_LEFT: //左方向へ進む te[i][2] = te[i][2] - te[i][4]/2; te[i][3] = te[i][3] + te[i][4]/2; tmp_houkou = H__RIGHT;//衝突時方向設定 break; case H_CENTER://真ん中方向へ進む te[i][3] = te[i][3] + te[i][4]; tmp_houkou = H_CENTER;//衝突時方向設定 break; case H__RIGHT://右方向へ進む te[i][2] = te[i][2] + te[i][4]/2; te[i][3] = te[i][3] + te[i][4]/2; tmp_houkou = H_LEFT;//衝突時方向設定 break; } var ret = colliTekivsTeki(i); 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_ON; //両機とも爆発 te[ret][0] = TEKI_ON; continue; }else{ //敵機同士、味方機同士 te[i][2] = tmp_x; //横座標を戻す te[i][3] = tmp_y; //縦座標を戻す te[i][1] = tmp_houkou;//衝突時方向に設定 continue; } } //戦闘機と衝突しているか 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_ON; final(); } if( te[i][3] > canvas.height){//下画面はみ出し? te[i][0] = TEKI_ON; final(); } if( te[i][2] < 0){ //左画面はみ出し? te[i][2] = 0; te[i][1] = H__RIGHT; } if( te[i][2] > canvas.width - teki_x_size){//右画面はみ出し? te[i][2] = canvas.width - teki_x_size; te[i][1] = H_LEFT; } } } } |
弾丸衝突
弾丸と味方機が衝突した場合はゲーム終了なので衝突した機の情報が必要です。しかし弾丸と敵機の衝突判定を行っている関数colliTeki()も、衝突有の時にtrueを返すだけです。そこで戻り値を変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/* 敵機との衝突判定 引数: x・・・横座標、y・・・縦座標 lx・・・横幅、ly・・・縦幅 戻り値: COLLISION_NOTHING 衝突無し COLLISION_ANYTHING以上 衝突有り 配列インデクスが戻る */ function colliTeki(x,y,lx,ly){ for(var i=0;i<te.length;i++){//出撃中の敵機を探す if(te[i][0]==TEKI_FIGHT_TEKI || te[i][0]==TEKI_FIGHT_MIKATA ){ if(collision(te[i][2],te[i][3],teki_x_size,teki_y_size, x,y,lx,ly)){ return i; //衝突した配列インデックスを返す } } } return COLLISION_NOTHING; } |
弾丸処理の衝突判定を次の通り変更します。
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 30 31 32 33 34 35 36 37 38 |
/* 弾丸描画 */ function bulletMove(){ if(bullet_flg==true){ //スペースキーが押されているか bullet_count++; if(bullet_count > BULLET_INTER){ //発射間隔を過ぎているか shot(my_x+my_x_size/2,canvas.height-my_y_size-10);//発射 bullet_count = 0; } } 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; //弾丸終了 } var ret = colliTeki(bullet[i][1],bullet[i][2], BULLET_WIDTH,BULLET_HEIGHT); if( ret > COLLISION_ANYTHING){ // 衝突 if( te[ret][0] == TEKI_FIGHT_MIKATA){ //味方機と衝突? bullet[i][0] = BULLET_OFF; te[ret][0] = TEKI_ON; final(); }else{ //敵機 bullet[i][0] = BULLET_OFF; //弾丸終了 te[ret][0] = TEKI_ON; } } } } } |
実行
赤い味方機の衝突処理を確認します。実行画面へ
登場人物が揃いました。次のステップへ進みます。
ソースコードを掲載します。