トップページ > 記事閲覧
リフレッシュレートの違いでゲーム速度が変わってしまいます💦
名前:ゆめゆめYUME 日時: 2022/11/15 17:14

144ヘルツのパソコン(ゲーミングPC)でゲームを作りました。すると、一般的なパソコンは60ヘルツなので、普通のパソコンで遊ぶと速度が遅くなってしまいました。 改善するために、動くものを144/60倍つまり2.4倍にしたりして、いろいろと工夫したのですが、バグだらけになってしまい、自分のパソコンで動くものとは変わり果ててしまいました。 どうにかして144ヘルツのゲームを、60ヘルツのゲームに変換できないでしょうか。。。 (半年くらいかけて制作したゲームなので諦めたくないのです…) どうかご教授よろしくお願いします!
メンテ

Page: 1 |

Re: リフレッシュレートの違いでゲーム速度が変わってしまいます💦 ( No.1 )
名前:名無三 日時:2022/11/15 20:03

・SetGraphModeで指定できるなら指定 ・上ができないなら計算を修正 足し算なら A += B; を A += B * 60.f/GetFPS(); に 掛け算なら積分を用いて A *= B; を A += A * (std::powf(B, 60.f / FPS) - 1.f); にする ・自前で60FPSを維持するようにタイマーを用意する(以下例) SetWaitVSyncFlag(FALSE);//垂直同期を切る。Init前にやる { /*初期化処理*/ } m_Wait = GetNowHiPerformanceCount();//開始時の経過秒数を得る while (ProcessMessage() == 0) { { /*ループ処理*/ ScreenFlip(); } //次ループに行く直前に待機 while ((GetNowHiPerformanceCount() - m_Wait) <= (1000 * 1000 / 60)) {}//16.66msループ m_Wait = GetNowHiPerformanceCount();//現時点の経過秒数を得る } 上記のいづれかの対応ができそうです(3つ目はちょっと安定しなかったので自分はあまりしませんが…)
メンテ
Re: リフレッシュレートの違いでゲーム速度が変わってしまいます&#128166; ( No.2 )
名前:管理人 日時:2022/11/18 00:44

名無三さんの『・自前で60FPSを維持するようにタイマーを用意する(以下例)』に近い処理となりますが、 『144ヘルツ用のプログラムを144ヘルツ以外の環境で無理やり実行する』というサンプルプログラムを 作ってみましたので、よろしければ参考にしてください m(_ _)m #include "DxLib.h" // プログラムで想定するヘルツ #define FPS 144 int x = 0, xadd = 8 ; // 1フレーム分動作させる関数 void Move( void ) { // x座標が画面の左右に達したら移動方向を反転させる x += xadd ; if( x < 0 || x > 640 ) xadd = -xadd ; } // 描画を行う関数 void Render( void ) { // 画面をクリア ClearDrawScreen() ; // 現在の座標に矩形を描画する DrawBox( x, 0, x + 32, 32, GetColor( 255,255,255 ), TRUE ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { LONGLONG PrevTime ; LONGLONG NextAddTime ; int NextLoopMoveNum ; // ウィンドウモードで起動 ChangeWindowMode( TRUE ) ; // ウィンドウが非アクティブになっても動作するようにする SetAlwaysRunFlag( TRUE ) ; // DXライブラリ初期化処理 if( DxLib_Init() == -1 ) return -1; // エラーが起きたら直ちに終了 // 描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; // 現在の時間を取得しておく PrevTime = GetNowHiPerformanceCount() ; // 余り時間を 0 にする NextAddTime = 0 ; // 次のループで行う動作関数呼び出しの数を1に設定 NextLoopMoveNum = 1 ; // メインループ while( ProcessMessage() == 0 ) { // NextLoopMoveNum の回数だけ動作させる関数を呼び出し for( int i = 0 ; i < NextLoopMoveNum ; i ++ ) { Move() ; } // 描画する関数を呼び出し Render() ; // ソフトのウィンドウが非アクティブかどうかで処理を分岐 if( GetActiveFlag() == FALSE ) { // 非アクティブの場合はアクティブになるまで待つ while( ProcessMessage() == 0 && GetActiveFlag() == FALSE ) { Sleep( 1 ) ; } // アクティブになったら時間関係のパラメータを初期化して次のループに進む PrevTime = GetNowHiPerformanceCount() ; NextAddTime = 0 ; NextLoopMoveNum = 1 ; } else { LONGLONG NowTime ; LONGLONG LoopTime ; // 現在の時間を取得 NowTime = GetNowHiPerformanceCount() ; // 前回の時間との差分を計算 LoopTime = NowTime - PrevTime ; // 経過した時間が1フレーム分に満たない場合は1フレーム分の時間が経過するまで待つ if( LoopTime < 1000000 / FPS ) { while( ProcessMessage() == 0 && LoopTime < 1000000 / FPS ) { NowTime = GetNowHiPerformanceCount() ; LoopTime = NowTime - PrevTime ; } } // 次のループで実行する動作関数の回数を算出( 経過した時間を1フレーム分の時間で割る ) NextLoopMoveNum = ( int )( ( LoopTime + NextAddTime ) / ( 1000000 / FPS ) ) ; // 割って余った時間は次のループの計算の際に使用するので余り時間を保存しておく NextAddTime = ( LoopTime + NextAddTime ) - NextLoopMoveNum * ( 1000000 / FPS ) ; // 今回の時間を保存しておく PrevTime = NowTime ; } } // DXライブラリ使用の終了処理 DxLib_End() ; // ソフトの終了 return 0 ; } 仕組みとしては、144ヘルツの場合メインループを 2.4ループすると 60ヘルツの 1ループの時間に相当するので 1ループに掛かった時間に応じて動作の処理を何回も実行する、というものです ( NextLoopMoveNum が何回動作の処理を実行するか、という回数を保存する変数です ) 動く物の速度の値を 2.4倍にしてうまく動作させることができれば見た目の動きは綺麗になりますが、上記のような 『144ヘルツの処理のまま、別のヘルツの環境で動かしてしまう』のが一番簡単です (^ ^; ( 少し動作はぎこちなくなりますが… )
メンテ
Re: リフレッシュレートの違いでゲーム速度が変わってしまいます&#128166; ( No.3 )
名前:たろう 日時:2022/11/17 22:15

すみません、横から失礼しますm(__)m 私も自前のFPS制御に自信がないので、取り換えて こちらを使わせてもらおうかと試したのですが、 動作を確認するために下のように改造したところ、 1000ミリ秒ごとにMoveを平均120回通過しているようです 私のチェックが間違えているのかもしれません どうでしょうか?m(__)m #include "DxLib.h" // プログラムで想定するヘルツ int FPS=144,今fps,MOVi=0; int x = 0, xadd = 8 ; double FFPSave(){ static double rt=0; static int t=GetNowCount(); if(GetNowCount()-t>1000){t+=1000;rt=MOVi;MOVi=0;} return rt;} // 1フレーム分動作させる関数 void Move( void ) { // x座標が画面の左右に達したら移動方向を反転させる x += xadd ; if( x < 0 || x > 640 ) xadd = -xadd ; MOVi++; } // 描画を行う関数 void Render( void ) { // 画面をクリア ClearDrawScreen() ; // 現在の座標に矩形を描画する DrawBox( x, 0, x + 32, 32, GetColor( 255,255,255 ), TRUE ) ; DrawFormatString( 0,50,GetColor(255,255,255),"今fps(%d)",今fps ); // 裏画面の内容を表画面に反映 ScreenFlip() ; } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { LONGLONG PrevTime ; LONGLONG NextAddTime ; int NextLoopMoveNum ; // ウィンドウモードで起動 ChangeWindowMode( TRUE ) ; // ウィンドウが非アクティブになっても動作するようにする SetAlwaysRunFlag( TRUE ) ; // DXライブラリ初期化処理 if( DxLib_Init() == -1 ) return -1; // エラーが起きたら直ちに終了 // 描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; // 現在の時間を取得しておく PrevTime = GetNowHiPerformanceCount() ; // 余り時間を 0 にする NextAddTime = 0 ; // 次のループで行う動作関数呼び出しの数を1に設定 NextLoopMoveNum = 1 ; // メインループ while( ProcessMessage() == 0 ) { 今fps=FFPSave(); // NextLoopMoveNum の回数だけ動作させる関数を呼び出し for( int i = 0 ; i < NextLoopMoveNum ; i ++ ) { Move() ; } // 描画する関数を呼び出し Render() ; // ソフトのウィンドウが非アクティブかどうかで処理を分岐 if( GetActiveFlag() == FALSE ) { // 非アクティブの場合はアクティブになるまで待つ while( ProcessMessage() == 0 && GetActiveFlag() == FALSE ) { Sleep( 1 ) ; } // アクティブになったら時間関係のパラメータを初期化して次のループに進む PrevTime = GetNowHiPerformanceCount() ; NextAddTime = 0 ; NextLoopMoveNum = 1 ; } else { LONGLONG NowTime ; LONGLONG LoopTime ; // 現在の時間を取得 NowTime = GetNowHiPerformanceCount() ; // 前回の時間との差分を計算 LoopTime = NowTime - PrevTime ; // 経過した時間が1フレーム分に満たない場合は1フレーム分の時間が経過するまで待つ if( LoopTime < 1000000 / FPS ) { while( ProcessMessage() == 0 && LoopTime < 1000000 / FPS ) { NowTime = GetNowHiPerformanceCount() ; LoopTime = NowTime - PrevTime ; } } // 次のループで実行する動作関数の回数を算出( 経過した時間を1フレーム分の時間で割る ) NextLoopMoveNum = ( int )( ( LoopTime + NextAddTime ) / ( 1000000 / FPS ) ) ; // 割って余った時間は次のループの計算の際に使用するので余り時間を保存しておく NextAddTime = LoopTime - NextLoopMoveNum * ( 1000000 / FPS ) ; // 今回の時間を保存しておく PrevTime = NowTime ; } } // DXライブラリ使用の終了処理 DxLib_End() ; // ソフトの終了 return 0 ; }
メンテ
Re: リフレッシュレートの違いでゲーム速度が変わってしまいます&#128166; ( No.4 )
名前:管理人 日時:2022/11/18 00:51

ご指摘ありがとうございます すみません、この行の計算式が間違っていました orz <誤> NextAddTime = LoopTime - NextLoopMoveNum * ( 1000000 / FPS ) ; <正> NextAddTime = ( LoopTime + NextAddTime ) - NextLoopMoveNum * ( 1000000 / FPS ) ; 上記のように変更することで1000ミリ秒辺り平均144回通過するようになりますので、よろしければお試しください m(_ _;m ( 私の投稿の方は修正しておきました m(_ _;m )
メンテ
Re: リフレッシュレートの違いでゲーム速度が変わってしまいます&#128166; ( No.5 )
名前:たろう 日時:2022/11/18 06:12

ありがとうございます、ちゃんと動きました。 では、引っ込みますm(__)m
メンテ
Re: リフレッシュレートの違いでゲーム速度が変わってしまいます&#128166; ( No.6 )
名前:ゆめゆめYUME 日時:2022/11/19 21:30

返信ありがとうございます! 私も試してみます!
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存