敵のショット位置について
Posted: 2008年2月05日(火) 12:39
初めまして、いつも拝見させてもらってます。ここのソースファイルを写していたんですが、敵が移動しても敵のショットの出る場所が変わりません。また、敵を倒してもショットが出続けるんですけど、どうすればいいか教えてください。
typedef struct{ int flag; double x,y; } ENEMY_SHOTS_t; //1組の弾が持つ情報 typedef struct{ int flag,pattern,counter,img; double mem_ex,mem_ey,mem_px,mem_py,Angle[ENEMY_TOTAL_SHOT_NUM];//[200]; ENEMY_SHOTS_t EnemyShots[ENEMY_TOTAL_SHOT_NUM];//[200]; } ENEMY_SHOT_t;------------------------------------
void EnemyPattern2(int i){
int j;
if(enemy.counter<50)
enemy.y+=4.0f;
if(enemy.counter==75){//エネミーカウンターが75の時
for(j=0;j < ENEMY_TOTAL_NUM ;j++)//発射されていない弾を探す。
if(EnemyShot[j].flag==0)//あったらそこでiを保持してブレイク
break;
EnemyShot[j].flag=1;//発射フラグを立てる
EnemyShot[j].mem_ex=enemy.x;//弾の初期x座標を敵の座標から設定する
EnemyShot[j].mem_ey=enemy.y;//同様y
EnemyShot[j].mem_px=Player.x;//うつ瞬間のプレイヤーの座標を記憶
EnemyShot[j].mem_py=Player.y;//同様y
EnemyShot[j].counter=0;//カウンターを初期化
EnemyShot[j].pattern=1;//ショットパターン1とする※1
EnemyShot[j].img=0;//画像タイプは0とする※2
}
if(enemy.counter>100)
enemy.y-=4.0f;
}
void EnemyCalcDisp(){ int i; for(i=0;i<100;i++) if(enemy.flag==0) break; switch(counter){//今回はパターン2の動きだけさせる case 50: enemy.pattern=2; //どういう軌道を描くか enemy.flag=1; //出現フラグを立てる enemy.counter=0;//出現して何カウント目か測るカウンター初期化 enemy.size=0.5f;//敵の大きさ enemy.x=100.0; //xの初期座標 enemy.y=-10.0; //yの初期座標 break; default: break; } int enemy_img[8]={0,1,2,3,4,3,2,1}; for(i=0;i<100;i++){ if(enemy.flag==1){ enemy.counter++; DrawRotaGraph( (int)enemy.x , (int)enemy[i].y , enemy[i].size , 0.0f , img_enemy1[enemy_img[counter%32/4]] , TRUE ) ; if(enemy[i].x<0.0-MONSTER1_X_SIZE/2.0*enemy[i].size || enemy[i].x>420.0+MONSTER1_X_SIZE/2.0*enemy[i].size || enemy[i].y<0.0-MONSTER1_Y_SIZE/2.0*enemy[i].size || enemy[i].y<0.0-MONSTER1_Y_SIZE/2.0*enemy[i].size) enemy[i].flag=0; } } }
//敵 typedef struct{ double x,y,size; int flag,counter,hp,pattern,range; } BODY_enemy_t; BODY_enemy_t enemy[ENEMY_TOTAL_NUM]; //[100] //個々の弾の情報 typedef struct{ int flag; double x,y,angle,disp_angle,speed; } ENEMY_SHOTS_t; //ENEMY_SHOTS_t EnemyShots[ENEMY_TOTAL_SHOT_NUM]; //[200]; //1組の弾の情報 typedef struct{ int flag,pattern,counter,img; // double mem_ex,mem_ey,mem_px,mem_py,Angle[ENEMY_TOTAL_SHOT_NUM]; //[200]; double mem_ex,mem_ey,mem_px,mem_py,Enx[60],Eny[60]; //[200]; ENEMY_SHOTS_t EnemyShots[ENEMY_TOTAL_SHOT_NUM]; //[200]; BODY_enemy_t enemy[ENEMY_TOTAL_NUM]; //[100] } ENEMY_SHOT_t; ENEMY_SHOT_t EnemyShot[ENEMY_TOTAL_NUM]; //[100]; -----------------------------------enemy_shot.cpp-------------------------------------- //敵のショットパターン3 void EnemyShotPattern3(int i){ for(int j=0;j<10;j++){ if(EnemyShot.counter==20*j){ if(EnemyShot.enemy.flag=1){ //弾を発射する敵が出たら EnemyShot.EnemyShots[j].flag=1; //発射フラグを立てる EnemyShot.EnemyShots[j].x=EnemyShot.mem_ex; EnemyShot.EnemyShots[j].y=EnemyShot.mem_ey; //現在のプレイヤーの座標と、弾の初期座標からそれぞれ角度を計算する。 EnemyShot.EnemyShots[j].angle = atan2(Player.y-EnemyShot.mem_ey, Player.x-EnemyShot[i].mem_ex); StopSoundMem(sound_enemy_shot[0]); PlaySoundMem(sound_enemy_shot[0],DX_PLAYTYPE_BACK); } EnemyShot[i].EnemyShots[j].x+=PATTERN1SPEED*cos(EnemyShot[i].EnemyShots[j].angle); EnemyShot[i].EnemyShots[j].y+=PATTERN1SPEED*sin(EnemyShot[i].EnemyShots[j].angle); }else{ break; //敵のフラグが1以外(倒されたら)ループを抜ける } } }
一番簡単なのは・・
typedef struct{
int flag,id;
double x,y,angle,disp_angle,speed;
} ENEMY_SHOTS_t;
ここにidを追加し、どの敵から発射されたものかを記憶します。
敵は弾にあたったらflagを2にします。
敵の描画はflagが1の時のみ行います。
idの敵のflagが2の時は発射しないようにします。
全ての弾が画面外になったら、idの敵のフラグは0にします。
・・とこれが一番早い実装ではないでしょうか。
しかし、お遊び程度しか対応しないこのコード・・。
本格的に作ることが出来ません。
もし本格的に作るのならば、「ステージの作り方」のトピの最後にあるサンプルを参考に、ご自分でお作りになったほうがいいかもしれません(_ _|||)
HPの更新が遅くなってすみません(汗
------------------------------------GlobalVariable.h-----------------------------------------------
//敵
typedef struct{
double x,y,size;
int flag,counter,hp,pattern,range;
} BODY_enemy_t;
BODY_enemy_t enemy[ENEMY_TOTAL_NUM]; //[100]
//個々の弾の情報
typedef struct{
int flag,id;
double x,y,angle,disp_angle,speed;
} ENEMY_SHOTS_t;
//ENEMY_SHOTS_t EnemyShots[ENEMY_TOTAL_SHOT_NUM]; //[200];
//1組の弾の情報
typedef struct{
int flag,pattern,counter,img;
double mem_ex,mem_ey,mem_px,mem_py,Enx[60],Eny[60]; //[200];
ENEMY_SHOTS_t EnemyShots[ENEMY_TOTAL_SHOT_NUM]; //[200];
BODY_enemy_t enemy[ENEMY_TOTAL_NUM]; //[100]
} ENEMY_SHOT_t;
ENEMY_SHOT_t EnemyShot[ENEMY_TOTAL_NUM]; //[100];
------------------------------------player.cpp-----------------------------------------------
//自機のショットと敵の当たり判定処理
void CollisionDetection(){
for(int i=0;i<PLAYER_MAX_SHOT1;i++){ //ショットの全列分
for(int j=0;j<PLAYER_MAX_SHOT2;j++){ //1列全弾分
if(PlayerShot[j].flag==1){ //その弾が発射中なら
for(int s=0;s<ENEMY_TOTAL_NUM;s++){ //全敵100体分
if(enemy.flag==1){ //その敵が出現中なら
double x,y;
int range;
x=(int)(PlayerShot[j].x-enemy.x);
y=(int)(PlayerShot[j].y-enemy.y);
switch(i){
case 0: //0列目と
case 5: //5列目と
case 6: //6列目の
range=12; //大きさは半径12
break;
default:
range=9; //大きさは半径9
break;
}
//当たり判定処理
if((int)sqrt(x*x+y*y) < range+enemy.range){ //当たり判定内なら
PlayerShot[j].flag=0;
enemy.hp--;
if(enemy.hp==0){
EnemyShot.EnemyShots[j].id=enemy.flag=2;
enemy.flag=0; //表示フラグを戻す
//EnemyShot.flag=0;
PlayerShot[j].flag=0; //当たった弾を消す
if(CheckSoundMem(sound_enemy_death)==1){ //消滅音が鳴っていなかったら
StopSoundMem(sound_enemy_death); //とめて
}
PlaySoundMem(sound_enemy_death, DX_PLAYTYPE_BACK); //消滅音を鳴らす
}
}
}
}
}
}
}
}
------------------------------------enemy_shot.cpp-----------------------------------------------
void EnemyShotPattern3(int i){
for(int s=0;s<ENEMY_TOTAL_NUM;s++){
if(enemy.flag==1){
break;
}
}
for(int j=0;j<10;j++){
EnemyShot.EnemyShots[j].id=enemy[s].flag=1;
if(EnemyShot.counter==20*j){
if(EnemyShot.EnemyShots[j].id=enemy[s].flag==1){
printfDx("1"); //テスト用に表示
EnemyShot.EnemyShots[j].flag=1;
EnemyShot[i].EnemyShots[j].x=EnemyShot[i].mem_ex;
EnemyShot[i].EnemyShots[j].y=EnemyShot[i].mem_ey;
//現在のプレイヤーの座標と、弾の初期座標からそれぞれ角度を計算する。
EnemyShot[i].EnemyShots[j].angle = atan2(Player.y-EnemyShot[i].mem_ey, Player.x-EnemyShot[i].mem_ex);
StopSoundMem(sound_enemy_shot[0]);
PlaySoundMem(sound_enemy_shot[0],DX_PLAYTYPE_BACK);
}
if(EnemyShot[i].EnemyShots[j].id=enemy[s].flag==2){
printfDx("2"); //テスト用に表示
}
}
EnemyShot[i].EnemyShots[j].x+=PATTERN1SPEED*cos(EnemyShot[i].EnemyShots[j].angle);
EnemyShot[i].EnemyShots[j].y+=PATTERN1SPEED*sin(EnemyShot[i].EnemyShots[j].angle);
}
}
//敵のパターン2 void EnemyPattern2(int i){ if(enemy.counter<50){ enemy.y+=4.0f; } if(enemy.counter==75){ for(int j=0;j<ENEMY_TOTAL_NUM;j++){ if(EnemyShot[j].flag==0){ break; } } EnemyShot[j].mem_ex=enemy.x; //敵のx座標 EnemyShot[j].mem_ey=enemy.y; //敵のy座標 EnemyShot[j].mem_px=Player.x; //プレイヤーのx座標 EnemyShot[j].mem_py=Player.y; //プレイヤーのy座標 EnemyShot[j].counter=0; //弾が発射されてからのカウンターの初期化 EnemyShot[j].flag=1; //弾が発射されたことを示すフラグを1に EnemyShot[j].pattern=3; //ショットパターンは3を指定 EnemyShot[j].img=0; //弾の画像 } if(enemy.counter>200){ enemy.y-=4.0f; } }