ページ 11

FPSを60に固定

Posted: 2009年12月29日(火) 15:26
by PG
こちらでDXライブラリについて勉強させていただいております。
こちらのサンプルをみてFPSを固定するということまで出来ました。

ただし毎回62.5で回ってしまうのですが
これを60にしたいです。

どのようにすればよいのでしょうか。

Re:FPSを60に固定

Posted: 2009年12月29日(火) 15:45
by kazuoni
ソースコードを見てみないとなんともいえないと思うので、
FPS制御の全ソースコードと、FPS制御関数(?)の使用している前後を
アップすればよい回答が返ってくるかもしれません。
(この掲示板は容量制限がありますが、添付機能があります。) 画像

Re:FPSを60に固定

Posted: 2009年12月29日(火) 15:49
by PG
意見ありがとうございます。
http://dixq.net/g/52.html
上記のソースを使っております。

Re:FPSを60に固定

Posted: 2009年12月29日(火) 16:15
by kazuoni
原因は
http://dixq.net/rp/43.html
に書いてあります。

そして回答もそちらに載ってます。
(管理人さんの書かれた方のが詳しく、わかりやすく載ってますので割合します^^;)

Re:FPSを60に固定

Posted: 2009年12月29日(火) 16:43
by PG
ご回答ありがとうございます。

閲覧させていただきました。
上手くいかないというよりはFILE fpがどこで宣言されているかがわかりません・・・。

また自分なりに変数の名前をかえてしまっております。

Re:FPSを60に固定

Posted: 2009年12月29日(火) 16:56
by kazuoni
> FILE fp

提示してくださったソースコード内にも、
管理人さんの書かれたhttp://dixq.net/rp/43.htmlにも
そのワードは出てきていませんが・・・?

Re:FPSを60に固定

Posted: 2009年12月29日(火) 17:03
by PG
下記のことです、
これはいらないのでしょうか?

fprintf(fp,"%d:%d\n",fps_count,term);
if(fps_count==600) fclose(fp);

Re:FPSを60に固定

Posted: 2009年12月29日(火) 17:11
by kazuoni
申し訳ありません。完全に見落としていました。
fprintfを管理人さんは使っていたのですね。。

必要ないと思いますよ。

Re:FPSを60に固定

Posted: 2009年12月29日(火) 17:33
by PG
消させて頂き動かせました。

ただ修正したのですが62.5になってしまいます。
定義は60です・・・。
void FPS(){

    int term,i,gnt;
    static int t=0;
    if(System.fpsCnt==0){//60フレームの1回目なら
        if(t==0)//完全に最初ならまたない
            term=0;
        else//前回記録した時間を元に計算
            term=System.fpsTime+1000-GetNowCount();
    }
    else    //待つべき時間=現在あるべき時刻-現在の時刻
        term = (int)(System.fpsTime+System.fpsCnt*(1000.0/FLAME))-GetNowCount();

    if(term>0)//待つべき時間だけ待つ
        Sleep(term);
    gnt=GetNowCount();
    if(System.fpsCnt==0)//60フレームに1度基準を作る
        System.fpsTime=gnt;
    System.fpsAdd[System.fpsCnt]=gnt-t;//1周した時間を記録
    t=gnt;
    //平均計算
    if(System.fpsCnt==FLAME-1){
        System.fpsAve=0;
        for(i=0;i<FLAME;i++)
            System.fpsAve+=System.fpsAdd;
        System.fpsAve/=FLAME;
    }
   System.fpsCnt = (++System.fpsCnt)%FLAME ;
}

Re:FPSを60に固定

Posted: 2009年12月29日(火) 18:25
by kazuoni
fpsAveをintからdoubleに変えてみてください。

Re:FPSを60に固定

Posted: 2009年12月29日(火) 18:32
by PG
出来ました><
ありがとうございます。
intだったのが原因だったのですね・・・。

Re:FPSを60に固定

Posted: 2009年12月29日(火) 18:38
by PG
すみませn。
解決マーク付けさせていただきます。

Re:FPSを60に固定

Posted: 2009年12月30日(水) 13:41
by Dixq (管理人)
fprintf(fp,"%d:%d\n",fps_count,term);
if(fps_count==600) fclose(fp);

↑これはデバッグ用にかいたコードで、消し忘れでした;
修正しました。ありがとうございます。

閉じるボタンを押したときにデバッグが終わらない

Posted: 2010年1月09日(土) 16:55
by tibi
お世話になります
C++の質問です。
WindowsXP
Visual C++ 2008 Express Edithionを使っています。

現在シューティングゲームを作っています。
画像の読み込みと破棄、音楽の再生と停止、クラスの生成と破棄はそれぞれコンストラクタとデストラクタで行っているのですが、ウィンドウの閉じるボタンを押して終了したときにデバッグが終わらず、
ウィンドウを閉じた後も音楽を再生しては停止、再生しては停止…を繰り返してしまいます。
その場合タスクマネージャからプロセスを終了させないと止まりません。
クラスの流れ
Main ─ Game ┬ Menu
             └ Shooting ┬ MyShip
                         ├ Enemy
                         └ 以下略 



int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        LPSTR lpCmdLine, int nCmdShow)
{
    Game game;
    if(DxLib_Init() == -1) return -1;  //ここでウィンドウサイズ(640,480)、裏画面描画、ログ出力の有無の設定を行う。
    SetDrawScreen(DX_SCREEN_BACK);
    game.Run();
    DxLib_End();
    return 0;
}


void Game::Run() {
    menu = new Menu(FPS);
    while(menu->Select() != 0) {  // メニュー画面
        RunStg();
    }
    //RunStg();
    delete menu;
    menu = NULL;
}

void Game::RunStg() {
    stg = new Shooting(FPS);
    stg->Run();  //シューティングの処理へ
    delete stg;
    stg = NULL;
}
参考
Shooting::Shooting(double fps) {
    WaitTime = (int)(1000/fps);
    PlayMusic("./music/sorato.mid", DX_PLAYTYPE_LOOP);
    FrameCount = 0;
    ship = new MyShip;
    shot = new Shot;
    enm = new Enemy;
    blt = new Bullet;
    scene = new Scene;
}

Shooting::~Shooting() {
    StopMusic();
    if(ship != NULL) {
        delete ship;
        ship = NULL;
    }
    if(shot != NULL) {
        delete shot;
        shot = NULL;
    }
    if(enm != NULL) {
        delete enm;
        enm = NULL;
    }
    if(blt != NULL) {
        delete blt;
        blt = NULL;
    }
    if(scene != NULL) {
        delete scene;
        scene = NULL;
    }
}
てっきりウィンドウの閉じるボタンを押した場合もデストラクタは呼び出されると思ってこのように
書いていたのですが、これだとマズいのでしょうか?

少し前の段階で
void Game::Run() {
    menu = new Menu(FPS);
    RunStg();
    delete menu;
    menu = NULL;
}
このようにメニュー用のループを入れていない時は普通に終了していました。

すみません、ソースが断片的過ぎるかとは思いますがこの辺りから推測できる
問題点はありますでしょうか。
それと、閉じるボタンを押された場合は特別な解放処理がなんかが必要なんでしょうか。

追記:
出力ウィンドウには
スレッド 'Win32 スレッド' (0x1f8) はコード 0 (0x0) で終了しました。
'Snow 0.02.exe': 'C:\WINDOWS\system32\mciseq.dll' をアンロード
'Snow 0.02.exe': 'C:\WINDOWS\system32\mciseq.dll' を読み込みました
スレッド 'Win32 スレッド' (0xbc0) はコード 0 (0x0) で終了しました。
'Snow 0.02.exe': 'C:\WINDOWS\system32\mciseq.dll' をアンロード
'Snow 0.02.exe': 'C:\WINDOWS\system32\mciseq.dll' を読み込みました
スレッド 'Win32 スレッド' (0x5e4) はコード 0 (0x0) で終了しました。
'Snow 0.02.exe': 'C:\WINDOWS\system32\mciseq.dll' をアンロード
'Snow 0.02.exe': 'C:\WINDOWS\system32\mciseq.dll' を読み込みました
スレッド 'Win32 スレッド' (0xbac) はコード 0 (0x0) で終了しました。
'Snow 0.02.exe': 'C:\WINDOWS\system32\mciseq.dll' をアンロード
'Snow 0.02.exe': 'C:\WINDOWS\system32\mciseq.dll' を読み込みました
スレッド 'Win32 スレッド' (0xa0c) はコード 0 (0x0) で終了しました。
'Snow 0.02.exe': 'C:\WINDOWS\system32\mciseq.dll' をアンロード
'Snow 0.02.exe': 'C:\WINDOWS\system32\mciseq.dll' を読み込みました

このような出力が繰り返されます。 画像

Re:閉じるボタンを押したときにデバッグが終わらない

Posted: 2010年1月09日(土) 18:03
by ベリ工
作りがまずいですね。
特に

>while(menu->Select() != 0) { // メニュー画面
> RunStg();
>}

のあたりが。OSからのメッセージを処理しないと
×ボタンで終了してもこのループはどうやって
"×ボタンから終了された"の判断を行うのでしょうか?

ここを参考にされるとよろしいかと。
http://dixq.net/rp/2.html

どうしても今の作りを変えたくないのであれば
×ボタンから終了できないように制御し、
必ずゲームのメインメニュー??の終了から行えるように
するとか・・・。

Re:閉じるボタンを押したときにデバッグが終わらない

Posted: 2010年1月09日(土) 18:27
by tibi
ベリ工さん、ありがとうございます!
試しに
void Game::Run() {
    menu = new Menu(FPS);
    while(menu->Select() != 0) {
        if(RunStg() == -1) break;  //中の処理でProcessMessage() == -1が返ってきた場合は戻り値で伝える
    }
    delete menu;
    menu = NULL;
}
にしたら直りました。
下の階層でProcessMessage() == -1 が返されたとき時に呼び出し元に伝えていなかったんですね。
もう一度見直してみます。ありがとうございましたm(_ _)m 画像