ページ 11

シューティングの弾のショットについて

Posted: 2012年11月18日(日) 16:47
by SKY
[1] 質問文
シューティングゲームを作っています。自機から弾を出すときなんですがボタンを押すと、弾の画像が自機より少し上あたりに1回だけ表示されて終わってしまいます。
何時間かにらめっこしたんですがうまくいきません。
連続でちゃんと飛んでいく球を作るにはどうすればいいでしょうか。「シューティング基本。」を参考に書かせてもらいましたhttp://dixq.net/g/29.html
px,pyは自機の座標です。

コード:

struct SHOT{
	int flag;
	int x;
	int y;
	int gh;
	int width,height;
};

void PLAYER(){
	
	
	
	   int w,h,i;
	   GetGraphSize(tama1,&w,&h);
	   SHOT shot[10];
	
	
	   DrawGraph(px,py,player,TRUE);
	
	        for(i=0;i<10;i++){                  
                shot[i].x=px; shot[i].y=py; 
                shot[i].flag=0;                
				shot[i].gh=tama1;
			}



                if(counter<5)                        
                        counter++;                      
 
                else if( Key[ KEY_INPUT_Z]  == 1 ){
                        counter=0;                      
                        for(i=0;i<10;i++){             
                                if(shot[i].flag==0){    
                                        shot[i].flag=1; 
                                        break;
                                }
                        }
                }
                for(i=0;i<10;i++){
                        if(shot[i].flag==1){              
                                shot[i].y-=8;             
                                DrawGraph( shot[i].x , shot[i].y , shot[i].gh , TRUE );
                                if(shot[i].y < -32){      
                                        shot[i].y=py;    
                                        shot[i].flag=0;  
                                }
                        }
                }
                
				ScreenFlip() ;
}

void loadgraph(){
	player =LoadGraph("画像パス");
	tama1=LoadGraph("画像パス");
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

	ChangeWindowMode(TRUE);
	

        DxLib_Init();   //初期化
		SetDrawScreen( DX_SCREEN_BACK ); 
		loadgraph();
        
		while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0&& gpUpdateKey()==0 ){
			PLAYER();	
        
		}
        DxLib_End();
        return 0;
}

[2] 環境  
 [2.1] OS :windouws7
 [2.2] コンパイラ名 : VC++ 2010 EX,
[3] C,C++は初心者です。ライブラリはDXライブラリを使っております

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 16:59
by へにっくす
インデントがずれまくってます。直して下さい。
また、以下に違反しています。
書いてはいけない4つの処理
で、本題ですが、
弾のyが-32より小さい時にpyに初期化しているようですが、
弾を出すタイミングで初期化するべきだと思います。

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 17:25
by SKY
へにっくすさんご指摘ありがとうございます。
インデントとやってはいけない処理は直しておきました。
本題のほうはやってみたんですが、変化がないみたいで・・・

コード:

void PLAYER(){
	int w,h,i;
	GetGraphSize(tama1,&w,&h);
	SHOT shot[10]={0};
	
	
	DrawGraph(px,py,player,TRUE);
	for(i=0;i<10;i++){                  
		shot[i].x=px; shot[i].y=py; 
		shot[i].flag=0;              
		shot[i].gh=tama1;
	}
	if(counter<5)                        
		counter++;                      
	else if( Key[ KEY_INPUT_Z]  == 1 ){
		counter=0;
		shot[i].y=py;//ここでよろしかったでしょうか。

		for(i=0;i<10;i++){

			if(shot[i].flag==0){
				shot[i].flag=1; 
				break;
			}
		}
	}
	for(i=0;i<10;i++){
		if(shot[i].flag==1){              
			shot[i].y-=8;             
			DrawGraph( shot[i].x , shot[i].y , shot[i].gh , TRUE );
			if(shot[i].y < -32){      
				shot[i].flag=0;  
			}
		}
	}
                
}
上記以外の部分にも初期化のタイミングを変えてみたんですが変化がなくて・・・

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 17:31
by nil
17行目のiの中に入っている数字は何でしょうか?

関数の命名規則がバラバラなのは何故でしょう?
いづれかに統一したほうが良いと思います。

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 17:39
by SKY
涼雅さんご指摘ありがとうございます。
17行目はおかしいですね
結局どこに初期化の処理を入れたらいいかわからなかったんで・・・
すいませんが関数の命令規則とはどのあたりのことを言ってるんでしょうか。

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 17:49
by ISLe
n+0フレーム目:shot全要素初期化→キーが押されていた→shotの一要素にフラグを立てる→描画
n+1フレーム目:shot全要素初期化→キーが押されていた→shotの一要素にフラグを立てる→描画
の繰り返しになっていることは分かりますか?

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 17:58
by SKY
>n+0フレーム目:shot全要素初期化→キーが押されていた→shotの一要素にフラグを立てる→描画
>n+1フレーム目:shot全要素初期化→キーが押されていた→shotの一要素にフラグを立てる→描画
>の繰り返しになっていることは分かりますか?

はい、その部分は理解してます。

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 18:30
by nil
命名規則ですが、
PLAYERは全て大文字、loadgraphは全て小文字なのはなぜか? ということです。

ところで、shot変数をPLAYER内のローカル変数で扱っていますが、
変数のスコープについては理解なさっていますか?

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 18:36
by ISLe
SKY さんが書きました:>n+0フレーム目:shot全要素初期化→キーが押されていた→shotの一要素にフラグを立てる→描画
>n+1フレーム目:shot全要素初期化→キーが押されていた→shotの一要素にフラグを立てる→描画
>の繰り返しになっていることは分かりますか?

はい、その部分は理解してます。
ということは、質問文にある「ボタンを押すと、弾の画像が自機より少し上あたりに1回だけ表示されて終わって」の原因は分かっているわけですね。

でしたら、わたしが書いたのと同じように日本語で箇条書きしたものを矢印で繋いで、弾が飛んでいく手順を説明していただけますか。

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 18:40
by SKY
命名規則ついてはわかりました。
変数のスコープは完全ではないけれど大体わかります。
少し不安ですが。

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 18:51
by SKY
ISLeさん。修正した場合の手順の説明をするってことでしょうか?

n+0フレーム目:shot全要素初期化→キーが押されていた→shotの一要素にフラグを立てる→描画
n+1フレーム目:shot全要素初期化→キーが押されていた→shotの一要素にフラグを立てる→描画
が毎フレーム全要素が初期化されてしまってるから、1回表示されてしまい終わってしまってるってことでしょうか。

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 18:52
by nil
SKY さんが書きました:変数のスコープは完全ではないけれど大体わかります。
ならば問題は簡単です。
弾が前へと飛ばない理由は

コード:

#include <cstdio>

int func(){
	int i = 0;
	i++;
	printf( "%d\n", i );
}

int main(){
	while(true){
		func();
	}
}
このコードで1しか表示されない理由と同じです。

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 19:16
by SKY
涼雅さん、それはiがローカルで宣言されてないからiの値が1になってしまうんですよね

つまりshotをグローバルで宣言すればよいのですね。
構造体の場合のグローバル宣言がよくわからないのですが
SHOT shot[10];
を外で宣言すればいいのでしょうか?

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 19:22
by SKY
[quote="SKY"]涼雅さん、それはiがローカルで宣言されてないからiの値が1になってしまうんですよね

quote]
すいませんローカルではなくグローバルですね

Re: シューティングの弾のショットについて

Posted: 2012年11月18日(日) 19:40
by SKY
皆様本当にありがとうございました。
おかげで無事動作することができました。