litediary | ||||||||||||||||||||||||||||||||||||||||||||||||||
過去の記事
2015年04月
2015年01月
2014年09月
2014年07月
2014年02月
2013年12月
2013年01月
2012年12月
2012年11月
2012年07月
2012年06月
2012年05月
2012年04月
2012年03月
2012年02月
2012年01月
2011年12月
2011年11月
2011年10月
2011年08月
2011年07月
2011年06月
2011年05月
2011年04月
2011年03月
2011年01月
2010年12月
2010年11月
2010年10月
2010年09月
2010年08月
2010年07月
2010年06月
2010年04月
2010年03月
2010年02月
2010年01月
2009年12月
2009年11月
2009年10月
2009年09月
2009年08月
2009年07月
2009年06月
2009年05月
2009年04月
2009年03月
2009年02月
2009年01月
2008年12月
2008年11月
2008年10月
2008年09月
2008年08月
2008年07月
2008年06月
2008年05月
2008年04月
2008年03月
2008年02月
2008年01月
2007年12月
2007年11月
2007年10月
2007年09月
2007年08月
2007年07月
2007年06月
2007年05月
2007年04月
2007年03月
2007年02月
2006年12月
2006年11月
2006年10月
2006年09月
2006年08月
2006年07月
2006年06月
2006年05月
2006年04月
2006年03月
2006年02月
2006年01月
2005年12月
2005年11月
2005年10月
2005年09月
2005年08月
2005年07月
2005年06月
2005年05月
2005年04月
2005年03月
2005年02月
2005年01月
2004年12月
2004年11月
2004年10月
2004年09月
2004年08月
2004年07月
2004年06月
2004年05月
2004年04月
2004年03月
2004年02月
|
フレームレート08/02/01 02:55
モニタのフレームレート(リフレッシュレート)は家庭用TVでも何種類かある。 日本ではNTSCという規格がメインで、59.94Hzである。 海外ではPALも多く、これは50Hzである。 PCのモニタは50〜120Hzくらいは普通に設定できるものがある。 ゲーム(に限らず画面の動くもの)を作る場合、動きをスムーズにするために表示の更新をモニタのフレームレートにあわせる。 ところが、何も考えずに「→を押したら1フレームに1ドット右に動く」のような作り方をすると、60Hzの環境と120Hzの環境で2倍も速度が違ってしまうことになる。 (携帯ゲーム機のようなフレームレート固定の環境なら問題にはならないのだが。) そこで、この問題について考察する。 表示を更新する間隔をSYNC、画面の座標等を更新する間隔をLOOPと呼ぶとしよう。 SYNCは環境によって固定されていて、LOOPは好きに設定できる。 しかし、単純にSYNC=LOOPにすると上記の問題が起きる。 ところが、SYNC≠LOOPにすると、1SYNC中のLOOP数が一定でなくなり、一定速度で動いてるものが一瞬止まる/早く動くと言うことが起こり、カクカク動いて見える。 この問題を解決するために、単純に考えつくのは、SYNCに応じてLOOPでの処理を変えることだろう。 [実装1] while(1) { float time = GetLoopTime(); //前回の呼び出しからの経過時間を取得 GameLoop(time); Draw(); WaitVSync(); } GameLoop(time)では、timeに応じて移動距離などを調整する。 これだとSYNCによってパッドの反応速度等は変わってしまうが、そこまで気づく人はいないと思われる。(いない…よね?) 通常時はこれで問題はないだろうと思う。 多少の処理落ちも吸収できる副作用もある。 この実装において、リプレイを再生する場合を考えてみる。 リプレイデータは、乱数の種と各フレームのtimeとパッドの入力とする。 リプレイの再生は次のような処理になる。 float t_replay=0; float t_sync=0; int i=0; while(1) { float time = GetLoopTime(); //前回の呼び出しからの経過時間を取得 t_sync += time; while(t_replay<t_sync) { t_replay += replay[i].time; i++; if (i>=replay.len) { // リプレイ終了 } SetPad(replay[i].pad); GameLoop(replay[i].time); } Draw(); WaitVSync(); } timeとreplay[i].timeが完全に一致してれば1SYNCに1LOOPが再生され、スムーズに見える。 しかし一致しなかった場合、1SYNC中に2LOOP再生されたり1LOOPも再生されなかったりして、カクついて見えることが予想される。 そこで回避策として、表示より十分早い固定レートでGameLoopを実行することも考えてみた [実装2] float t = 0; while(1) { float time = GetLoopTime(); //前回の呼び出しからの経過時間を取得 t += time; while(t>LOOP_TIME) { t -= LOOP_TIME; GameLoop(LOOP_TIME); } Draw(); WaitVSync(); } ここでLOOP_TIMEをいくつにするか考察してみる。 家庭用TVゲームの場合は50/59.94/60Hzの何れかであると思ってよい。 これらの最小公倍数を取ってみると299700Hzとなり、明らかに非現実的である。 59.94はおおよそ60であるとして、50と60の最小公倍数の300Hzというのが現実的なところである。 しかし日本で一番多い59.94Hzについて妥協するのは得策とは思えない。 またCPU負荷の問題もある。 ■実験 59.94Hzのモニタを使用し、オブジェクトを等速運動させながら、(1/LOOP_TIME)を50, 60, 70, 120, 140, 300の6段階で変更してみた。 (70,140は50Hzのモニタで60,120を再生したときを想定) ・ 50:×ガクガク ・ 60:△スムーズだが時々カクっとなる ・ 70:×ガクガク ・120:△時々カクっとなるが、60よりは違和感は小さい ・140:×50や70よりはスムーズだがカクカクする ・300:○時々カクついているはずだが、ほとんど分からない。 という結果になった。 70,140でカクカクするということは、50Hzのモニタで60,120で再生したときにカクカクするということである。 この手法をとるなら300以上にするべきであろう。 以上。 ******************************************************************** 実装1ではあたり判定などの処理を適当にやると、処理落ちしたときに敵の弾をすり抜けるとかいうことが起きる。 実装2のLOOP_TIME=300はCPUパワーがかなりあやしい。 実装1で毎フレーム時間を計るのをやめて、起動時にフレームレート取得してtime固定にするかな? さて他のゲームはどうしてるんだろう… 動画は24fpsと30fps混合のときは最小公倍数の120fpsにするようだけど。 卒論/修論の季節ですね。 minibbs - テスト稼動中
creeper2012/05/03 01:28 .jpからもきてるんか…
creeper2012/05/02 10:52 誰も書き込まないのにSPAMばっかりくるようになったのでhost名制限かけました。 基本的に逆引きできて*.jpにならないと弾きます
wataru2010/12/01 11:43 GT5俺がかわりにやっといてあげますよ。
q2010/12/01 10:35 消化不良すぎ
2010/10/30 01:03 netbeansだとmakeファイル使う機会があるかもしれませんね
2010/10/05 06:04 なに書き込み不可能とか直しちゃってるのこわい
creeper2010/10/04 02:58 長いことコメント書き込み不可能になってた。直しました。
ao 2007/09/30 10:54 お、良いねぃ
creeper2007/09/16 05:18 そこまで詳しくなかったので調べてみた。Wikipedia万歳 なるほど、失敗する6号機まではかぐやと同じ3t強をSBB無しの202で上げてたんですね。 SRB-Aの出力を下げてSBB追加することでとりあえず対応していたと。 今後の予定をみると、次の燃えるのは2010年の金星探査機かー 「超高速インターネット衛星WINDS」は名前には惹かれるけど都心に引きこもってる限り関係ないなー Wikipediaの予定だとWINDSは2024になってますね。 重量的に、2024か204か新型か…
A責ダッシュ!2007/09/15 10:11 SSB使っての打ち上げって今回が最後じゃなかったかな? まー、今回のもSRB-Aがもともとの性能を出せてれば2022じゃなくて202で上げられたかもしれないです。LE-7Aの再生長ノズルはこなれてきたようなので、元のSRB-Aが復帰すればまたちょっとづつ色々変わっていくんじゃないのでしょうか。H-IIBも控えてますしね。
creeper2007/09/12 05:55 http://lovelove.rabi-en-rose.net/blog.php?n=256 今回はcygwinのgccつかってます。 まぁ、ソース見ての通りこの問題が1:1になるのは自明で、 かつrandの結果は偶数奇数が交互に出るようなこともなく、 おかしな偏りも無かったのでOKということで。 |