ページ 11

DXライブラリのシューティングで

Posted: 2011年6月05日(日) 17:34
by うすしお
ゲームプログラミングの館などの色々なサイトを参考にしてDXライブラリでシューティングゲームを作成しているのですが、うまくいかないことがあり困ってます
出てくる敵が自機に向かって弾を撃つようにしたいのですが

コード:

#include "DxLib.h"
#include <math.h>
#define PI 3.141593
#define PATTERN1SPEED 4.0f

#define PLAYER_MAX_SHOT1 5
#define PLAYER_MAX_SHOT2 8

#define ENEMY_TOTAL_NUM 100
#define ENEMY_TOTAL_SHOT_NUM 1

#define ENEMY1_X_SIZE 26.0
#define ENEMY1_Y_SIZE 35.0

//グローバル関数
int counter=0;
int color_white;
char Key[256];

//画像
int img_background[2];
int img_player;
int img_player_shot;
int img_enemy1;
int img_enemy_shot1;


//構造体

//プレイヤー
typedef struct{
        double x,y;
        int status,counter;
        int shot [11][15];
} BODY_player_t;

BODY_player_t Player;

//敵
typedef struct{
        double x,y,size;
        int flag,counter,hp,pattern,range;
} BODY_enemy_t;

BODY_enemy_t enemy[ENEMY_TOTAL_NUM];

//弾
typedef struct{
        double x,y;
        int flag;
} SHOT_t;

SHOT_t PlayerShot[PLAYER_MAX_SHOT1][PLAYER_MAX_SHOT2];

typedef struct{
        int flag;
        double x,y;
} ENEMY_SHOTS_t;

//敵ショット
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;

ENEMY_SHOT_t EnemyShot[ENEMY_TOTAL_NUM];//[100];


//画像読み込み
void img_load(){
    img_background[0] = LoadGraph("background1.png");
    img_background[1] = LoadGraph("background2.png");
    img_player = LoadGraph("player.png");
    img_player_shot = LoadGraph("shot.png");
	img_enemy1 = LoadGraph("enemy1.png");
	img_enemy_shot1 = LoadGraph("enemy_shot1.png");
}

//初期化
void initialization(){
	int i;
    Player.x = 225.0;
    Player.y = 400.0;
    Player.counter = 0;
    Player.status = 0;

    for(int i=0; i<PLAYER_MAX_SHOT1; i++)
             for(int j=0; j<PLAYER_MAX_SHOT2; j++)
                    PlayerShot[i][j].flag = 0;

	for(i=0;i<ENEMY_TOTAL_NUM;i++){
             enemy[i].flag=0;
                EnemyShot[i].flag=0;
                for(int j=0;j<ENEMY_TOTAL_SHOT_NUM;j++)
                        EnemyShot[i].EnemyShots[j].flag=0;
	}

}

//背景の描画
void Background(){
    DrawGraph(0,0,img_background[0],FALSE);
    DrawGraph(450,0,img_background[1],FALSE);
}

//プレイヤーの操作
void PlayerControl(){
    if(Key[KEY_INPUT_LEFT] == 1){
            Player.x -= 5.0f;
            if(Player.x < 10.0)
                   Player.x = 10.0;
     }

    if(Key[KEY_INPUT_RIGHT] == 1){
            Player.x += 5.0f;
            if(Player.x > 435.0)
                   Player.x = 435.0;
     }

    if(Key[KEY_INPUT_UP] == 1){
            Player.y -= 5.0f;
            if(Player.y < 0.0)
                   Player.y = 0.0;
     }

    if(Key[KEY_INPUT_DOWN] == 1){
            Player.y += 5.0f;
            if(Player.y > 435.0)
                   Player.y = 435.0;
     }

    DrawGraph((int)Player.x-15,(int)Player.y+5,img_player,TRUE);//プレイヤーを描画
}

//弾の発射
void PlayerShotCalc(){
	int j;

    if(Key[KEY_INPUT_Z]==1 && counter%8==0){

         for(j=0;j<PLAYER_MAX_SHOT2;j++){

               if(PlayerShot[0][j].flag == 0){
                     PlayerShot[0][j].flag=1;
                     PlayerShot[0][j].x=Player.x;
                     PlayerShot[0][j].y=Player.y;
                     break;
		    }
        }
    }

    for(j=0; j<PLAYER_MAX_SHOT2; j++){

         if(PlayerShot[0][j].flag == 1){
               PlayerShot[0][j].y -= 10;

               if(PlayerShot[0][j].y < -20)
                     PlayerShot[0][j].flag = 0;
        }
    }
}

//弾の描画
void PlayerShotDisp(){
    int j;

    for(j=0;j<PLAYER_MAX_SHOT2;j++){

         if(PlayerShot[0][j].flag==1){
			   DrawGraph(PlayerShot[0][j].x-5,PlayerShot[0][j].y-10,img_player_shot,TRUE);
        }
    }
}

//敵のパターン1
void EnemyPattern1(int i){
	  int j;
               enemy[i].y += 2.0f;

        if(enemy[i].counter==75){
                for(j=0;j<ENEMY_TOTAL_NUM;j++)
                        if(EnemyShot[j].flag==0)
                                break;
        EnemyShot[j].mem_ex=enemy[i].x;
        EnemyShot[j].mem_ey=enemy[i].y;
        EnemyShot[j].mem_px=Player.x;
        EnemyShot[j].mem_py=Player.y;
        EnemyShot[j].counter=0;
        EnemyShot[j].flag=1;
        EnemyShot[j].pattern=1;
        EnemyShot[j].img=0;
		}

}

//敵の設定
void EnemyControl(){
        for(int i=0;i<50;i++)
            if(enemy[i].flag==1)
                if(enemy[i].pattern==1)
                     EnemyPattern1(i);
}

//敵の描画
void EnemyCalcDisp(){
        int i;
        for(i=0; i<50; i++)
                if(enemy[i].flag == 0)
                        break;
        switch(counter){
                case 50:
                case 90:
                case 130:
                case 170:
                case 210:
                        enemy[i].flag=1;   //出現フラグを立てる
                        enemy[i].counter=0;//出現して何カウント目か測るカウンター初期化
                        enemy[i].pattern=1;//どういう軌道を描くか
                        enemy[i].size=1.0f;//敵の大きさ
						enemy[i].range=(ENEMY1_X_SIZE)/2.0f*enemy[i].size;//あたり判定範囲
                        enemy[i].x=100.0;//xの初期座標
                        enemy[i].y=-10.0;//yの初期座標
                        break;	
                default:
                        break;
        }

        for(i=0; i<50; i++)
                if(enemy[i].flag==1)
                        DrawRotaGraph( (int)enemy[i].x, (int)enemy[i].y, enemy[i].size, 0.0f, img_enemy1, TRUE ) ;

                if(enemy[i].x<0.0-ENEMY1_X_SIZE/2.0*enemy[i].size || enemy[i].x>420.0+ENEMY1_X_SIZE/2.0*enemy[i].size || 
				   enemy[i].y<0.0-ENEMY1_Y_SIZE/2.0*enemy[i].size || enemy[i].y<0.0-ENEMY1_Y_SIZE/2.0*enemy[i].size)
                        enemy[i].flag=0;

}

//あたり判定
void CollisionDetection(){
        for(int i=0;i<PLAYER_MAX_SHOT1;i++){          
        for(int j=0;j<PLAYER_MAX_SHOT2;j++){           
        if(PlayerShot[i][j].flag==1){                	
		for(int s=0;s<ENEMY_TOTAL_NUM;s++){        

            if(enemy[s].flag==1){                  
                double x,y;
                int range;
                x=(int)(PlayerShot[i][j].x-enemy[s].x);
                y=(int)(PlayerShot[i][j].y-enemy[s].y);

                     switch(i){
                       case 0:
                       case 5:
                       case 6:
                       range=12;
                          break;
                       default:
                          range=9;
                          break;
            }

            if( (int)sqrt(x*x+y*y) < range+enemy[s].range){
                enemy[s].flag=0;
				PlayerShot[i][j].flag=0;
            }
          }
        }
      }
    }
  }
}

//敵の弾のパターン
void EnemyShotPattern1(int i){
        if(EnemyShot[i].counter==0){
                EnemyShot[i].EnemyShots[0].flag=1;
                EnemyShot[i].EnemyShots[0].x=EnemyShot[i].mem_ex;
                EnemyShot[i].EnemyShots[0].y=EnemyShot[i].mem_ey;
                EnemyShot[i].Angle[0] = atan2(EnemyShot[i].mem_py-EnemyShot[i].mem_ey,EnemyShot[i].mem_px-EnemyShot[i].mem_ex);
        }
        EnemyShot[i].EnemyShots[0].x+=PATTERN1SPEED*cos(EnemyShot[i].Angle[0]);
        EnemyShot[i].EnemyShots[0].y+=PATTERN1SPEED*sin(EnemyShot[i].Angle[0]);
}

//敵の弾の設定
void EnemyShotControl(){
     int i;
     for(i=0;i<ENEMY_TOTAL_NUM;i++){
         if(EnemyShot[i].flag==1){
                if(EnemyShot[i].pattern==1)
                        EnemyShotPattern1(i);
         }
     }
}


void EnemyShotCalcDisp(){
     for(int i=0;i<ENEMY_TOTAL_NUM;i++){

         if(EnemyShot[i].flag==1){

            EnemyShot[i].counter++;

                for(int j=0;j<ENEMY_TOTAL_SHOT_NUM;j++){

                     if(EnemyShot[i].EnemyShots[j].flag==1){
                        
		DrawGraph( (int)EnemyShot[i].EnemyShots[j].x, (int)EnemyShot[i].EnemyShots[j].y, img_enemy_shot1, TRUE ) ;

                        if(EnemyShot[i].EnemyShots[j].x<-20.0||EnemyShot[i].EnemyShots[j].x>440.0||EnemyShot[i].EnemyShots[j].y<-20.0||EnemyShot[i].EnemyShots[j].y>500)
                                EnemyShot[i].flag=0;
                      }
                }
            }
        }

        for(int i=0;i<ENEMY_TOTAL_NUM;i++){

            if(EnemyShot[i].flag==1){

                 for(int j=0;j<ENEMY_TOTAL_SHOT_NUM;j++){

                        if(EnemyShot[i].EnemyShots[j].flag==1){
                           return;
                        }
                 }
                        EnemyShot[i].flag=0;
            }
        }
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){
        int RefreshTime=0;

        ChangeWindowMode( TRUE ) ;
        if( DxLib_Init() == -1 ) return -1; 

        SetDrawScreen( DX_SCREEN_BACK ) ;                 

        img_load();                                      
        initialization();                                 

        while(ProcessMessage() == 0 && GetHitKeyStateAll(Key) == 0){
                RefreshTime = GetNowCount();     

                ClearDrawScreen();                        

                Background();                            

                PlayerShotCalc();                     
            
                PlayerShotDisp();                       

                PlayerControl();                          

                EnemyControl();                          

                EnemyCalcDisp();                        

                EnemyShotControl();

                EnemyShotCalcDisp();

                CollisionDetection();               

                ScreenFlip() ;                           

                counter++;

                if(Key[KEY_INPUT_ESCAPE]==1)    break;    
                while(GetNowCount() - RefreshTime < 17);  
        }
                
        DxLib_End() ;
        return 0 ;
}
上の様にソースを入力してコンパイルしてみても、何故か出てくる敵が弾を発射しません
弾を発射させるにはどこを弄ったらいいのか教えてください

Re: DXライブラリのシューティングで

Posted: 2011年6月05日(日) 17:52
by h2so5

コード:

//敵のパターン1
void EnemyPattern1(int i){
      int j;
               enemy[i].y += 2.0f;
 
        if(enemy[i].counter==75){
                for(j=0;j<ENEMY_TOTAL_NUM;j++)
                        if(EnemyShot[j].flag==0)
                                break;
        EnemyShot[j].mem_ex=enemy[i].x;
        EnemyShot[j].mem_ey=enemy[i].y;
        EnemyShot[j].mem_px=Player.x;
        EnemyShot[j].mem_py=Player.y;
        EnemyShot[j].counter=0;
        EnemyShot[j].flag=1;
        EnemyShot[j].pattern=1;
        EnemyShot[j].img=0;
        }
 
}
この部分がおかしいですね。
for(j=0;j<ENEMY_TOTAL_NUM;j++)

このforループの書き方だと、直下の文しかループされません。
つまり、

EnemyShot[j].mem_ex=enemy.x;

以降の部分はforループ内に入っていません。

Re: DXライブラリのシューティングで

Posted: 2011年6月05日(日) 18:25
by ARCS
敵の情報のカウンターを増やす処理が無いので、敵の弾の発射処理が実行されてないと思われます。

EnemyCalcDispあたりにでも
Enemy.counter++;
を追加すればOKだと思います。

コピー&ペースト等のせいでおかしくなってるだけなのかもしれませんが、
ifやforなどの処理を1文の場合にブロック{}で囲まないのなら、インデントは正しくなるようにしましょう。
勘違い等でバグを生みやすくなると思います。

私は一行でもきちんと{}で囲むのを推奨します。
なにか処理を追加しようとしたときに、{}をつけ忘れる可能性は大きいです。

Re: DXライブラリのシューティングで

Posted: 2011年6月05日(日) 18:30
by うすしお
返信ありがとうございます。
ご指摘を受けてその部分を以下の様に修正しました

コード:


void EnemyPattern1(int i){
	    int j;
        enemy[i].y += 2.0f;

        if(enemy[i].counter==75){
			for(j=0;j<ENEMY_TOTAL_NUM;j++){
                EnemyShot[j].mem_ex=enemy[i].x;
                EnemyShot[j].mem_ey=enemy[i].y;
				EnemyShot[j].mem_px=Player.x;
				EnemyShot[j].mem_py=Player.y;
				EnemyShot[j].counter=0;
				EnemyShot[j].flag=1;
				EnemyShot[j].pattern=1;
				EnemyShot[j].img=0;
                if(EnemyShot[j].flag==0)
                       break;
			}
		}
}
しかし、修正した状態でコンパイルしても弾が出ません
なぜでしょうか?