「裏画面処理ってなんだ?」と思う人もいるかもしれません。
ゲーム画面は普通、モニタに反映する映像を作る領域である表画面に直接書き込んだりしません。
PCのモニタは普通60Hz(1秒間に60回書き変わる)で動いていますが、映像を作る領域(フレームバッファ)に直接書き込んでしまうと、
60Hz以外のタイミングで書き込んでしまい、映像を作る途中でモニタに反映されてしまうかもしれません。
結果としてチラチラして見えたり未完成な映像が映ってしまいます。
そこで、裏画面と呼ばれる一時保存領域に、モニタに表示すべき完成した絵を作ってから、
表画面に一気に転送する手法を用います。これが「裏画面を使った表示」です。
いまいちピンとこないかもしれませんから、何故こんなことが必要なのかを知るために、まずは裏画面を使わずにモニタに表示してみましょう。
前の章のプログラムを使って画像を動かしながら表示してみます。
xという変数を用意し、常にx座標を変えながら描画してみましょう。(Sleepという関数は指定ミリ秒処理を止める関数です。7という値は適当です)
※画像は"キャラクタ00.png"から透過処理を施してある"キャラクタ01.png"に変更しています。画像については2章で詳しく説明します。
差分表示
#include "DxLib.h" int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){ ChangeWindowMode( TRUE ); // ウィンドウモードに設定 DxLib_Init(); // DXライブラリ初期化処理 int x = 50; int Handle; // 画像格納用ハンドル Handle = LoadGraph( "画像/キャラクタ01.png" ); // 画像のロード while( 1 ){ if( ProcessMessage() != 0 ){ // メッセージ処理 break;//ウィンドウの×ボタンが押されたらループを抜ける } DrawGraph( x, 100, Handle, TRUE ); //画像の描画 x = x + 2; // xを2増やす Sleep(7); // 7[ms]待機 } DxLib_End(); // DXライブラリ終了処理 return 0; }
実行結果
「なんじゃこりゃ!」
そりゃ前に描いたものを消さずに常にずらしながら描いたらこうなりますよね。
ゲーム画面は1フレームずつ、描画したら前に画面に描いたものを消してから、次のフレームの描画を行わなければなりません。
画面に描いた内容を消す関数は ClearDrawScreen関数 と言います。
この関数もただ呼ぶだけでいいので、特に関数の説明はしません。
ループの最初に ProcessMessage関数 と ClearDrawScreen関数 が必要なのだと覚えておいてください。
差分表示
#include "DxLib.h" int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){ ChangeWindowMode( TRUE ); // ウィンドウモードに設定 DxLib_Init(); // DXライブラリ初期化処理 int x = 50; int Handle; // 画像格納用ハンドル Handle = LoadGraph( "画像/キャラクタ01.png" ); // 画像のロード while( 1 ){ if( ProcessMessage() != 0 ){ // メッセージ処理 break;//ウィンドウの×ボタンが押されたらループを抜ける } ClearDrawScreen(); // 画面を消す DrawGraph( x, 100, Handle, TRUE ); //画像の描画 x = x + 2; // xを2増やす Sleep(7); // 7[ms]待機 } DxLib_End(); // DXライブラリ終了処理 return 0; }
実行結果
※ 黄色い矢印や文字は後から付け足したものです。実際には表示されません。
いかがでしょうか。環境によって見た目は異なりますが、ぎこちなく動いたり、チラチラしたりして見えたのではないかと思います。
※ 環境によっては全く表示されないこともあります。
これは先ほど言ったようにモニタが更新しているタイミング(1秒間に60回)と画像を描画しているタイミングが異なる為起こっています。
そこで、「裏画面に描画する」→「全ての描画が終わったら表画面へ反映する」という仕組み、すなわち「裏画面処理」が必要になるわけです。
次の章で裏画面処理をしてキャラクタを移動させてみましょう。
- Remical Soft -