弾消しフラグ2

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

弾消しフラグ2

#1

投稿記事 by situmon » 16年前

何度も何度もすいませんが、スレが古くなってしまったのでもう一度投稿しました。
EnemyShot[j].flag=2;//弾を2のフラグに
if(EnemyShot[j].flag==2)//弾が2のフラグなら
EnemyShot.EnemyShots[j].flag=0;//それ以上登録しない
else(EnemyShot[j].flag==2 && EnemyShot.flag==0);//もし(そうではなく)弾が2のフラグで弾が全部外なら
EnemyShot[j].flag=0;//弾を0にする。
でいいのでしょうか。

Dixq (管理人)

Re:弾消しフラグ2

#2

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

どの時、どの部分にこの処理が入るのでしょうか?
あと、弾の登録部と弾の軌道計算、フラグ計算部は違うと思います。

また、

EnemyShot[j].flag==2 && EnemyShot.flag==0

この意味がよくわかりません。jはiの特定の弾番号を示していると思いますから
これではおかしいです。

弾幕構造体の中に複数の弾があるという構造になっています。

typedef struct{
  //フラグや座標データ
}弾_t;

typedef struct{
  //フラグや座標データ
  弾_t 弾[弾MAX];
}弾幕_t;

弾幕_t 弾幕[弾幕MAX];


こんな構造ですよね。ある特定の弾幕データが持つ弾が全部フラグオフかどうかを調べる必要があるのです。

situmon

Re:弾消しフラグ2

#3

投稿記事 by situmon » 16年前

ENEMY_TOTAL_SHOT_NUMが弾MAX、
ENEMY_TOTAL_NUMが弾MAX
であっていますか?
だから
ENEMY_TOTAL_NUMが弾MAXのフラグが0かを調べればいいわけですね。

situmon

Re:弾消しフラグ2

#4

投稿記事 by situmon » 16年前

EnemyShot[j].flag=2;
for(i=0; i<ENEMY_TOTAL_SHOT_NUM; i++){
if(EnemyShot[j].flag!=0){
break;
}
}
if(i==ENEMY_TOTAL_SHOT_NUM){
EnemyShot[j].flag=0;
}
としたら
解決できたのですが、これでもだめなのでしょうか?

Dixq (管理人)

Re:弾消しフラグ2

#5

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

上にも書きましたが、どこの判定式ですか?
プログラムのどの部分でこれを使っているのかがわからないとあってるかどうかわからないです。

>ENEMY_TOTAL_SHOT_NUMが弾MAX、 
>ENEMY_TOTAL_NUMが弾MAX 
>であっていますか? 

とはどういういみでしょう?
上は弾データの最大値、下は弾データをもつ、敵の弾幕データの最大値です。

>ENEMY_TOTAL_NUMが弾MAXのフラグが0かを調べればいいわけですね。

もよくわかりません。
その弾幕が持つ弾が全て画面外にあるかどうかは、フラグを調べればよいです。

>としたら 
>解決できたのですが、これでもだめなのでしょうか?

先日から同じ事を何度も言っているので、よく考えて下さい。
「弾幕」というデータは「弾」を持っている弾データの塊のデータなのです。
弾幕が持つ弾データのフラグが全てオフの時、弾幕フラグをオフにすればいいのです。
・・が、しかしそれは既に実装されていますよね。
自分で作る必要はありません。

あと、iとjが混在していますが、jは何を表しているのでしょうか?
また、iを使ったループの中にiがありません。
もし単なる見間違いなら、iとjを使わないようにしましょう。
iとjはOと0の次に見間違いやすい変数かと思います。
iとsなど見間違う可能性の低い文字を使うとよいでしょう。

そして、コードを投稿する時はタグを使って下さい。
 

Dixq (管理人)

Re:弾消しフラグ2

#6

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

龍神録プログラミングの館で実装している例です。
引数は敵のID番号です。
//敵が死ぬかどうかの決定
void enemy_death_judge(int s){
    int i;
    se_flag[8]=1;//敵に当たった音
    if(enemy.hp<0){//敵のHPが0未満になったら
        enemy.flag=0;//敵を消滅させる
        se_flag[1]=1;//敵のピチュリ音
        enter_del_effect(s);
        enter_enemy_item(s);//敵sのアイテムを出現させる(39章)
        for(i=0;i<SHOT_MAX;i++){//敵総数分
            if(shot.flag!=0){//登録されている弾幕データがあれば
                if(s==shot.num){//その敵が登録した弾幕があれば
                    shot.flag=2;//それ以上弾幕を続けないフラグを立てる
                    break;
                }
            }
        }
    }
}
 
 

situmon

Re:弾消しフラグ2

#7

投稿記事 by situmon » 16年前

>上にも書きましたが、どこの判定式ですか?
プログラムのどの部分でこれを使っているのかがわからないとあってるかどうかわからないです。
void CollisionDetection(){
・・・略
if( (int)sqrt(x*x+y*y) < range+enemy.range){
if(enemy.hp <= 0){
enemy.flag=0;
EnemyShot[j].flag=2;
for(j=0; j<ENEMY_TOTAL_SHOT_NUM; j++){
if(EnemyShot[j].flag!=0)
break;
}
}
if(j==ENEMY_TOTAL_SHOT_NUM){
 EnemyShot[j].flag=0;
}
}

の部分です。
>「弾幕」というデータは「弾」を持っている弾データの塊のデータなのです。
>とはどういういみでしょう?
上は弾データの最大値、下は弾データをもつ、敵の弾幕データの最大値です。
へんな勘違いをしていたみたいです、それに日本語もおかしかったです。
すいませんでした。

追加、
管理人さんの最新の書き込みがされたときにこの書き込みをしていました。
すいません。

Dixq (管理人)

Re:弾消しフラグ2

#8

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

これはループ文などが省略されているのでしょうか?
それともCollisionDetection関数はこれだけですか?

sとiとjが何をさしているのかわからないです。

それからEnemyShotはENEMY_TOTAL_SHOT_NUM個用意したなら
EnemyShot[ENEMY_TOTAL_SHOT_NUM]は存在しませんよね。
そして、EnemyShotはENEMY_TOTAL_SHOT_NUM個用意したものではありません。
宣言や定義をもう一度見直してみて下さい。

situmon

Re:弾消しフラグ2

#9

投稿記事 by situmon » 16年前

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:
							case 5:
							case 6:
								range=12;
								break;
							default:
								range=9;
								break;
						}
						if( (int)sqrt(x*x+y*y) < range+enemy.range){
                                                        if(enemy.hp <= 0){
                                                                enemy.flag=0;
                                                                EnemyShot[j].flag=2;
																for(j=0; j<ENEMY_TOTAL_SHOT_NUM; j++){
																	if(EnemyShot[j].flag!=0){
															   break;
																	}
																}
																if(j==ENEMY_TOTAL_SHOT_NUM){
                                                                     EnemyShot[j].flag=0;
																}

                                                                if(CheckSoundMem(sound_enemy_death)==1)
                                                                        StopSoundMem(sound_enemy_death);
                                                        }
                                                        enemy.hp -= 1;
							PlayerShot[j].flag=0;
							if(CheckSoundMem(sound_enemy_death)==1)
								StopSoundMem(sound_enemy_death);
                            PlaySoundMem(sound_enemy_death,DX_PLAYTYPE_BACK);
						}
					}
				}
			}
		}
	}
}

がすべてです。
さきほどの龍神録のにあてはめると
EnemyShot[j].flag=2;
for(j=0; j<ENEMY_TOTAL_SHOT_NUM; j++){
if(EnemyShot[j].flag!=0){
break;
}
}
if(j==ENEMY_TOTAL_SHOT_NUM){
EnemyShot[j].flag=0;
}


for(i=0; i<ENEMY_TOTAL_NUM; i++){
if(EnemyShot.flag!=0){
if(s==EnemyShot.flag){//その敵が登録した弾幕があれば
EnemyShot.flag=2;
break;
}
}
}
になりますが・・・

Dixq (管理人)

Re:弾消しフラグ2

#10

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

アルゴリズムがどうなるべきなのか、また、変数がどう変化するのか考えて見ましょう。
とりあえず10*20のループをさせるため、

for(i=0;i<10;i++){
    for(i=0;i<20;i++){
        //処理
    }
}

これじゃ200回のループにはなりませんよね?
これと同じことがお書きになっているプログラムでも起こっています。

4重ループを作るには4つの変数が必要です。

また、あまりネストが深くなるのはよくないです。
いくつもループが必要な時は関数わけするなどしたほうがいいと思います。
そして、この4重ループは適切ではありません。

フラグを立てる時は立てるだけにして、フラグによる制御はまた別に行うべきです。
今のままでは、敵が死んだ瞬間にしか処理がされません。


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:
                            case 5:
                            case 6:
                                range=12;
                                break;
                            default:
                                range=9;
                                break;
                        }
                        if( (int)sqrt(x*x+y*y) < range+enemy.range){
                            if(enemy.hp <= 0){
                                enemy.flag=0;
                                EnemyShot[j].flag=2;
                                for(j=0; j<ENEMY_TOTAL_SHOT_NUM; j++){
                                    if(EnemyShot[j].flag!=0){
                                        break;
                                    }
                                }
                                if(j==ENEMY_TOTAL_SHOT_NUM){

                                     EnemyShot[j].flag=0;
                                }
                                if(CheckSoundMem(sound_enemy_death)==1)
                                        StopSoundMem(sound_enemy_death);
                            }
                            enemy.hp -= 1;
                            PlayerShot[j].flag=0;
                            if(CheckSoundMem(sound_enemy_death)==1)
                                StopSoundMem(sound_enemy_death);
                            PlaySoundMem(sound_enemy_death,DX_PLAYTYPE_BACK);
                        }
                    }
                }
            }
        }
    }
}
 

見易いように自下げしました

situmon

Re:弾消しフラグ2

#11

投稿記事 by situmon » 16年前

すいません間違えたので消しました。
今回どうもありがとうございました。

閉鎖

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