弾を残像させる方法2

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

弾を残像させる方法2

#1

投稿記事 by yrao » 15年前

先日のスレが過去ログに入ってしまったので、改めて質問させていただきます。


softyaさん遅れてしまいすみません;



>弾を生成する場所
これはshot.cppのshot_main()関数で良いのでしょうか?

softya

Re:弾を残像させる方法2

#2

投稿記事 by softya » 15年前

過去ログは、これですね。
http://www.play21.jp/board/formz.cgi?ac ... 1261004873

>弾を生成する場所
>>これはshot.cppのshot_main()関数で良いのでしょうか?
違いますね。
ヒントとして、弾(bullet)のどのパラメータを変えると弾が生成され移動や表示されるか考えてみればわかりますよ。

yrao

Re:弾を残像させる方法2

#3

投稿記事 by yrao » 15年前

boss.shot.bullet.flagですか?

もしそうであれば、
search_boss_shot()
ではないかと考えているのですが…

softya

Re:弾を残像させる方法2

#4

投稿記事 by softya » 15年前

じゃぁ、そう仮定して何処を直せばよいか分かりますか?

yrao

Re:弾を残像させる方法2

#5

投稿記事 by yrao » 15年前

よく分からないです…

先日の穴埋め問題の、

1、配列を画面外で初期化する

この手順の¨配列を初期化する¨という事がよく分からない(方法が分からない)のです。

もし、龍神録のプロジェクトのなかで、他にこの配列の初期化をしている箇所があれば参考にしたいのですが、ありますでしょうか?

ちなみに初期化をする配列は、
・bx[10]
・by[10]
でいいんですよね?

softya

Re:弾を残像させる方法2

#6

投稿記事 by softya » 15年前

>この手順の¨配列を初期化する¨という事がよく分からない(方法が分からない)のです。

forループで回して同じ値を入れるだけですよ。

>・bx[10]
>・by[10]

bangleも同時に初期化してくださいね。

yrao

Re:弾を残像させる方法2

#7

投稿記事 by yrao » 15年前

for( int b=9 ; b>0 ; b-- ) {boss_shot[n].bullet[k].bx = -50;
・・・・・・


こういうことですか?

softya

Re:弾を残像させる方法2

#8

投稿記事 by softya » 15年前

>for( int b=9 ; b>0 ; b-- ) {

このfor文をここで使うのは間違っています。
bが9から始まって、bが1で終わるためです。
ごく普通にループを回せば良いだけですよ。

もし、本当にこれが分からないのであれば流石にC言語の基本的な勉強を1ヶ月で良いのでされた方が良いと思います。例えば0から100までの数値をprintfするプログラムは即時に作れますよね?
出来るのであれば難しく考えすぎだと思います。

yrao

Re:弾を残像させる方法2

#9

投稿記事 by yrao » 15年前

0~100を表示する
…というと

int i
for(i=0; i<=100; i++){
printf("%d\n",i);
}
ですよね?
(間違ってたらどうしよう…)


そうすると、
for(int b=0; b<=9; b++)

でしょうか

softya

Re:弾を残像させる方法2

#10

投稿記事 by softya » 15年前

>for(int b=0; b<=9; b++)
そうですね。これでOKです!

ただ、
for(int b=0; b<10; b++)
こう書くほうが一般的で、かつ配列の宣言時と同じ数値が出てくる方が後で直すときとかに便利ですね。

yrao

Re:弾を残像させる方法2

#11

投稿記事 by yrao » 15年前

分かりました。


後分からないのは、弾を発生させている場所ですね。これがどうにも…


確認したいのですが、
弾を生成するためのフラグは、

boss_shot.bullet.flag
ですよね?

softya

Re:弾を残像させる方法2

#12

投稿記事 by softya » 15年前

boss_shot.bullet[j].flag
が弾の存在有無を決めますね。
値が0なら存在しなくて、1なら存在です。

yrao

Re:弾を残像させる方法2

#13

投稿記事 by yrao » 15年前

boss_shot.bullet.flag
が1にされているのは、boss_shotH.cpp内のような気がするのですが、あってますか?

softya

Re:弾を残像させる方法2

#14

投稿記事 by softya » 15年前

>boss_shotH.cpp内のような気がするのですが、あってますか?
合ってますよ。
そもそも、全部のボスショットに残像を付けるんじゃなくて、特定のボスショットだけに残像を付けるつもりなんですよね?それとも全部ですか?

yrao

Re:弾を残像させる方法2

#15

投稿記事 by yrao » 15年前

ここまで話を進めておいて、質問の仕方が悪かったようです…


例えば、

『ケロちゃん風雨に負けず』
を作ってみよう

の章で、
boss_shot.bullet[k].eff_detail
を1にすると弾がピカピカ光るようになりますよね。あれと同じ仕組みで、
eff_detailを2にすると弾が尾を引く、という風にできないでしょうか?

という事だったのですが…明らかな質問不足でしたね。本当にすいません;

softya

Re:弾を残像させる方法2

#16

投稿記事 by softya » 15年前

であれば、そのショットの初期化時にeff_detailを2にして、弾残像の値もセットしてやれば良いだけですね。
で、残像の計算や表示処理もeff_detailが2の場合だけ行えばよいのです。

yrao

Re:弾を残像させる方法2

#17

投稿記事 by yrao » 15年前


また頭がこんがらがって来てしまいました;
次の二つのことについて確認させて下さい。



一つ目

>そのショットの初期化時にeff_detailを2にして、

…これは、段幕関数内で、boss_shot.bullet.x=□□□;
boss_shot.bullet.y=□□□;



のように書いているところで、
boss_shot.bullet.eff_detail=2;
と書いてやる
ということでしょうか?


二つ目

>弾残像の値もセットしてやれば良い

…この処理はどこに書くのでしょうか?
弾幕関数内ではないですよね?

softya

Re:弾を残像させる方法2

#18

投稿記事 by softya » 15年前

>>一つ目
その通りですね。
弾幕関数内で、弾を生成していますのでそこでeff_detail=2;を設定してやれば良いです。

>>二つ目
同じ場所ですよ。
弾のbx,byは一度でも使われると画面内の値が入っているんで画面外に再設定してやる必要があります。
まぁ、初回かどうか判定する必要も無く無条件に画面外座標の設定で良いでしょう。

yrao

Re:弾を残像させる方法2

#19

投稿記事 by yrao » 15年前

なるほど

つまり、
bx[10]
by[10]
bangle[10]
の初期化は、毎回、各弾幕関数内で行う、ということですか?

softya

Re:弾を残像させる方法2

#20

投稿記事 by softya » 15年前

>の初期化は、毎回、各弾幕関数内で行う、ということですか?
それでOKです。
私の趣味としては、それとは別にini関数で初期化しておきたいですけどね。
これは、長年の経験から初期化してない変数はバグの元って意識があるからです。

yrao

Re:弾を残像させる方法2

#21

投稿記事 by yrao » 15年前

了解です。
そうですね、ini関数内でも初期化することにします。



おかげさまで、ようやく弾を残像させる方法がわかってきました。
今から処理を書いていってみようと思います。
もしまた、プログラムの書き方で分からない所が出てたら質問させてくださいm(__)m

yrao

Re:弾を残像させる方法2

#22

投稿記事 by yrao » 15年前

出ました、エラーが;


error C2665: 'DrawRotaGraphF' : オーバーロードのどれも、すべての引数の型を変換できませんでした

というエラーです。
恐らく問題になっている箇所は、graph.cppのgraph_bullet()内の
if(boss_shot.bullet[j].eff_detail==2){
   for(int b=9; b>0; b--){
      double blend = 0.8;
      SetDrawBlendMode(DX_BLENDMODE_ALPHA,blend);
      DrawRotaGraphF(
      boss_shot.bullet[j].bx+FX+dn.x , boss_shot.bullet[j].by+FY+dn.y , 1.3 , disp_angle,
      img_bullet[boss_shot.bullet[j].knd][boss_shot.bullet[j].co[/url],TRUE);  
      blend-=0.07; 
   }
}

…だと思うのですが…

softya

Re:弾を残像させる方法2

#23

投稿記事 by softya » 15年前

少なくとも
>for(int b=9; b>0; b--){
は間違っています。
このループだけ取り出してbをprintfしてみて下さい。意味が分かります。
前のスレッドで、このループは特殊な使い方だと説明したはずですが・・・。

>SetDrawBlendMode(DX_BLENDMODE_ALPHA,blend);
だけして、
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0) ;
していないのも問題です。

エラーを見る限りDrawRotaGraphF()で間違いがあります。
まず、bx[/url]は配列のはずなのに添字がありません。
disp_angleと言う変数も何処で宣言したのか分かりませんし、bangle[/url]はどこで使われたのでしょうか?

その他にもエラーが出ているはずなんですが?出てませんか?

yrao

Re:弾を残像させる方法2

#24

投稿記事 by yrao » 15年前

いろいろと間違っていましたね(汗

とりあえず…
if(boss_shot.bullet[j].eff_detail==2){
    for(int b=0; b>10; b++){
       double blend = 0;
       SetDrawBlendModeDX_BLENDMODE_ALPHA,blend);
       DrawRotaGraphF(
       boss_shot.bullet[j].bx+FX+dn.x , boss_shot.bullet[j].by+FY+dn.y , 1.3 ,boss_shot.bullet[j].bangle ,
       img_bullet[boss_shot.bullet[j].knd][boss_shot.bullet[j].co[/url],TRUE);  
       SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
       blend+=0.07; 
    }
 }


に変更しました。
エラーは出なくなり、実行は出来るようになったのですが

・残像しない
・fpsがガタ落ち(29位まで落ちました)


…という現象が…




後、bx,by,bangleの三つの配列の初期化なのですが、弾幕作成に、龍神録の支館様の弾幕簡略化関数を用いているため、簡略化関数を作成している場所でまとめて初期化してしまっています。

不具合に関係があるかもしれないので一応…

softya

Re:弾を残像させる方法2

#25

投稿記事 by softya » 15年前

やたら、eff_detail==2にしてない限りは処理落ちしないはずです。
それと、if(boss_shot.bullet[j].eff_detail==2)の条件の前に、boss_shot.bullet[j].flagが1か確認してますよね?無効な弾の残像表示していたら遅くなりますよ。

あれ?
残像の位置の計算の話が出ませんが組み込まれたのでしょうか?
そちらのソースも処理する条件を見直してみて下さい。

yrao

Re:弾を残像させる方法2

#26

投稿記事 by yrao » 15年前

やっとインターネットにつなげたので、追加した部分とその周辺を載せますね。
(今まで携帯からの質問だったので)

・配列初期化
//  bullet_way(発射座標 X, 発射座標 Y, 分割(n道弾), ベース角度, 分割角度幅, 速度, 種類, 色, 状態,きらきら);
int bullet_way(double x, double y, int way, double angle, double angle2, double spd, int knd, int col, int state , int brt){
    int k,i;

    for(i=0;i<way;i++){
        if((k=search_boss_shot())!=-1){
            boss_shot.bullet[k].flag  = 1;
            boss_shot.bullet[k].cnt   = 0;
            boss_shot.bullet[k].x     = x;
            boss_shot.bullet[k].y     = y;
            boss_shot.bullet[k].angle = angle-angle2*(way/2)+angle2*i;
            boss_shot.bullet[k].knd   = knd;
            boss_shot.bullet[k].spd   = spd;
            boss_shot.bullet[k].col   = col;
            boss_shot.bullet[k].state = state;
            boss_shot.bullet[k].eff_detail = brt;
            
        }
    }
    for(int b=0; b<10; b++){//←ココ
        boss_shot.bullet[k].bx = -50;
        boss_shot.bullet[k].by = -50;
        boss_shot.bullet[k].bangle = 0;
    }
    se_flag[0]=1;

    return k;
}


・残像計算
void boss_shot_calc(){
    int i;
    boss.endtime--;
    if(boss.endtime<0)
        boss.hp=0;
    for(i=0;i<BOSS_BULLET_MAX;i++){
        if(boss_shot.bullet.flag>0){
            boss_shot.bullet.x+=cos(boss_shot.bullet.angle)*boss_shot.bullet.spd;
            boss_shot.bullet.y+=sin(boss_shot.bullet.angle)*boss_shot.bullet.spd;
            boss_shot.bullet.cnt++;
            if(boss_shot.bullet.flag!=0){//←ここから
                if(boss_shot.bullet.eff_detail==2){
                    for(int b=9; b>0; b--){
                        boss_shot.bullet[i].bangle=boss_shot.bullet[i].bangle[b-1];
                        boss_shot.bullet[i].bx=boss_shot.bullet[i].bx[b-1];
                        boss_shot.bullet[i].by=boss_shot.bullet[i].by[b-1];
                    
                        boss_shot.bullet[i].bangle[0]=boss_shot.bullet[i].angle;
                        boss_shot.bullet[i].bx[0]=boss_shot.bullet[i].x;
                        boss_shot.bullet[i].by[0]=boss_shot.bullet[i].y;
                    }
                }//←ここまで
            }
            if(boss_shot.bullet[i].cnt>boss_shot.bullet[i].till){
                if(boss_shot.bullet[i].x<-150 || boss_shot.bullet[i].x>FMX+150 ||
                    boss_shot.bullet[i].y<-150 || boss_shot.bullet[i].y>FMY+150)
                    boss_shot.bullet[i].flag=0;
            }
        }
    }
    
}

・残像描画
//弾丸の描画
void graph_bullet(){
    int i,j,eff;
    double disp_angle;
    SetDrawMode( DX_DRAWMODE_BILINEAR ) ;//線形補完描画
    for(i=0;i<SHOT_MAX;i++){//敵の弾幕数分ループ
        if(shot[i].flag>0){//弾幕データがオンなら
            for(j=0;j<SHOT_BULLET_MAX;j++){//その弾幕が持つ弾の最大数分ループ
                if(shot[i].bullet[j].flag!=0){//弾データがオンなら
                    if(shot[i].bullet[j].eff==1)
                        SetDrawBlendMode( DX_BLENDMODE_ADD, 255) ;
                    if(bullet_info[shot[i].bullet[j].knd].kaiten==1)
                        disp_angle=PI2*(shot[i].bullet[j].cnt%120)/120;
                    else
                        disp_angle=shot[i].bullet[j].angle+PI/2;

                    DrawRotaGraphF(
                        shot[i].bullet[j].x+FX+dn.x, shot[i].bullet[j].y+FY+dn.y,
                        1.0, disp_angle,
                        img_bullet[shot[i].bullet[j].knd][shot[i].bullet[j].co[/url],TRUE);

                    if(shot[i].bullet[j].eff==1)
                        SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0) ;
                }
            }
        }
    }
    void boss_assist_img();
    //ボス
    if(boss_shot.flag>0){//弾幕データがオンなら
        for(j=0;j<BOSS_BULLET_MAX;j++){//その弾幕が持つ弾の最大数分ループ
            if(boss_shot.bullet[j].flag!=0){//弾データがオンなら
                eff=0;
                if(boss_shot.bullet[j].kaiten==1)
                    disp_angle=PI2*(boss_shot.bullet[j].cnt%120)/120;
                else
                    disp_angle=boss_shot.bullet[j].angle+PI/2;
                if(boss_shot.bullet[j].eff_detail==1){//風雨にも負けず用弾エフェクト
                    SetDrawBlendMode( DX_BLENDMODE_ADD, 100+GetRand(155)),eff=1 ;
                    DrawRotaGraphF(
                        boss_shot.bullet[j].x+FX+dn.x, boss_shot.bullet[j].y+FY+dn.y,
                        1.3, disp_angle,
                        img_bullet[boss_shot.bullet[j].knd][boss_shot.bullet[j].co[/url],TRUE);
                }
                if(boss_shot.bullet[j].eff_detail==2){//残像
                    for(int b=0 ; b<10; b++){
                        double blend =0;
                        SetDrawBlendMode( DX_BLENDMODE_ALPHA, blend);
                        DrawRotaGraphF(
                            boss_shot.bullet[j].bx+FX+dn.x, boss_shot.bullet[j].by+FY+dn.y,
                            1.3,boss_shot.bullet[j].bangle,
                            img_bullet[boss_shot.bullet[j].knd][boss_shot.bullet[j].co[/url],TRUE);
                        SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0);
                        blend+=0.07;
                    }
                }
                if(boss_shot.bullet[j].eff==1)
                    SetDrawBlendMode( DX_BLENDMODE_ADD, 255),eff=1 ;
                if(boss_shot.bullet[j].eff==2)
                    SetDrawBlendMode( DX_BLENDMODE_ADD, 255+GetRand(100)),eff=1 ;
                DrawRotaGraphF(
                    boss_shot.bullet[j].x+FX+dn.x, boss_shot.bullet[j].y+FY+dn.y,
                    1.0, disp_angle,
                    img_bullet[boss_shot.bullet[j].knd][boss_shot.bullet[j].co[/url],TRUE);

                if(eff==1)
                    SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0) ;
            }
        }
//アシスト
・・・字数の都合上省略させていただきます。・・・    
    

       }
    SetDrawMode(DX_DRAWMODE_NEAREST);//描画形式を戻す
}


こんなところでしょうか。
ini関数内での初期化はまだ書いていません。
 
処理落ちは、いまだ改善されていない状況です;

ひよこ

Re:弾を残像させる方法2

#27

投稿記事 by ひよこ » 15年前

残像しないというのは、この部分が原因ではないのでしょうか?
boss_shot.bullet.bx=boss_shot.bullet.bx[b-1];
boss_shot.bullet.by=boss_shot.bullet.by[b-1];
どんどん新しくするときに弾の座標が入っていないのではないのでしょうか。
あと、残像のブレンドなのですが、ループごとに宣言しているように見えるので
色も変わらない気がします。

yrao

Re:弾を残像させる方法2

#28

投稿記事 by yrao » 15年前

ひよこさんありがとうございますm(__)m

返信がおくれてしまってすみませんでした。
 
>boss_shot.bullet.bx=boss_shot.bullet.bx[b-1];
>boss_shot.bullet.by=boss_shot.bullet.by[b-1];
>どんどん新しくするときに弾の座標が入っていないのではないのでしょうか。
>あと、残像のブレンドなのですが、ループごとに宣言しているように見えるので
>色も変わらない気がします。

下のように変更してみたところ、残像させることはできました。

 
 
if(boss_shot.bullet[j].eff_detail==2){//残像
                            
                    
                    for(int b=0 ; b<10; b++){
                        SetDrawBlendMode( DX_BLENDMODE_ALPHA, 225-b*30);
                        DrawRotaGraphF(
                            boss_shot.bullet[j].bx+FX+dn.x, boss_shot.bullet[j].by+FY+dn.y,
                            1.3,boss_shot.bullet[j].bangle,
                            img_bullet[boss_shot.bullet[j].knd][boss_shot.bullet[j].co[/url],TRUE);
                        SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0);
                        
                    }
                    
                }



(弾の座標計算の箇所は特にいじらなくても、残像は一応しました・・・)



残像させること自体はできたのですが、

・残像の弾の向きが、元の弾の向きと明らかに違う(bangle関係で、どこかがまちがっているのでしょうか・・・)

・(x,y)=(0,0)の場所に、残像するように設定した弾が描画されている。

・相変わらずfpsが28~30台
 

という不具合が・・・

これは何が問題になっているのでしょうか

swing

Re:弾を残像させる方法2

#29

投稿記事 by swing » 15年前

ひとつ気になったこと。
for(int b=0 ; b<10; b++){
  SetDrawBlendMode( DX_BLENDMODE_ALPHA, 225-b*30);
  DrawRotaGraphF(
225-b*30は0~255以内でないといけないと思うんですが。

wing

Re:弾を残像させる方法2

#30

投稿記事 by wing » 15年前

自分の名前、間違えました。
swingではなくwingです。
失礼しました。

ひよこ

Re:弾を残像させる方法2

#31

投稿記事 by ひよこ » 15年前

元の弾の向きと明らかに違う
>>これは角度が違います。普通の弾の描画にはdisp_angleが使われています。
>>disp_angleは回転のフラグが立っていなかったらdisp_angle=boss_shot.bullet[j].angle+PI/2;
>>と弾に角度を足して描いているのでそのままじゃおかしくなります。
しかし、私も作ってみましたがfpsが低くなってしまいますね。

softya

Re:弾を残像させる方法2

#32

投稿記事 by softya » 15年前

出遅れましたが、純粋に残像の描画負荷が重いのかも知れませんね。
時間ができたら試してみますね。

wing

Re:弾を残像させる方法2

#33

投稿記事 by wing » 15年前

もうひとつ気になったところが
if(boss_shot.bullet[j].eff==1)
      SetDrawBlendMode( DX_BLENDMODE_ADD, 255),eff=1 ;
    if(boss_shot.bullet[j].eff==2)
      SetDrawBlendMode( DX_BLENDMODE_ADD, 255+GetRand(100)),eff=1 ;
    DrawRotaGraphF(
      boss_shot.bullet[j].x+FX+dn.x, boss_shot.bullet[j].y+FY+dn.y,
      1.0, disp_angle,img_bullet[boss_shot.bullet[j].knd][boss_shot.bullet[j].co[/url],TRUE);

    if(eff==1)
      SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0) ;
のところで、
SetDrawBlendMode( DX_BLENDMODE_ADD, 255+GetRand(100)),eff=1 ;は
SetDrawBlendMode( DX_BLENDMODE_ADD, 155+GetRand(100)),eff=1 ;ではないでしょうか。

yrao

Re:弾を残像させる方法2

#34

投稿記事 by yrao » 15年前

皆さんありがとうございます。
 
 
>>wingさん
 
>for(int b=0 ; b<10; b++){
>  SetDrawBlendMode( DX_BLENDMODE_ALPHA, 225-b*30);
>  DrawRotaGraphF(
>225-b*30は0~255以内でないといけないと思うんですが。

・・・確かにそうですね、

SetDrawBlendMode( DX_BLENDMODE_ALPHA, 150-b*15);

に修正しました。
ご指摘どうもです。

>SetDrawBlendMode( DX_BLENDMODE_ADD, 155+GetRand(100)),eff=1 ;

これも修正しておきました。
 
 
 
 
>>ひよこさん
 
disp_angleに変更したところ、角度の問題は解決しました!
ありがとうございます。
 
 
 
>>softyaさん

 
お手数をおかけしてしまってすみません、
よろしくおねがいしますm(__)m

描画数が10倍以上になってしまうわけですし、
残像処理はやはり負荷が大きいのでしょうか・・・
 
せっかくここまでやってきたので、なんとか実装したいのですが・・・
配列の数を減らせば、処理も軽くなるでしょうか?
 
 
 
 
 
 
それと、あとひとつ、
 
玉が連続的に x=0,y=0 に描画されていく
 
この不具合の原因がわからないです;
 
 

ひよこ

Re:弾を残像させる方法2

#35

投稿記事 by ひよこ » 15年前

disp_angleじゃなくて
boss_shot.bullet[j].bangle+PI/2
としてくださいと言ったわけです。

yrao

Re:弾を残像させる方法2

#36

投稿記事 by yrao » 15年前

>>ひよこさん

意味を取り違えていました(+_+)

ありがとうございます、修正しました。

閉鎖

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