弾を同時に2発

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ゆうdすけ

弾を同時に2発

#1

投稿記事 by ゆうdすけ » 14年前

こんばんは。
シューティングゲームをC言語を使って作ろうとしています。
環境は、visual C++で、DXライブラリを使用しています。 言語は、C言語です。

今回質問したのは、シューティングゲームで、弾を同時に2発出す処理で困っているので、質問しました。
ソースコードは

コード:

 
#define Player_Burret_MAX  3 //連続で発射される弾の数
#define Burret_FPS         10    //なんフレーム目で2発目を出すか
#define Burret_Num2    2  //同時に出す玉の数

int Player_Shot_Burret_X[Burret_Num] = {  0, 10 }; //X弾
int Player_Shot_Burret_Y[Burret_Num] = { 10, 10 }; //Y弾

void Player_Burret(){

	if( CheckHitKey(KEY_INPUT_X) == 1){
		for( int j=0 ; j<Player_Burret_MAX ; j++ ){
			for( int i=-1 ; i<Burret_Num ; i++ ){
				
		if( Burret[j].counter == 0 ){
		if( Burret[j].Flag == 0 ){
	PlaySoundMem( Music.hassya, DX_PLAYTYPE_BACK ); //音の再生
	Burret[j].X = Player_Shot_Burret_X[i] + X_Player;
	Burret[j].Y = Player_Shot_Burret_Y[i] + Y_Player;
	Burret[j].Flag = 1;
		break;
		     	}
	   	   
		Burret[j].counter = Burret_FPS;
			
			}else
		Burret[j].counter -= 1;
			}
		}
	}
	for( int j=0 ; j< Player_Burret_MAX ; j++ ){
	if( Burret[j].Flag == 1 ){
		Burret[j].Y -= 16;
	if( Burret[j].Y < -80 ) Burret[j].Flag = 0;
	
	DrawGraph( Burret[j].X, Burret[j].Y, Burret_Graph, TRUE );	//銃
	HitPoint_Burret( Burret[j].X, Burret[j].Y, j, Enemis_X, Enemis_Y );//銃ダメージ判定	
			
			}
		}
	}
 
となっています。
実行してみると、弾がランダム(?)で変な箇所で発射され、連続で3発発射させたいのに、1発が画面に出たら2発目になってしまいます。
また、同時に2発出したいのに、1発づつしか発射されません。
何処の箇所が間違っているのでしょうか?また、どうすればよいでしょうか?
説明がへたくそですみません・・。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 弾を同時に2発

#2

投稿記事 by h2so5 » 14年前

13行目:
for( int i=-1 ; i<Burret_Num ; i++ )

なぜiを-1から始めているんですか?

naohiro19
記事: 256
登録日時: 15年前
住所: 愛知県

Re: 弾を同時に2発

#3

投稿記事 by naohiro19 » 14年前

13行目のfor文がおかしいです

ゆうすけ

Re: 弾を同時に2発

#4

投稿記事 by ゆうすけ » 14年前

naohiro19さんh2so5さん 返信・ご回答ありがとうございます。

あ、何故-1にしたんでしょう・・・。自分でも分かりません・・・

 i=0にしてみましたが、変なところに弾が出る問題は解決したのですが、同時に2発だしたいのに1発づつしかでません。
また、連続で3発(同時に2発なので6発)発射してくれません。
それと
#define Player_Burret_MAX 3 //連続で発射される弾の数
の部分を
#define Player_Burret_MAX 6 //連続で発射される弾の数

に訂正しました。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 弾を同時に2発

#5

投稿記事 by h2so5 » 14年前

21行目のbreak; は何のために入れているんですか?

ゆうすけ

Re: 弾を同時に2発

#6

投稿記事 by ゆうすけ » 14年前

h2so5さん返信ありがとうございます。

>21行目のbreak; は何のために入れているんですか?

flagが立ったらforを抜けるために入れました。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 弾を同時に2発

#7

投稿記事 by h2so5 » 14年前

ゆうすけ さんが書きました:flagが立ったらforを抜けるために入れました。
1発撃ったらforを抜けてしまうので2発目は出ないと思いますけど。

あと、Burret_Numの定義が書かれていませんが、定義値は2ですか?

ゆうすけ

Re: 弾を同時に2発

#8

投稿記事 by ゆうすけ » 14年前

h2so5さん返信ありがとうございます。

>>1発撃ったらforを抜けてしまうので2発目は出ないと思いますけど。
breakなしで実行してみましたが、何も変化がありませんでした。

>>Burret_Numの定義が書かれていませんが、定義値は2ですか?
ごめんなさい、コードが変になってしまって、変数と値がくっついてしまいました。

#define Burret_Num2    2 //同時に出す玉の数

#define Burret_Num    2 //同時に出す玉の数
に訂正です。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 弾を同時に2発

#9

投稿記事 by h2so5 » 14年前

配列Burretの初期化部分のソースが怪しいので見せてください。

(ちなみに”弾”のスペルはbulletです)

↓ソースが見ずらいので修整しました

コード:

#define Player_Burret_MAX  3 //連続で発射される弾の数
#define Burret_FPS         10    //なんフレーム目で2発目を出すか
#define Burret_Num2    2  //同時に出す玉の数
 
int Player_Shot_Burret_X[Burret_Num] = {  0, 10 }; //X弾
int Player_Shot_Burret_Y[Burret_Num] = { 10, 10 }; //Y弾
 
void Player_Burret(){
 
    if( CheckHitKey(KEY_INPUT_X) == 1){
        for( int j=0 ; j<Player_Burret_MAX ; j++ ){
            for( int i=-1 ; i<Burret_Num ; i++ ){
                
	        if( Burret[j].counter == 0 ){
		        if( Burret[j].Flag == 0 ){
			    PlaySoundMem( Music.hassya, DX_PLAYTYPE_BACK ); //音の再生
			    Burret[j].X = Player_Shot_Burret_X[i] + X_Player;
			    Burret[j].Y = Player_Shot_Burret_Y[i] + Y_Player;
			    Burret[j].Flag = 1;
			 }
		        Burret[j].counter = Burret_FPS;
	            
	        }else{
	        	Burret[j].counter -= 1;
	        }
            }
        }
    }
    
    for( int j=0 ; j< Player_Burret_MAX ; j++ ){
    
	    if( Burret[j].Flag == 1 ){
	        Burret[j].Y -= 16;
	        
	    	if( Burret[j].Y < -80 ) Burret[j].Flag = 0;
	    
	    	DrawGraph( Burret[j].X, Burret[j].Y, Burret_Graph, TRUE );  //銃
	    	HitPoint_Burret( Burret[j].X, Burret[j].Y, j, Enemis_X, Enemis_Y );//銃ダメ  
	            
	    }
    }
}

ゆうすけ

Re: 弾を同時に2発

#10

投稿記事 by ゆうすけ » 14年前

返信ありがとうございます。

>>配列Burretの初期化部分のソースが怪しいので見せてください。
Burret[j].~~の部分ですか?

Burret Burret[Player_Burret_MAX];
とだけしてあります。これが原因でしょうか?

念のため
INAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTRlpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);//ウィンドウモード
// 画面モードの設定
SetGraphMode( 640 , 480 , 16 ) ;
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
Load_Graph();


のあとに
for(int i=0;i<Player_Burret_MAX;i++){
Burret.X = 0;
Burret.Y = 0;
Burret.Flag = 0;
Burret.FPS = 0;
のようにして初期化しました。それでもなにも変わりませんでした・・・。

while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理   ↑画面をクリア     ↑入力状態を保存       ↑ESCが押されていない

↑はその次のコードです。

凄く見難くてすみません。
もしかしたら全部書き換えないといけないとか・・でしょうか。

アバター
Dixq (管理人)
管理人
記事: 1662
登録日時: 15年前
住所: 北海道札幌市
連絡を取る:

Re: 弾を同時に2発

#11

投稿記事 by Dixq (管理人) » 14年前

グローバル変数であれば最初から既に0クリアされてますよ。
また、初期化をしたい時はfor文で面倒な代入をしなくても
memset( アドレス, 0, sizeof(変数名) );
で0クリア出来ます。
(ただこの方法は一応こういうことを知ったうえで使いましょう。
http://www.kijineko.co.jp/tech/supersti ... emset.html

ゆうすけ

Re: 弾を同時に2発

#12

投稿記事 by ゆうすけ » 14年前

Dixqさん返信ありがとうございます。

あ、勝手に初期化してくれるんですか!たしか、本でもそんなことを読んだような記憶が・・。

memsetについては初めて知りました。そのサイトを参考にしてこれから活用したいと思います。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 弾を同時に2発

#13

投稿記事 by h2so5 » 14年前

Burret[0].counter もBurret[1].counter も初期値が0なので、
2発同時に発射されて重なっている可能性があります。

if( Burret[j].counter == 0 )
の条件分岐をする前に Burret[j].counter = Burret_FPS; が実行されていないとおかしいかと。

ゆうすけ

Re: 弾を同時に2発

#14

投稿記事 by ゆうすけ » 14年前

h2so5さん返信ありがとうございます。

>2発同時に発射されて重なっている可能性があります。
たしかに弾の数を増やしてやってみると、音量が大きくなっていました。

>if( Burret[j].counter == 0 ).....


if(Burret[j].counter == 0) を

Burret[j].counter = Burret_FPS
if(Burret[j].counter == 0){
...
...
}
のようにしたら弾が出ませんでした。
おそらくifの前で初期化してしまったため、counterが0にならないから(?)と判断したので、今度は

if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
Load_Graph();

for(int i=0 ; i<Player_Burret_MAX ; i++) Burret.counter = Burret_FPS;

while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理   ↑画面をクリア     ↑入力状態を保存       ↑ESCが押されていない

という風にしてみました。
弾は発射されるのですが、重なってるみたいです。
他にも色々位置をずらしてやってみたのですが、どうも改善されません・・・。

どうすれば解決するのでしょうか。
何度も何度も本当にすみません・・・。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 弾を同時に2発

#15

投稿記事 by h2so5 » 14年前

おかしな部分がたくさんあるので指摘しておきます。

弾が同時に2発、連続で3発出るなら弾は6発になるはずですが、
Burret Burret[Player_Burret_MAX];
という宣言ではPlayer_Burret_MAX=3なのでどうやっても画面上には同時に3発の弾しか表示できません。

11行目、31行目のfor( int j=0 ; j<Player_Burret_MAX ; j++ ){ も同様です。
変数iがPlayer_Shot_Burret_Xの部分にしか使われていないのも変です。

ちなみに
for(int i=0 ; i<Player_Burret_MAX ; i++) Burret.counter = Burret_FPS;
とした場合、すべての弾のカウントが同じになるため、カウントが0になるのも同時でやはり重なってしまいます。

おっく

Re: 弾を同時に2発

#16

投稿記事 by おっく » 14年前

・Burret_Num2   :使われてない。Burret_Numがどこからか来て使われてる。
・Burret_Num    :出所が不明。値がわからない。↑コレ
・Burret[j].counter = Burret_FPS; :この処理の意味がわからない。時間カウントしたいの?同時に玉出したいんじゃないの?
・#define Burret_FPS 10 //なんフレーム目で2発目を出すか  :これもそう。数フレーム後に2発目を出す?同時に出すのどっちなのか?

・2回目のfor(Player_Burret_MAX)ループ  :他の人からも指摘がありますが、玉描画が3回しか発生しない。目に見えるのは3個。

--個人的に--
同時に玉を出したいと言う反面、「数フレーム後に出す」とコメントされてるのも、意図がボヤけて見えます。
そもそも、同じ回数処理するモノを、for分けて書くのも?な感じです。
提示されてるソースコードにBurret_Numのような出所がわからない要素があるとか、
色々と手際が悪いのも事実。

外に弾発射の関数を作って、
それをPlayer_Burret_MAX回チェックして、
同時に玉を出したいのなら同時発射数分だけ弾発射関数をコールすれば、
見た目もすっきりするじゃないかなと。

ゆうすけ

Re: 弾を同時に2発

#17

投稿記事 by ゆうすけ » 14年前

おっくさんh2so5さん返信ありがとうございます

>>という宣言ではPlayer_Burret_MAX=3なのでどうやっても画面上には同時に3発の弾しか表示できません。
訂正しました。

>>変数iがPlayer_Shot_Burret_Xの部分にしか使われていないのも変です。
>>すべての弾のカウントが同じになるため、カウントが0になるのも同時でやはり重なってしまいます。
色々作り直してみました。(下コード)

>>使われてない。Burret_Numがどこからか来て使われてる。
訂正しました。

>>この処理の意味がわからない。時間カウントしたいの?同時に玉出したいんじゃないの?
少し間隔をあけて3発目(4発目?)を出したいと思ったのですが、無理そうなので諦めます・・。

>>外に弾発射の関数を作って.....
何となくですが、自分なりに試行錯誤して作ってみました。

コード:

#define Graph_Counter_MAX 20	//何フレーム間グラフィックを表示するか
#define Burret_Num		   2	//同時に出す玉の数

void Player_Burret_Monitor(){

for(int j=0; j<Burret_Num; j++){			
				Player_Burret(j);					
		}
	}




void Player_Burret(int j){

	if( CheckHitKey(KEY_INPUT_Z) == 1){

		if( Burret[j].Flag == 0 ){		
			PlaySoundMem( Music.hassya, DX_PLAYTYPE_BACK );		//音の再生
			Burret[j].X = Player_Shot_Burret_X[j] + X_Player;	//弾の位置
			Burret[j].Y = Player_Shot_Burret_Y[j] + Y_Player;	//弾の位置
			Burret[j].Flag = 1;
	}
}

if( Burret[j].Flag == 1 ){		
	Burret[j].Y -= 15.;

	if( Burret[j].Y < -80 ) Burret[j].Flag = 0;
		DrawGraph( Burret[j].X, Burret[j].Y, Burret_Graph, TRUE );			//弾のグラフィック
		HitPoint_Burret( Burret[j].X, Burret[j].Y, j, Enemis_X, Enemis_Y );//弾ダメージ判定	
	}	
}

これだと、当たり前ですが弾が外に出た後または敵に当たった時3発目(4発目?)が発射されてしまいます。(連続ででない)
重ならずに、6発連続で出すにはどこを訂正すればよいでしょうか?

本当に質問ばかりですみません・・・。

ゆうすけ

Re: 弾を同時に2発

#18

投稿記事 by ゆうすけ » 14年前

ごめんなさい、今コードを少しみて、訂正しました。

コード:


#define Burret_Num		   2	//同時に出す玉の数

void Player_Burret(){

	if( CheckHitKey(KEY_INPUT_Z) == 1){
	for(int j=0; j<Burret_Num; j++){				//2発の弾
		if( Burret[j].Flag == 0 ){		//フラグOFF
			PlaySoundMem( Music.hassya, DX_PLAYTYPE_BACK );		//音の再生
			Burret[j].X = Player_Shot_Burret_X[j] + X_Player;	//弾の位置
			Burret[j].Y = Player_Shot_Burret_Y[j] + Y_Player;	//弾の位置
			Burret[j].Flag = 1;
	}


if( Burret[j].Flag == 1 ){		//フラグON
	Burret[j].Y -= 15.;

	if( Burret[j].Y < -80 ) Burret[j].Flag = 0;
		DrawGraph( Burret[j].X, Burret[j].Y, Burret_Graph, TRUE );			//弾のグラフィック
		HitPoint_Burret( Burret[j].X, Burret[j].Y, j, Enemis_X, Enemis_Y );//弾ダメージ判定	
			}
		}	
	}
}
二つに分けてた関数を一つにしました。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: 弾を同時に2発

#19

投稿記事 by ISLe » 14年前

次の弾が撃てるまで待つのはプレイヤーキャラの仕事ですよ。
弾の構造体メンバでどうこうするものではありません。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 弾を同時に2発

#20

投稿記事 by h2so5 » 14年前

コードが見にくいのでインデントをちゃんと付けて下さい。
このコードだと、ボタンを離すと弾が表示されなくなってしまいますが、それは良いのでしょうか?

コード:

 
#define Burret_Num         2    //同時に出す玉の数
 
void Player_Burret(){
 
    if( CheckHitKey(KEY_INPUT_Z) == 1){
    	for(int j=0; j<Burret_Num; j++){                //2発の弾
    	
	        if( Burret[j].Flag == 0 ){      //フラグOFF
	            PlaySoundMem( Music.hassya, DX_PLAYTYPE_BACK );     //音の再生
	            Burret[j].X = Player_Shot_Burret_X[j] + X_Player;   //弾の位置
	            Burret[j].Y = Player_Shot_Burret_Y[j] + Y_Player;   //弾の位置
	            Burret[j].Flag = 1;
	    	}
	 
	 
	        if( Burret[j].Flag == 1 ){      //フラグON
	            Burret[j].Y -= 15.;
		 
	            if( Burret[j].Y < -80 ) Burret[j].Flag = 0;
			
	            DrawGraph( Burret[j].X, Burret[j].Y, Burret_Graph, TRUE );          //弾のグラフィック
	            HitPoint_Burret( Burret[j].X, Burret[j].Y, j, Enemis_X, Enemis_Y );//弾ダメージ判定  
			
	        }
        }   
    }
}

ゆうすけ

Re: 弾を同時に2発

#21

投稿記事 by ゆうすけ » 14年前

コード:

#define Burret_Num         2    //同時に出す玉の数
 
void Player_Burret(){
 
    if( CheckHitKey(KEY_INPUT_Z) == 1){
    for(int j=0; j<Burret_Num; j++){                //2発の弾
        if( Burret[j].Flag == 0 ){      //フラグOFF
            PlaySoundMem( Music.hassya, DX_PLAYTYPE_BACK );     //音の再生
            Burret[j].X = Player_Shot_Burret_X[j] + X_Player;   //弾の位置
            Burret[j].Y = Player_Shot_Burret_Y[j] + Y_Player;   //弾の位置
            Burret[j].Flag = 1;
        }
    }
}
 for(int j=0; j<Burret_Num; j++){                //2発の弾
if( Burret[j].Flag == 1 ){      //フラグON
    Burret[j].Y -= 15.;
 
    if( Burret[j].Y < -80 ) Burret[j].Flag = 0;
        DrawGraph( Burret[j].X, Burret[j].Y, Burret_Graph, TRUE );          //弾のグラフィック
        HitPoint_Burret( Burret[j].X, Burret[j].Y, j, Enemis_X, Enemis_Y );//弾ダメージ判定  
               }
           }   
       }
 
でした。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 弾を同時に2発

#22

投稿記事 by h2so5 » 14年前

ゆうすけ さんが書きました: これだと、当たり前ですが弾が外に出た後または敵に当たった時3発目(4発目?)が発射されてしまいます。(連続ででない)
重ならずに、6発連続で出すにはどこを訂正すればよいでしょうか?
Burret_Num = 2なので、
Burret[0],Burret[1]しか使われず同時に2つしか弾が出ないようになっています。

閉鎖

“C言語何でも質問掲示板” へ戻る