衝突判定エンジン
前回紹介した衝突判定を実装します。
1 2 3 4 5 6 7 8 9 10 |
/* 衝突共通判断 四角形&四角形の衝突判定 */ function collision(x1,y1,lx1,ly1,x2,y2,lx2,ly2){ if( ((x1-lx2)<= x2) && (x2 <= (x1+lx1)) && ((y1-ly2)<= y2) && (y2 <= (y1+ly1)) ){ return true; } return false; } |
この関数を利用して敵対敵、敵対弾丸などの衝突判定を行います。
敵対敵
配列のインデクスで指定された敵機とその他敵機の衝突判定を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/* 敵機同士の衝突確認 引数: j 判定機の配列インデックス */ function colliTekivsTeki(j){ for(var i=0;i<te.length;i++){//出撃中の敵機を探す if( i==j){ //同じ機なら判定しない continue; } if(te[i][0]==TEKI_FIGHT){ 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 true; } } } return false; } |
敵機出撃
出撃時の横座標はランダムに決定しています。既に同じ座標に出撃機が存在する場合は出撃を取りやめます。
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 |
/* 出撃 */ function fight(){ count = 0; for(var i=0;i<te.length;i++){//出撃していない敵機を探す if( te[i][0] == TEKI_ON){ //横位置をランダムに決定 x = Math.round( Math.random()*(canvas.width-teki_x_size )); //方向をランダムに決定 h = Math.round( Math.random()*2); te[i][0] = TEKI_FIGHT; te[i][1] = h; te[i][2] = x; te[i][3] = teki_y_size * -1; te[i][4] = teki_speed; if(colliTekivsTeki(i)){//既に機が存在するか? te[i][0] = TEKI_ON; continue; } count++; if(count>=teki_fight_su){ //1回の出撃数を超えた? break; } } } teki_fight_su=teki_fight_su + 1; //1回の出撃数増加 teki_speed=teki_speed+0.02; //スペードアップ } |
敵機移動
描画後に各方向に移動します。移動先に機が存在するなら移動を止め、右方向移動なら左へ、左方向移動なら右へ反転させます。
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 |
/* 敵機描画 */ 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){ 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; } if(colliTekivsTeki(i)){ //衝突しているか? te[i][2] = tmp_x; //横座標を戻す te[i][3] = tmp_y; //縦座標を戻す te[i][1] = tmp_houkou;//衝突時方向に設定 } if( te[i][3] > canvas.height){//下画面はみ出し? te[i][0] = TEKI_ON; } 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; } } } } |
実行
動作を確認します。実行画面へ
敵機同士が重なり合うことが無くなりました。次に敵対弾丸の衝突判定を行います。