ページ 1 / 1
timeBeginPeriodについて
Posted: 2014年3月21日(金) 03:32
by sql
Sleep関数の精度を上げようと思い、timeBeginPeriod関数を使いたいのですが、どこに宣言したらいいかわかりません・・・・
※1
コード:
void C_GameWindow::MainLoop()
{
timeBeginPeriod(1);
while( !ScreenFlip() && !ProcessMessage() && !ClearDrawScreen() && !clsDx() )
{
fps->Wait();
calc();
draw();
fps->Draw();
}
timeEndPeriod(1);
}
※2
コード:
#include "DxLib.h"
#include "GameWindow.h"
// メイン
int WINAPI WinMain( HINSTANCE hInstance , HINSTANCE hPrevInstance , LPSTR lpCmdLine , int nCmdShow )
{
C_GameWindow gamewindow;//インスタンス生成
timeBeginPeriod(1);
gamewindow.MainLoop();//メインループをここで回す
timeEndPeriod(1);
return 0;
};
とあり、while文の前後に宣言(※1)または、main文の中に宣言するのとどちらが良いのでしょうか?
また、sleep関数はfps制御クラスの関数の中にあります・・・その関数のsleep関数の前後に書くだけ、というのでもいいのでしょうか?
更に、timeBeginPeriod関数の危険性も調べたのですが、公開するゲームにこの関数が使われていたら、redume.txtたるものにこの関数が使われていることを書いたほうがいいのでしょうか?
Re: timeBeginPeriodについて
Posted: 2014年3月21日(金) 06:51
by へにっくす
これですね。
timeBeginPeriod - MSDN
書いた方が親切なのは確かですね。
でも書いたら書いたで、遊ぶ人は二の足踏みそうですけど (^^;
sleep関数って
これのこと?
だったらその前後でいいのでは。
必要な時に呼び出し、終わったら即後始末ですね。
※1、※2のように全体にかけたらやばいと思いますよ。
個人的にはSleep関数使う意味がわかりませんが。→参考)
補足資料.11章 書いてはいけない4つの処理
以下のページも参考になるかな
Windows, C++ で処理時間を計測。そしてtimeBeginPeriod()。
Re: timeBeginPeriodについて
Posted: 2014年3月21日(金) 13:07
by sql
返信ありがとうございます。
へにっくす さんが書きました:必要な時に呼び出し、終わったら即後始末ですね。
※1、※2のように全体にかけたらやばいと思いますよ。
毎フレーム呼び出し→後始末では重くなってしまうと思ったので全体に・・・と思いましたが、やはりSleep関数の前後でいいのですね。
へにっくす さんが書きました:個人的にはSleep関数使う意味がわかりませんが。
基本的に、ここの龍神録のコードを参考にしているのですが、C++版のfpsクラスの中に普通にSleepはありましたし、
へにっくす さんが書きました:参考)補足資料.11章 書いてはいけない4つの処理
の中にも「fps以外で・・・」と書いてあるので大丈夫かなと。
Re: timeBeginPeriodについて
Posted: 2014年3月21日(金) 15:39
by sql
追記
後々誤解をまねかないように書いておきますと、「参考にしている」のは龍神録(fps制御などごく一部)で、「現在作っている」のはリズムゲームです。
譜面と音楽の同期が重要だと思うのでこの質問をしました。
シューティングを作っていてこの質問・・・と思われる方がいらっしゃるかもしれないので・・・。
Re: timeBeginPeriodについて
Posted: 2014年3月21日(金) 18:42
by naohiro19
timeBeginPeriod
timeEndPeriod
の2つの関すはwinmm.hに記述されている時間関連の関数の精度を上げるためのものなのでDXライブラリでは意味がありません。
Re: timeBeginPeriodについて
Posted: 2014年3月21日(金) 20:51
by sql
返信ありがとうございます。
naohiro19 さんが書きました:timeBeginPeriod
timeEndPeriod
の2つの関すはwinmm.hに記述されている時間関連の関数の精度を上げるためのものなのでDXライブラリでは意味がありません。
とありますが、調べたら、
過去の類似したトピックのN0.5の回答で、大丈夫のような書き込みが見られるのですが・・・・
実際のところ、どうなのでしょうか?
Re: timeBeginPeriodについて
Posted: 2014年3月21日(金) 21:17
by sql
追記:1つ前の自分の返信の
類似した過去のトピックのNO.12に提示されたコードでは、mainの中のwhileのループ前にtimebeginPeriod(1)が書かれていますが、このトピックのはじめの質問である
sql さんが書きました:、while文の前後に宣言(※1)または、main文の中に宣言するのとどちらが良いのでしょうか?
の※1と似ているように思えてしまいます・・・・
自分なりの解釈ですが、類似過去トピックは無限ループ内にFPS制御、更新の関数があり、(その関数の中には)ミリ秒取得の処理もあるので、ループ前に書いたと思うのですが・・・自分の最初に提示したコードのMainLoop関数の中にfps制御が入っています・・・
どちらが正しいのか今の自分には判断できませんので、回答よろしくお願いします。
Re: timeBeginPeriodについて
Posted: 2014年3月21日(金) 22:39
by ISLe
ふつうはプログラムの最初のほうで設定して最後のほうで解除すると思います。
※1か※2かというのは、C_GameWindowクラスにとってtimeBeginPeriodが重要かどうかで決まるのではないでしょうか。
と言っても、そもそもDxLib_Init関数を呼んだ時点で精度が1ミリ秒に設定されるはずで自前でやる意味がありません。
Sleepは絶対に使ってはいけないというものではありません。
新・ゲームプログラミングの館にも以下のように書かれています。
FPS制御以外の部分で、Wait、Sleep系関数が含まれていたらその設計は間違いです。
※下線は加筆
ScreenFlip関数はモニタのリフレッシュレートにタイミングを合わせるだけです。
リフレッシュレートが60Hzでなければ60FPSになりません。
絶対に60FPSでゲームを動かしたいなら自前でフレームレートを制御する必要があります。
その場合、待機時間にSleepを使わないとCPU使用率が無駄に上がります。
フレームレートを制御するのであればSleepは必須です。
(参考)
処理落ちしても一定のFPS制御:ISLeのビデオゲーム工房
Sleep(1)と書いて15ミリ秒経過しないと戻らなかったのが正確に1ミリ秒で戻ると電力をより消費するというのは当たり前の話ですね。
そもそもがそう動作するように書かれていたわけです。
そういった電力消費に無頓着なコードがあふれていたおおむかしはバッテリーが減ると言ってtimeBeginPeriodを毛嫌いするひとがいました。
適切にSleepを使えば無駄に電力を消費することはないし処理時間も最適化します。
10分で済む処理を20分掛けたほうがバッテリーの持ちが良いなどというのはナンセンスだと思います。
timeBeginPeriodは、GetTickCountやウィンドウプロシージャのタイマーイベントにも影響を与えます。
ウィンドウズ95や98のころは、API毎に異なる(どのように異なるかも環境ごとに違う)こともあったようですが。
Re: timeBeginPeriodについて
Posted: 2014年3月21日(金) 23:11
by sql
返信ありがとうございます。
ISLe さんが書きました:と言っても、そもそもDxLib_Init関数を呼んだ時点で精度が1ミリ秒に設定されるはずで自前でやる意味がありません。
恥ずかしいことに知りませんでした・・・・DXライブラリのリファレンスを見たのですが精度のことについては表記されていなかったので、DXライブラリの方の掲示板で質問したいと思います。(確認のため。管理人からの直接の返信が来れば最高ですが。)
ISLe さんが書きました:絶対に60FPSでゲームを動かしたいなら自前でフレームレートを制御する必要があります。
その場合、待機時間にSleepを使わないとCPU使用率が無駄に上がります。
フレームレートを制御するのであればSleepは必須です。
(参考)処理落ちしても一定のFPS制御:ISLeのビデオゲーム工房
リズムゲームを作成しているので、音楽と譜面の同期が重要視されると思いますので、できるだけ60fpsに近い状態に常にいないといけないと思い、Sleep関数の精度を上げるtimeBeginPeriodについて質問した次第です。
ズレの補正などのプログラムはこれからなので・・・。
また、参考ページもありがたいです。
ISLe さんが書きました:Sleep(1)と書いて15ミリ秒経過しないと戻らなかったのが正確に1ミリ秒で戻ると電力をより消費するというのは当たり前の話ですね。
そもそもがそう動作するように書かれていたわけです。
そういった電力消費に無頓着なコードがあふれていたおおむかしはバッテリーが減ると言ってtimeBeginPeriodを毛嫌いするひとがいました。
いろいろなサイトにSleep(1);とやっても15ミリくらいになる・・・と書かれていました。
昔のことも少し知れて良かったです。(何かの参考になるかもしれません。)
オフトピック
とあるサイトに書かれていたのですが、timeBeginPeriodを使わなくてもwindows media playerを起動させた状態でやれば、timeBeginPeriodの危険性の1つとして書いてあった「他のプロセスにも影響する」の通り、精度が1ミリ秒になるのは本当なのでしょうか?
Re: timeBeginPeriodについて
Posted: 2014年3月22日(土) 07:41
by へにっくす
sql さんが書きました:追記:1つ前の自分の返信の
類似した過去のトピックのNO.12に提示されたコードでは、mainの中のwhileのループ前にtimebeginPeriod(1)が書かれていますが、・・・
私のSleepの前後という回答は撤回します。混乱させてすみませんでした。
理解してなかったのは私でした・・・m(__)m
リンク先のコードではtimeEndPeriodがないね。これじゃ確かに混乱するな。
まあでもsqlさんが確認のため投稿したと思われる
DxLib_Init関数によるミリ秒の精度
で管理人さんが回答をくれてますね。すでにやってるよ!!と
結局書く必要がないことが判明しましたね。
ただ今度からは、何のゲームを作ってるのかも書いといてくれるといいかな
(解決)した後のNo.4で背景を説明されても。
そうすれば、私ももう少し調べたと思う。いいわけですけど。(^^;
オフトピック
sql さんが書きました:精度が1ミリ秒になるのは本当なのでしょうか?
それはあなたが確かめてみればいいことだと思います。
media playerを起動している間、自分のプログラムがどのくらいの精度になっているかを取得すれば、わかることですよね?
本家の管理人さんがその方法を教えてくれてるんだし
Re: timeBeginPeriodについて
Posted: 2014年3月22日(土) 12:54
by sql
返信ありがとうございます。
へにっくす さんが書きました:ただ今度からは、何のゲームを作ってるのかも書いといてくれるといいかな
(解決)した後のNo.4で背景を説明されても。
そうすれば、私ももう少し調べたと思う。いいわけですけど。(^^;
そうですね。作っているゲーム(など)のジャンルを記しておけば、より回答しやすいですし。
書いてないことに気づいた時は時すでに遅し・・でした・・。
へにっくす さんが書きました:で管理人さんが回答をくれてますね。すでにやってるよ!!と
結局書く必要がないことが判明しましたね。
そうですね。
へにっくす さんが書きました:それはあなたが確かめてみればいいことだと思います。
media playerを起動している間、自分のプログラムがどのくらいの精度になっているかを取得すれば、わかることですよね?
本家の管理人さんがその方法を教えてくれてるんだし
そうですね。管理人(DXライブラリ)さんからの調べ方の回答がオフトピックを書き込む前だったらこんなこと聞かなかったと思います。調べ方を知った(教えてもらった)のはオフトピックで質問したずっと後でした・・・。
知りたいことも知れたので、改めて「解決」とさせていただきます。
Re: timeBeginPeriodについて
Posted: 2014年3月22日(土) 19:22
by ISLe
sqlさんの作ったプログラムでtimeBeginPeriodを使っていれば、他のプログラムにも影響します。
DXライブラリを使ったプログラムを起動すると、同時に動いているすべてのプログラムに影響します。
timeBeginPeriod(2)とやったらSleep(1)でも2ミリ秒戻ってこない、というものではありません。
timeBeginPeriodは最低限欲しい精度を設定するもので、それより高い精度で動作する可能性もあります。
Sleepは、最短で指定した時間に戻るもので、それより遅く戻る可能性もあります。
ちなみに設定可能な精度を調べることはできますが、現在の精度を調べることはできません。
他のプログラムが起動してtimeBeginPeriodを使えばそこで精度が変わりますから、常に変化する可能性があり調べても無駄です。
特に正確さを必要としないものでなければ上に書いたことを考慮していれば問題ないはずです。