ボスのショットについてです。

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

ボスのショットについてです。

#1

投稿記事 by 胡椒 » 15年前

以前、上のURLで質問したものです。
上のURLのやり方であっていたと思ったんですが、根本的な解決にはなっていないことに気づきました。
試しに

void boss_shot_bulletH003(){
int i,k,x,j,t=boss_shot.cnt;
if(t%100==0){
for(i=0;i<2;i++){
if((k=search_boss_shot())!=-1){
boss_shot.bullet[k].col = 4;
boss_shot.bullet[k].x = boss.x;
boss_shot.bullet[k].y = boss.y;
boss_shot.bullet[k].knd = 0;
boss_shot.bullet[k].angle = (3+2*i)*PI/4;
boss_shot.bullet[k].flag = 1;
boss_shot.bullet[k].cnt = 0;
boss_shot.bullet[k].spd = 1.5;
se_flag[0]=1;
}
}
}
for(i=0;i<4;i++){
if(boss_shot.bullet.flag>0){
}
if(t%10==0){
if((k=search_boss_shot())!=-1){
boss_shot.bullet[k].col = 1;
boss_shot.bullet[k].x = boss_shot.bullet.x;
boss_shot.bullet[k].y = boss_shot.bullet.y;
boss_shot.bullet[k].knd = 8;
boss_shot.bullet[k].angle = PI;
boss_shot.bullet[k].flag = 1;
boss_shot.bullet[k].cnt = 0;
boss_shot.bullet[k].spd = 5;
se_flag[0]=1;
}
}
}
}

というショットを作ってみたのですが、上手くいきません。
これは100カウントに一回、knd=0の弾を二個出し、その二個の弾の座標からknd=8の弾を10カウントに一回出すという意図で作りました。
どこが悪いのでしょうか?


Ma

Re:ボスのショットについてです。

#3

投稿記事 by Ma » 15年前

インデントがひどいですが、それはともかく

{}
ブレースが、おかしくありませんか?

for(i=0;i<4;i++){
if(boss_shot.bullet.flag>0){
}

ここ。 画像

胡椒

Re:ボスのショットについてです。

#4

投稿記事 by 胡椒 » 15年前

すみません。そのURLでのショットでは上手く行ったのですが違うショットを作ってみると上手くいきません。
違いは最初のif分がif(t%100==0)かif(t==1)だと思うのですが・・・

Ma

Re:ボスのショットについてです。

#5

投稿記事 by Ma » 15年前

>そのURLでのショットでは上手く行ったのですが

失礼、きのせいでした笑 画像

胡椒

Re:ボスのショットについてです。

#6

投稿記事 by 胡椒 » 15年前

すみません。色々と試してみたときのが残っていたみたいです。

void boss_shot_bulletH003(){
int i,k,x,j,t=boss_shot.cnt;
if(t%100==0){
for(i=0;i<2;i++){
if((k=search_boss_shot())!=-1){
boss_shot.bullet[k].col = 4;
boss_shot.bullet[k].x = boss.x;
boss_shot.bullet[k].y = boss.y;
boss_shot.bullet[k].knd = 0;
boss_shot.bullet[k].angle = (3+2*i)*PI/4;
boss_shot.bullet[k].flag = 1;
boss_shot.bullet[k].cnt = 0;
boss_shot.bullet[k].spd = 1.5;
se_flag[0]=1;
}
}
}
for(i=0;i<4;i++){
if(boss_shot.bullet.flag>0){
if(t%10==0){
if((k=search_boss_shot())!=-1){
boss_shot.bullet[k].col = 1;
boss_shot.bullet[k].x = boss_shot.bullet.x;
boss_shot.bullet[k].y = boss_shot.bullet.y;
boss_shot.bullet[k].knd = 8;
boss_shot.bullet[k].angle = PI;
boss_shot.bullet[k].flag = 1;
boss_shot.bullet[k].cnt = 0;
boss_shot.bullet[k].spd = 5;
se_flag[0]=1;
}
}
     }
}
}

基本的にはこれで試していました

Ma

Re:ボスのショットについてです。

#7

投稿記事 by Ma » 15年前

ここのシューティング講座を中途半端にしか読んでいないので、的外れな解答かもしれませんが、
なんとなく、0 から 4 のインデックスに、青色の弾(knd = 8)もはいっているきがします。

たぶんあってる・・・とおもう。

これから打開策を探ってみます。 画像

胡椒

Re:ボスのショットについてです。

#8

投稿記事 by 胡椒 » 15年前

for(i=0;i<4;i++)のところは最初はfor(i=0;i<BOSS_BULLET_MAX;i++)となっていたんですけど、
まえのURLのショットではfor(i=0;i<BOSS_BULLET_MAX;i+)をfor(i=0;i<2;i++)にかえたらできたので、
for(i=0;i<4;i++)としてしまいました。

ただ、前のは一発しか撃たなかった{if(t==1)}ので問題なかった(?)のだと思います・・・

Ma

Re:ボスのショットについてです。

#9

投稿記事 by Ma » 15年前

*注意:かなり我流です。
管理人様、もしくはここの講座に慣れ親しんでいる方、最適化よろしくおねがいします。


void boss_shot_bulletH000(){
#define MAX_BIGSHOT 10

int i,k,x,j,t=boss_shot.cnt;
static int indexs[MAX_BIGSHOT] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
if(t%100==0){
for(i=0;i<2;i++){
if((k=search_boss_shot())!=-1){
boss_shot.bullet[k].col = 4;
boss_shot.bullet[k].x = boss.x;
boss_shot.bullet[k].y = boss.y;
boss_shot.bullet[k].knd = 0;
boss_shot.bullet[k].angle = (3+2*i)*PI/4;
boss_shot.bullet[k].flag = 1;
boss_shot.bullet[k].cnt = 0;
boss_shot.bullet[k].spd = 1.5;
se_flag[0]=1;
for(int n= 0; n < MAX_BIGSHOT; n++){
if(indexs[n] == k)
break;
if(indexs[n] == -1 || boss_shot.bullet[indexs[n]].flag <= 0 || boss_shot.bullet[indexs[n]].knd != 0 ){
indexs[n] = k;
break;
}
}
}
}
}

for(int n= 0;(indexs[n] != - 1) && (n < MAX_BIGSHOT); n++){
if(t%10==0){
if((k=search_boss_shot())!=-1){
boss_shot.bullet[k].col = 1;
boss_shot.bullet[k].x = boss_shot.bullet[indexs[n]].x;
boss_shot.bullet[k].y = boss_shot.bullet[indexs[n]].y;
boss_shot.bullet[k].knd = 8;
boss_shot.bullet[k].angle = PI;
boss_shot.bullet[k].flag = 1;
boss_shot.bullet[k].cnt = 0;
boss_shot.bullet[k].spd = 5;
se_flag[0]=1;
}
}
}
}


一応動作確認しました。
static 使ってしまったので、他の方ならもっといい方法を教えてくれるかもしれません。
バグもありえます(汗
あと、読んでみてわからなかったらコメント必要だといってください。

*ちょっとソースコード修正しました。 画像

あ~る

Re:ボスのショットについてです。

#10

投稿記事 by あ~る » 15年前

前回答えてた人です
出来たなら良かったと思って、完成したコードあんま見てなかったんですが、色々危なそうです

for(i=0;i<2;i++){
if(boss_shot.bullet.flag>0 && t2>105){
boss_shot.bullet.spd=0;}
if(t2>240 && t>60 && t%5==0){
for(j=0;j<30;j++){
if((k=search_boss_shot())!=-1){ x=j%9;
boss_shot.bullet[k].col = x;
boss_shot.bullet[k].x = boss_shot.bullet.x;
boss_shot.bullet[k].y = boss_shot.bullet.y;
boss_shot.bullet[k].knd = 8;
boss_shot.bullet[k].angle = bossatan3(i,ch.x,ch.y)+PI2/30*j;
boss_shot.bullet[k].flag = 1;
boss_shot.bullet[k].cnt = 0;
boss_shot.bullet[k].spd = 5;
se_flag[0]=1;
}
}
}
}
}

まず
for(i=0;i<2;i++){
としてますが、多分最初に撃った弾がたまたま0番と1番の弾だっただけなので、不測の事態が起こる可能性があります
なのでここは
for(i=0;i<BOSS_BULLET_MAX;i++){
のままで良かったです
また
if(boss_shot.bullet.flag>0 && t2>105){
boss_shot.bullet.spd=0;}
の部分で、boss_shot.bullet.spd=0;}
のところでif文を閉じてはだめです
ここの流れは
フラグがある弾を探し、もしt2が105以上ならその弾のspdを0にする
さらにt2が240以上でtが60以上でt2が5の倍数ならば、その弾の座標から弾を出す
みたいな感じなんで、
「さらにt2が240以上でtが60以上でt2が5の倍数ならば、その弾の座標から弾を出す」
も、if文の中に入れとかなきゃいけません
なので}の位置が違います
ここら辺を踏まえて直してみて下さい

またまた携帯からなんで見にくいかも…(-.-;)

Ma

Re:ボスのショットについてです。

#11

投稿記事 by Ma » 15年前

先の私のプログラムについて追記です。

indexs[n] = -1
の処理をいれわすれたので、
以下のようなfor 文を、途中に加えるといいとおもいます。

*一例
for(int n= 0; n < MAX_BIGSHOT; n++){
if(indexs[n] != -1){
if(boss_shot.bullet[indexs[n]].flag <= 0 || boss_shot.bullet[indexs[n]].knd != 0)
indexs[n] = -1;
}
}


これがなくても見た目はまったく変わりませんが、-1に戻し忘れると、青い弾(knd = 8)を親の弾(knd=0)だと誤解して、青い弾の上に青い弾を発射しかねません。
(つまり弾が重なるかもしれません。)


それにともなって、最後のfor文も、以下のようします。
for(int n= 0;n < MAX_BIGSHOT; n++){
if(indexs[n] != -1 && t%10==0){




*追記
>for(i=0;i<BOSS_BULLET_MAX;i++){
個人的な意見ではありますが、できるだけ無駄が多いfor文は避けたいので、私は static でインデックスを記録する方針をとりました。
(ただ、計算量を節約しても今度はメモリの無駄といわれるかも。) 画像

胡椒

Re:ボスのショットについてです。

#12

投稿記事 by 胡椒 » 15年前

あ~るさん>
まずすみません「t2>105」は「t2==0」の間違いです。

if(boss_shot.bullet.flag>0 && t2==105){
boss_shot.bullet.spd=0;}

ここで}で閉じないと

if(t2>240 && t>60 && t%5==0){
for(j=0;j<30;j++){
if((k=search_boss_shot())!=-1){
boss_shot.bullet[k].col = 1;
boss_shot.bullet[k].x = boss_shot.bullet.x;
boss_shot.bullet[k].y = boss_shot.bullet.y;
boss_shot.bullet[k].knd = 8;
boss_shot.bullet[k].angle = bossatan3(i,ch.x,ch.y)+PI2/30*j;
boss_shot.bullet[k].flag = 1;
boss_shot.bullet[k].cnt = 0;
boss_shot.bullet[k].spd = 5;
se_flag[0]=1;
}
}

で出された弾のスピードも0になっていしまいまして・・・
また、
フラグがある弾を探し、もしt2が105以上ならその弾のspdを0にする
さらにt2が240以上でtが60以上でt2が5の倍数ならば、その弾の座標から弾を出す
のふたつの文を一つのif文に入れてしまうと最初の大弾が止まらなくなってしまいます・・・

Maさんのを見てstaticを使ってつくってみたのですが、やはり上手くいきません
コード自体は前よりは良くなっていると思うのですが・・・

void boss_shot_bulletH001(){
#define TM000 120
int i,k,j,t=boss_shot.cnt%TM000,t2=boss_shot.cnt;
static int x[BOSS_BULLET_MAX][1],y[BOSS_BULLET_MAX][1];
if(t2==5){
for(i=0;i<2;i++){
if((k=search_boss_shot())!=-1){
boss_shot.bullet[k].col = 4;
boss_shot.bullet[k].x = boss.x;
boss_shot.bullet[k].y = boss.y;
boss_shot.bullet[k].knd = 0;
boss_shot.bullet[k].angle = (3+2*i)*PI/4;
boss_shot.bullet[k].flag = 1;
boss_shot.bullet[k].cnt = 0;
boss_shot.bullet[k].spd = 3;
boss_shot.bullet[k].state = 1;
se_flag[0]=1;
}
}
}
for(i=0;i<BOSS_BULLET_MAX;i++){
if(boss_shot.bullet.flag>0){
if(t2==105 && boss_shot.bullet.state==1){
boss_shot.bullet.spd=0;
x[0]=boss_shot.bullet.x;
y[0]=boss_shot.bullet[i].y;
}
if(t2>240 && t>60 && t%5==0){
for(j=0;j<30;j++){
if((k=search_boss_shot())!=-1){
boss_shot.bullet[k].col = 1;
boss_shot.bullet[k].x = x[i][0];
boss_shot.bullet[k].y = y[i][0];
boss_shot.bullet[k].knd = 1;
boss_shot.bullet[k].angle = bossatan3(i,ch.x,ch.y)+PI2/30*j;
boss_shot.bullet[k].flag = 1;
boss_shot.bullet[k].cnt = 0;
boss_shot.bullet[k].spd = 5;
se_flag[0]=1;
}
}
}
}
}
}

胡椒

Re:ボスのショットについてです。

#13

投稿記事 by 胡椒 » 15年前

Maさん>
Maさんのコードで上手くいきました!ありがとうございます!
しかし意味がよく分からないので質問してもいいでしょうか?

まず、MAX_BIGSHOTというのはなんなのでしょうか?画面に出ている大弾の数でしょうか?

また、index[MAX_BIGSHOT]の全てにはとりあえず-1を入れておいて

for(int n= 0; n < MAX_BIGSHOT; n++){
if(indexs[n] == k)
break;
if(indexs[n] == -1 || boss_shot.bullet[indexs[n]].flag <= 0 || boss_shot.bullet[indexs[n]].knd != 0 ){
indexs[n] = k;
break;

でkに入れ替えている、という解釈でいいでしょうか?

胡椒

Re:ボスのショットについてです。

#14

投稿記事 by 胡椒 » 15年前

すみません訂正です


<まず、MAX_BIGSHOTというのはなんなのでしょうか?画面に出ている大弾の数でしょうか?

なぜMAX_BIGSHOTは10なのでしょうか?という意味です

あ~る

Re:ボスのショットについてです。

#15

投稿記事 by あ~る » 15年前

む、なんか出来ちゃったみたいですけど一応僕の方の正解コード載せときます
あえて若干ミスってたんですけどわからなかったみたいなんで、頑張って理解してみて下さい
void boss_shot_bulletH015(){
        #define TM015 300
    int i,j,k,n,t=boss_shot.cnt,t2=boss_shot.cnt%TM015;
    if(t%100==0){
        for(i=0;i<2;i++){
            if((k=search_boss_shot())!=-1){
                boss_shot.bullet[k].col=4;
                boss_shot.bullet[k].knd=0;
                boss_shot.bullet[k].x=boss.x;
                boss_shot.bullet[k].y=boss.y;
                boss_shot.bullet[k].angle=PI2/300*t+i*PI;
                boss_shot.bullet[k].flag=1;
                boss_shot.bullet[k].cnt=0;
                boss_shot.bullet[k].spd=1.5;
                boss_shot.bullet[k].state=1;
                se_flag[0]=1;
            }
        }
    }
    for(i=0;i<BOSS_BULLET_MAX;i++){
        if(boss_shot.bullet.state==1 && boss_shot.bullet.flag>0 && boss_shot.bullet.cnt>50){
            boss_shot.bullet.spd=0;
            if(t%10==0){
            for(j=0;j<30;j++){
                if((k=search_boss_shot())!=-1){
                    boss_shot.bullet[k].col=1;
                    boss_shot.bullet[k].knd=0;
                    boss_shot.bullet[k].x=boss_shot.bullet.x;
                    boss_shot.bullet[k].y=boss_shot.bullet.y;
                    boss_shot.bullet[k].angle=bossatan3(k,ch.x,ch.y)+PI2/30*j;
                    boss_shot.bullet[k].flag=1;
                    boss_shot.bullet[k].cnt=0;
                    boss_shot.bullet[k].spd=5;
                    boss_shot.bullet[k].state=0;
                    se_flag[0]=1;
                    }
                }
            }
            if(boss_shot.bullet.cnt>200)boss_shot.bullet.flag=0;
        }
    }
}


#追記
どんな弾幕かわからなかったんで適当にアレンジしました 画像

Ma

Re:ボスのショットについてです。

#16

投稿記事 by Ma » 15年前

コメントつけました。

//大きな弾が表示される弾の最大数です。if(t%100==0)の頻度によって適応しなければなりません。現在は多くても6つだったので、10個にしておきました。
//もし、大きな弾が90個ぐらい出現する可能性があるなら、100確保する必要があります。そのため、あまり多いとメモリに無駄が発生しかねません。(intが2バイトなら200バイトしか使わないけどね…)
#define MAX_BIGSHOT 10

int i,x,k,t=boss_shot.cnt;
//boss_shot.bullet配列の中で大玉が指定されたインデックスを記録しておくための配列がindexsです。
static int indexs[MAX_BIGSHOT] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};

if(t%100==0){
for(i=0;i<2;i++){
if((k=search_boss_shot())!=-1){
boss_shot.bullet[k].col = 4;
boss_shot.bullet[k].x = boss.x;
boss_shot.bullet[k].y = boss.y;
boss_shot.bullet[k].knd = 0;
boss_shot.bullet[k].angle = (3+2*i)*PI/4;
boss_shot.bullet[k].flag = 1;
boss_shot.bullet[k].cnt = 0;
boss_shot.bullet[k].spd = 1.5;
se_flag[0]=1;
//indexs配列の中であいている配列を見つけ次第、そこにインデックスを代入します。
for(int n= 0; n < MAX_BIGSHOT; n++){
//同じインデックスがすでに登録されているなら、ループから出ます。
if(indexs[n] == k)
break;
//あいている場合、弾が消されている場合、そこに適応します。
if(indexs[n] == -1){
indexs[n] = k;
break;
}
}
}
}
}
//indexs配列で、登録されているが、すでに画面外に出たものや、他の弾になってしまっている弾は配列から除外します。
for(int n= 0; n < MAX_BIGSHOT; n++){
if(indexs[n] != -1){
if(boss_shot.bullet[indexs[n]].flag <= 0 || boss_shot.bullet[indexs[n]].knd != 0)
indexs[n] = -1;
}
}
//indexsの配列を全部回ります。
for(int n= 0;n < MAX_BIGSHOT; n++){
//indexs配列のn番目が空きではないのが条件。
if(indexs[n] != -1 && t%10==0){
if((k=search_boss_shot())!=-1){
boss_shot.bullet[k].col = 1;
boss_shot.bullet[k].x = boss_shot.bullet[indexs[n]].x;//大玉のインデックスはindexs[n]です。
boss_shot.bullet[k].y = boss_shot.bullet[indexs[n]].y;
boss_shot.bullet[k].knd = 8;
boss_shot.bullet[k].angle = PI;
boss_shot.bullet[k].flag = 1;
boss_shot.bullet[k].cnt = 0;
boss_shot.bullet[k].spd = 5;
se_flag[0]=1;
}
}
}
}



//私のは、メモリに多少無駄が出るうえ、static も使っているのであーるさんのが分かりやすいしいいと思う人も多いとおもいます。
それに対して、私のコードの長所はfor 文で MAX である 3000 だったかな?もループする必要がないところですかね。 画像

胡椒

Re:ボスのショットについてです。

#17

投稿記事 by 胡椒 » 15年前

あ~るさん、ありがとうございます!

自分のと比べてみたところ、おそらく
(t2>240 && t>60 && t%5==0)
の部分が悪かったのだと思います。(もちろんその前を()で閉じたところもですけど)

そのせいで最初の大弾も引っ張られてきて訳のわからないことになってたんんだとおもいます。
ここは大弾のカウントで制御したほうが簡単だったんですね。

また、大弾が止まるカウントもt(つまりboss_shot.cnt)で決めいてたからそのあとの小弾も止まってしまっていたみたいです。

胡椒

Re:ボスのショットについてです。

#18

投稿記事 by 胡椒 » 15年前

Maさん、ありがとうございます!
つまりMAX_BIGSHOTは一度実行してみて目で確認しながら調整しなければならないんですね。

Maさんのコードも理解しておくと役に立ちそうなので十分ためになりました!

本当にお二人ともありがとうございました!

閉鎖

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