ページ 11

sin(),cos()の値の上限値

Posted: 2010年3月28日(日) 01:35
by サンタクロース
こんばんわ。新しく作った弾幕が変な挙動を見せたので質問します。
この弾幕はボスを中心に弾が円運動をし、かつそれが拡大していくというものです。
しかし、円の半径が160を越えたあたりから弾が消えてしまうのです。
三角関数には、あまり大きな値を掛けてはいけないのでしょうか


void boss_shot_bulletH012(){
#define TM012 600
    int i,k,t=boss_shot.cnt%TM012,t2=boss_shot.cnt;
    double angle;
    
    if(t%200==0){
        angle=bossatan2();//自機とボスとの成す角
        for(i=0;i<60;i++){
            if((k=search_boss_shot())!=-1){
                boss_shot.bullet[k].col   = 4;//弾の色
                boss_shot.bullet[k].x     = 0;//座標
                boss_shot.bullet[k].y     = 0;
                boss_shot.bullet[k].knd   = 3;//弾の種類
                boss_shot.bullet[k].angle = 0;//角度
                boss_shot.bullet[k].flag  = 1;
                boss_shot.bullet[k].cnt   = 0;
                boss_shot.bullet[k].spd   = 0;//スピード
                se_flag[0]=1;
            }
        }
    }
    for(i=0;i<BOSS_BULLET_MAX;i++){
        if(boss_shot.bullet.flag>0){
                boss_shot.bullet.x     = boss.x+cos(PI2/60*i+boss_shot.bullet.cnt)*boss_shot.bullet.cnt;
                boss_shot.bullet.y     = boss.y+sin(PI2/60*i+boss_shot.bullet.cnt)*boss_shot.bullet.cnt;
                boss_shot.bullet.angle = bossatan3(i,boss.x,boss.y)+PI;
                    }
    }
}
画像

Re:sin(),cos()の値の上限値

Posted: 2010年3月28日(日) 05:01
by 紅葉
ソースを詳しく見ていないので間違えておりましたらすみません。

座標から角度を求めているようなのですがこれで意図したこととあっておりますか?
角度を増やしてcosやsinを使って位置を求めるのでしたらわかるのですが・・・。

また60で割っているのですが180ではないのでしょうか?
その他にもboss_shot.bullet.cntが0な気がするのですが・・・。

Re:sin(),cos()の値の上限値

Posted: 2010年3月28日(日) 05:09
by 紅葉
以前、同じようなことを行ったソースを一部改編したものです。
動かなかったらすみません。

このソースではどっちの方向にどのよう半径(Play.speed)で動くかというものです。

1、0~360度増えていく
2、Play.speedが一定なら円運動をする。
  今回は増えているので表示位置からどんどん離れて円運動をする。
// 開始時に1度だけ処理
void    Init(){
    Play.rot = 0;
    Play.speed = 0;
}

// 毎フレーム処理 
void    Loop(){

    Play.rot++;
    if(Play.rot > 360) Play.rot -= 360;

    float rot = float(Play.rot/180.0f*M_PI);    // 0~360です。 

    Play.speed += 0.01f;

    Pos.x = cos(rot) * Play.speed; 
    Pos.y = sin(rot) * Play.speed; 
}
宜しければ参考にして下さい。

Re:sin(),cos()の値の上限値

Posted: 2010年3月28日(日) 21:25
by たいちう
> しかし、円の半径が160を越えたあたりから弾が消えてしまうのです。
> 三角関数には、あまり大きな値を掛けてはいけないのでしょうか

憶測はやめましょう。

「弾が消えてしまう」

その時の弾の座標は何だろうか?

どの計算で、そのような意図しない座標になったのか?

計算のどの要素(三角関数の種類とか、角度とか、半径とか)が
おかしかったから、そのような値になったのか?

(半径がおかしかったとして)
どの計算で、そのような意図しない半径になったのか?

と、1つずつ確認し、原因を追及していきます。
ソースコードを確認するのも良いですが、慣れないうちは勘違いも多いので、
OutputDebugStringやprintfDxで、デバッグ出力に数値を表示させる方が確実です。

Re:sin(),cos()の値の上限値

Posted: 2010年3月28日(日) 22:08
by Dixq (管理人)
> boss.x+cos(PI2/60*i+boss_shot.bullet.cnt)*boss_shot.bullet.cnt

cosに渡す値に何故ラジアンではない物を渡すのでしょうか?
boss_shot.bullet.cntはただ1ずつ加算している整数です。

また、iをかける理由は何ですか?
弾はあいている番号を探してフラグを立て、計算するものなので、
iが連続するとは限りません。

適当な計算式で何かいい弾幕になるか考えるのではなく、事前に自分が作りたい弾幕を思い描き、
それが実現出来る計算式を考えだし、実装する方が良いと思います。

試行錯誤する事はよくありますが、「適当に計算式を作る」と言うのとは少し違うかなと。

で、何故消えているかですが、この弾幕は綺麗に少しずつ回転しているのではなく、
ものすごい勢いで回転しているのです。
回転している幅が1ラジアンずつである為、視覚的に少しずつ回転しているように見えますが。
1ラジアンは57.29578...°の事です。
ですから、大体1秒に10回転してます。

よって、弾がボスの上を通った時に「画面外」に一度出るので消えているのだと思います。

試しに弾幕の軌道計算関数内(boss_shot_calc関数)の「画面外に出るとフラグを落とす」部分のy範囲を広げてみてください。
弾は消え無くなると思います。

Re:sin(),cos()の値の上限値

Posted: 2010年3月30日(火) 00:11
by サンタクロース
回答ありがとうございます。
結果は無事にうまくいきました
> しかし、円の半径が160を越えたあたりから弾が消えてしまうのです。
> 三角関数には、あまり大きな値を掛けてはいけないのでしょうか

プログラミングをするためにこの腐った考えを排除出来るよう努力していきたいと思います。

> boss.x+cos(PI2/60*i+boss_shot.bullet.cnt)*boss_shot.bullet.cnt
>cosに渡す値に何故ラジアンではない物を渡すのでしょうか?
>boss_shot.bullet.cntはただ1ずつ加算している整数です。
>また、iをかける理由は何ですか?
>弾はあいている番号を探してフラグを立て、計算するものなので、
>iが連続するとは限りません。

こんな基礎にも気づけないとは自分は龍神録から何も学べていませんね

>適当な計算式で何かいい弾幕になるか考えるのではなく、事前に自分が作りたい弾幕を思い描き、
>それが実現出来る計算式を考えだし、実装する方が良いと思います。

ただこれだけは違います。自分は一日中弾幕のことを考えているような変人で弾幕を頭でまとめた上でやっております。
でもその結果がこれなら自分はプログラマにはなれないのでしょうかね。