点数アイテムの吸収

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

点数アイテムの吸収

#1

投稿記事 by ft » 15年前

弾幕終了時にボスの弾が点数アイテムに変化して自機に吸収されるという処理を付けてみました.
しかし瞬間的にループ回数が増えるためか処理落ちしてしまいます.
どのような改善策がありますか?ソースは以下に貼っていきます

define.hの以下を変更
//アイテムの表示最大数
#define ITEM_MAX 200
out.cppに以下を追加
//ボス弾の位置に点数アイテムを置く
void enter_boss_item(){
    int i,item_n[1]={6};
        for(i=0;i<BOSS_BULLET_MAX;i++){
        enter_item(boss_shot.bullet.x, boss_shot.bullet.y, item_n, 1);
        }
}


boss_shot.cppでextern void enter_boss_item();を宣言して,
boss_shot_main()の赤字部分を追加

//ボスの弾幕メイン
void boss_shot_main(){
        if(stage_count==boss.appear_count[0] && boss.flag==0)//開始時間なら
                enter_boss(0);//開始
        if(boss.flag==0)//ボスが登録されて無ければ戻る
                return;
        calc_boss();
        if(boss.phy.flag==1)//物理演算移動オンなら
                calc_phy();//物理計算を
        if(boss.state==2 && (boss.hp<=0 || boss.endtime<=0)){//弾幕中で体力が無くなったら
                enter_boss_item(),enter_boss(1),se_flag[14]=1;//次の弾幕を登録
        }
        if(boss.state==1){//弾幕間の待機時間
                waitandenter();
        }
        if(boss.state==2){//弾幕中なら
                boss_shot_bullet[boss.knd]();//弾幕関数へ
                boss_shot_calc();//弾幕計算
        }
        boss.cnt++;
}


calc.cppに以下を追加

if(boss.flag==1 && boss.hp<=0){//ボス弾幕終了,点数itemのスピード0でそのまま吸収
    item.state=1;
    item.v=0;
    calc_item_indraw(i);
}

Justy

Re:点数アイテムの吸収

#2

投稿記事 by Justy » 15年前


> 瞬間的にループ回数が増えるためか処理落ちしてしまいます

 enter_boss_item関数の処理内容から察するに、BOSS_BULLET_MAX個分の……
標準から変えてないとしたら 3000ものアイテムを boss_shot.bulletの位置から
出そうとしています。

 これはboss_shot.bullet.flagによる弾の登録の有無に関わらず
BOSS_BULLET_MAX個分の生成をしようとしますので、それなりに重いはずです。
 しかも、登録がない弾の位置は不定になっている可能性があるので
おかしな位置にアイテムが出る可能性があるのではないでしょうか。


 まず改善策としては、弾の登録がされているところだけを対象に
アイテム化してみてはどうでしょうか?

 いや弾が未登録でもアイテムを出す必要がある、もしくは登録済みのところだけを
対象にしてもまだ処理が重い、ということであれば、Releaseでビルドして実行してみて下さい。

ft

Re:点数アイテムの吸収

#3

投稿記事 by ft » 15年前

search_boss_shot()関数を使えば登録されているかどうか判断できますか?

ft

Re:点数アイテムの吸収

#4

投稿記事 by ft » 15年前

そういえばsearch_boss_shot()関数でもBOSS_BULLET_MAX個分のループをしておりましたね;
最初にフラグの有無も考えてみたのですが
これもBOSS_BULLET_MAX個分やってしまうため確かに遅くなってしまいますね.

>まず改善策としては、弾の登録がされているところだけを対象に
アイテム化してみてはどうでしょうか?

どのようにやればいいのでしょうか?

Justy

Re:点数アイテムの吸収

#5

投稿記事 by Justy » 15年前


> どのようにやればいいのでしょうか

 BOSS_BULLET_MAX個のボスショットを管理する配列のうち、
どれが登録されている(=使われている、表示されている)弾かの区別の
付け方はわかりますか?

 それさえわかれば enter_boss_item関数の、BOSS_BULLET_MAX分の forループを
回しているところで enter_item関数を呼ぶ際に参照する boss_shot.bulletが、
実際に使用されているものだけ行うようにすれば、いいんじゃないかと思います。

 そうすれば、5つしか弾が残っていなければ、5回だけしか enter_item関数は
呼ばれないので、その5つだけに対してアイテムが出現する、はずです。

ft

Re:点数アイテムの吸収

#6

投稿記事 by ft » 15年前

>BOSS_BULLET_MAX個のボスショットを管理する配列のうち、
どれが登録されている(=使われている、表示されている)弾かの区別の
付け方はわかりますか?

すみません,分かりません.

Justy

Re:点数アイテムの吸収

#7

投稿記事 by Justy » 15年前

 boss_shot.bullet[n].flagの値を見ることで、調べることができます。

 out.cppを見てるならこういうコードがあります。
[color=#d0d0ff" face="monospace]
for(n=0;n<BOSS_BULLET_MAX;n++){//弾総数
if(boss_shot.bullet[n].flag==1){//弾が登録されていたら
[/color]

 まんま、ですね。

 さすがに弾が使われているかいないかの区別が付かないというのは、大問題です。
 機能追加や改良を施す前に、龍神録の館をもう一度読み直すとかじっくり解析して、
龍神録のコードの理解を深めた方がいいかと思いますよ。

ft

Re:点数アイテムの吸収

#8

投稿記事 by ft » 15年前

それでしたら知っております.少々違った解釈をしてしまって勘違いしていました.

out.cppのenemyshot_and_ch()関数の
if(boss_shot.bullet[n].flag==1)
以降に
if(boss.hp<=0){
    enter_item(boss_shot.bullet[n].x, boss_shot.bullet[n].y, item_n, 1);
}
を追加することで同様の動作が得られました.
しかしあまりfpsは上昇しませんでした.

Justy

Re:点数アイテムの吸収

#9

投稿記事 by Justy » 15年前


> if(boss_shot.bullet[n].flag==1)
> 以降に
> ~
> しかしあまりfpsは上昇しませんでした

 そこでもだめですか。

 んー、となると
・ enter_boss_item()をコメントアウトすると処理落ちはしないのですか?
・ 前にも書きましたが Releaseビルドではどうですか?


 あ、直悦的には関係ないのですが [color=#d0d0ff" face="sans-serif]item_n[1]={6}[/color] のようにアイテムの指定をしていますが、
点数アイテムというのは6でいいのですか?

ft

Re:点数アイテムの吸収

#10

投稿記事 by ft » 15年前

遅れてすみません.

>enter_boss_item()をコメントアウトすると処理落ちはしないのですか?
はい,そうです.

>前にも書きましたが Releaseビルドではどうですか?
最初からReleaseビルドをやっておりましたので,その上での結果となります.

また,点数アイテムは私が新たに加えたアイテムで,番号は6と割り当てております.


書き忘れておりましたが,DXライブラリPortableというライブラリを用いてPSPにおける動作を試みているため,
もしかしたら描画まわりの方にも原因があるのかもしれません.

Justy

Re:点数アイテムの吸収

#11

投稿記事 by Justy » 15年前

 あぁ、PSPでしたか。
 前のスレを思い出しました。
 となると、どの程度龍神録から変更されたのかわからないですし
持ってないので、これ以上は何とも言いようがないですが、
ボトルネックの計測をして、処理落ちの原因になっている
直接の原因を調べるしかないです。

 その原因が特定できれば対策もたてられるかと思います。

ft

Re:点数アイテムの吸収

#12

投稿記事 by ft » 15年前

その計測というのは第44章のデバッグ支援関数を使えば良いということですよね?
(これとfpsを見る以外の方法は知りません;)

ちなみにネックを調べるために導入するこの関数計算自体がPSPにとって非常に重かったりします(汗)
その上で,enter_boss_item()をコメントアウトした場合,しない場合でかかる時間を調べれば良いということですか?

Justy

Re:点数アイテムの吸収

#13

投稿記事 by Justy » 15年前

遅くなりました。


> 第44章のデバッグ支援関数
> 関数計算自体がPSPにとって非常に重かったりします

 一番いいのはちゃんとした測定ツールを使うことですが、
現状それは望めないので、まずは44章を参考にということになります。

 ただそのままで PSPの環境に合うのかどうかはわかりません。
 合わなければうまく環境に合わせて調整してみて下さい。



> enter_boss_item()をコメントアウトした場合,しない場合でかかる時間を調べれば良いということですか

 それだけではなく、全体の負荷と enter_boss_itemから波及する部分にも
手を広げる必要があるかと。

 最終的にどこの処理に負荷がかかっているかがわかればいいので、
そのあたりは実際にやってみて試行錯誤してみて下さい。

ft

Re:点数アイテムの吸収

#14

投稿記事 by ft » 15年前

計測した結果,敵弾が点数アイテムへ変化する際にgraph.cppにて時間が掛かっておりました.

PSPは仕様上メモリへのアクセスがとても遅いらしく,
そして瞬時に多数の描画が増えるため処理落ちが起こるのではないかと考えております.

またPSPの描画関係をライブラリに頼っている現状,
私自身の力不足で描画自体の速度に関してはどうすることも出来ません.(ライブラリの描画速度も発展途上とのことです)

弾幕中でもないですし,この処理落ち自体もほんの一瞬のことで,「遅くなった」と体感できない程のため,
これで妥協しようかとも思っております.

ft

Re:点数アイテムの吸収

#15

投稿記事 by ft » 15年前

他にもcalc.cppでも時間が掛かることが判りました.

アイテムを自動吸収処理をする関数calc_item_indrawです.

そこで,自機との角度を返すatan2をatan2fとすることで処理落ちが無くなりました.

graph.cppは相変わらずでしたので,原因はここだったと思われます.

いろいろなご助言ありがとうございました!

Justy

Re:点数アイテムの吸収

#16

投稿記事 by Justy » 15年前


> 自機との角度を返すatan2をatan2fとすることで処理落ちが無くなりました

 見つかって良かったですね。

 ただ、1カ所あるということは他にもそういうところはありそうな感じもしますし、
この際徹底的にその手のボトルネックを見つけておいた方がいいのかもしれません。

ft

Re:点数アイテムの吸収

#17

投稿記事 by ft » 15年前

そうですね,三角関数はfastmathにするかテーブルを参照させる事に決めているため,
これは単に見落としていた,という事になります.
ちなみにテーブル参照にすると何故か遅くなる箇所がるため,一つ一つ確かめて使い分けています.
PSPのメモリアクセスが遅いことが関係しているのかもしれません.

他にもそのような部分があるかもしれないので見直してみようかと思います.

閉鎖

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