RPGツクールVXAceの網

RPGツクールVXAceの製作過程で気が付いたことをメモする。

動作環境と解像度(2)画面更新タイミング

検証をすすめるうちに、Graphics.updateの詳細が明らかになってきた。

Graphics.updateの機能は、ヘルプによると

ゲーム画面を更新し、時間を 1 フレーム進めます。このメソッドは必ず定期的に呼び出す必要があります。

だが、より詳細に書くと

メモリ上のバックバッファ描画データ(多分ビットマップ)をゲームウィンドウに描画し、フレームレート調整のための更新タイミング時刻に到達するまでウェイトを行う。Graphics.frame_count は1増やされる。

という感じになる。たとえば、Graphics.frame_rateが60(デフォルト)の場合、1フレームの更新にかかる時間は約16.66msになる。このとき、たとえばGraphics.update以外の処理に10msかかってからGraphics.updateが呼ばれたとすると、Graphics.updateは約6.6msのウェイトを行う(内部的には1ms刻みでコントロールしているようだ。16.666を刻みたい場合、16,17,17,16,17,17とすれば平均16.666になる)。Graphics.update自体に16.66ms以上かかると本末転倒だが、おそらく画面をウィンドウに描画するという処理はCPUの能力にもよるがそこまで長い時間はかからないという想定だろう。

こうして1フレーム内に軽い処理が入った場合でも重い処理が入った場合でも、極力固定のタイミングで画面とframe_countを更新することで、正確なゲーム時間と適切なCPU使用率を保っているようである。

そういう理由から、たとえばGraphics.frame_rate = 120 にすると、ゲームのエフェクトや入力検出全てが60FPSのときに対して倍速になるため、敵の行動が早すぎて表示が読み切れなかったり、下のコマンドに行こうとして下を押しっぱなしにすると想定以上に大きく下に移動してしまったりする。60FPSからの変更が推奨されないというのはこのようなズレを意図してのことと思われる。ちなみに「画面のちらつきをおさえる」をチェックしている場合は、画面更新は60FPS(ディスプレイのリフレッシュレート)に合うが、内部計算はGraphics.frame_rate の頻度で実施される。

ところで、Graphics.update以外の処理(計算とかバックバッファへの描画とか)が16.666ms以上かかってしまった場合、画面は更新されず次のフレームの処理が先に実施される。俗にフレームスキップと呼ばれる現象で、画面のスムーズさを犠牲にして内部計算を遅らせないようにする機能である。

例えば、Graphics.updateのあとにsleep 0.020(20ms)を入れると画面が一切更新されなくなるのか、といえばそうではない。5~10FPSくらいは出ているので、ゲームを認識できるレベルでの更新は行うようである。

次回は、解像度とフレームスキップが起こる処理負荷の関係について調べる。