#include "DxLib.h"
// WinMain関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
int x , y ;
// DXライブラリ初期化処理
if( DxLib_Init() == -1 ) return -1;
// 描画先画面を裏画面にする
SetDrawScreen( DX_SCREEN_BACK ) ;
x = 0 ; y = 0 ;
while( 1 )
{
// 画面に描かれているものをすべて消す
ClearDrawScreen() ;
// 上下左右のキー入力に対応して x, y の座標値を変更する
if( CheckHitKey( KEY_INPUT_LEFT ) == 1 ) x -= 8 ;
if( CheckHitKey( KEY_INPUT_RIGHT ) == 1 ) x += 8 ;
if( CheckHitKey( KEY_INPUT_UP ) == 1 ) y -= 8 ;
if( CheckHitKey( KEY_INPUT_DOWN ) == 1 ) y += 8 ;
// x , y が示す画面座標にBMP画像 test1.bmp を描画する
LoadGraphScreen( x , y , "test1.bmp" , TRUE ) ;
// 裏画面の内容を表画面に反映させる
ScreenFlip() ;
// 待たないと処理が早すぎるのでここで20ミリ秒待つ
WaitTimer( 20 ) ;
// Windows システムからくる情報を処理する
if( ProcessMessage() == -1 ) break ;
// ESCキーが押されたらループから抜ける
if( CheckHitKey( KEY_INPUT_ESCAPE ) == 1 ) break ;
}
// DXライブラリ使用の終了処理
DxLib_End() ;
// ソフトの終了
return 0 ;
}
<実行例>
実行画面は全く変わらないので以前のを流用します。(^^;
このプログラムを実行するとキーボードの方法キーで自在にグラフィックを操作する事が出来ると
思います。
では早速このプログラムの解説に入ります。
色違いの最初、x = 0 ; y = 0 ; ですが、お気付きかと思いますが、この x と y という変数は
は LoadGraphScreen 関数で絵を表示する時の座標指定に使われているところからわかるように、ずばり
『絵を表示する位置』を示す変数です。
変数 x の値が増えれば増えるほど絵は右のほうに表示され、変数 y の値が減れば減るほど絵は上の
方に表示されるという仕組みです。そうです、この2つの変数の値を変更する事によって絵を表示する
位置を操作できると言うわけです。この仕組みから見てわかるように、2Dゲームでキャラクターの
存在位置はこのように x と y の2つの変数を使って記憶しておくのが一般的です。
なお見ての通り、最初は x と y に0を代入して、絵は画面左上に表示されるようにしています。
次に while( 1 ) を説明したいと思います。これは条件無しで無限ループをする事を
示しています。
なぜ while( 1 ) で無限ループになるのか?ちょっと道をそれて説明します。
while 文は () 内の条件演算式が真であれば、つまり成立すればループを続け、偽であれば、つまり
成立していなければループから抜ける、という仕組みである事は皆さんご存知かと思います。
ですが while 文では実は条件式が成立しているかいないかなどは特に気にしていません。実際の
ところは while 文の () 内の演算結果が0以外だったらループを続け、0だったらループから抜ける
という単純な処理しかしていません。
じゃあ一体 () 内で行われている条件式は一体なんなんだ、と思われるかと思います。
ではここで一つ問題、次の式で変数 b には一体なんの値が代入されるでしょうか。
b = 100 > 10 ;
答えは1、では次の式では b に何の値が代入されるでしょうか。
b = 10 != 10 ;
答えは0、おわかりいただけたでしょうか? とどのつまり条件演算子である == や > や <= や != 等は
すべて条件が成立すれば演算の結果として1が、成立しなければ0が演算の結果となるようになっているの
です。ですから while 文では演算結果が真であったか偽であったかは計算式などは見なくても、結果が
0か0以外かで判断すれば事は足りてしまうのです。( 実は if 文や for 文のループ条件部も同じ仕組みです )
そして while で無限ループをしたいときはこの単純な仕組みを逆手に取ります。
用は while の () 内の演算結果が0以外ならばループは続行されるので、while( 1 ) とすれば演算結果は
常に0以外(演算はしていませんが…)になるので、半永久的にそのループは繰り返される事になるのです。
以上、無限ループの仕組みでした。
さて次になぜその無限ループを行う必要があるかをお話します。
前々回、絵を動いているようにみせるには『少しずらして表示、少しずらして表示を繰り返す』といいました。
ですから for 文で『少しずらして表示』を繰り返したわけですが、今回は別に『少し動かして表示』の回数を
制限する必要はありません。ですので無限ループとなっているのです。
次に今回の本題のキー入力部分です。
といってもたいしたことはしていません。要は『→』キーを押していたら絵が右に、『↓』キーを押していたら
絵が下に動けば良いわけです。先程説明した通り、今回、絵を表示する座標は x と y という変数を使って操作
しているので『→』を押していたら x の値を少し増やしてやり、『↓』を押していたら y の値を少し増やして
やればいいのです。
押しているかどうかを判断するには CheckHitKey 関数に押しているか調べたいキーのマクロを渡して、関数
から返ってくる値を調べれば言いので結果的に
例 『→』キーを押してたら変数 x に8の値を加算する
if( CheckHitKey( KEY_INPUT_RIGHT ) == 1 ) x += 8 ;
と言うような記述になるのです。プログラムにはこのような記述が4行あるのは上下左右すべての方向キーをチェックするからです。
最後に if( ProcessMessage() == -1 ) break ; と if( CheckHitKey( KEY_INPUT_ESCAPE ) == 1 ) break ; です。
if( CheckHitKey( KEY_INPUT_ESCAPE ) == 1 ) break ; は見ての通りエスケープキーが押されていたら break 文で
while ループを抜ける事を示しています。これは問題ないと思います。
それはさておき if( ProcessMessage() == -1 ) break ; の ProcessMessage ってなに!?と思われた事と思います。
この関数はDXライブラリが Windows というマルチタスクOS上で動作するために必要不可欠な関数です。
要は本来 Windows というOSは沢山のソフトが一度に動作し、それぞれのソフトは協調して Windows上 に存在する
ために Windows のシステムから色々な指令や情報が各ソフトに送られてきます。(『マウスが移動した』『ウインドウを
閉じなさい』など)一般的な Windows ソフトはその指令や情報によって動作を分岐・決定し、処理をします。
つまり Windows では各ソフトはシステムから送られてくる指令や情報を常に監視し、それらの情報が届いたら直ちに
送られてきた指令・情報を処理しなくてはならないのです。
ですがDXライブラリではそんな面倒くさく、ゲームには全く関係ない作業はDXライブラリ内でどうにかしてしまおうと思い、
それらの情報を勝手に処理する関数を用意しました。それが ProcessMessage という関数なのです。
ProcessMessage 関数はなんの引数も取らず、ただただ実行するだけです、後は勝手に Windows システムから送られ
てくる情報を処理してくれます。そして処理が終ると返ってきます。
注意しなくてはならないのは、ProcessMessage 関数の戻り値です。正常に情報処理が終了した場合は 0 が返って
きますが、情報処理に異常が発生した場合は -1 が返ってきます。この場合はなるべく早くソフトを終了しなくては
なりません。
さてこのプログラムではどうしているかと言うと。
if( ProcessMessage() == -1 ) break ;
つまり ProcessMessage 関数で異常が起きたら while の無限ループから脱出するようにしています。
ところで本来常に監視しておかなければならない Windows システムからの指令・情報ですが、実際にはそんなにずっと
監視している必要はありません。ですから今までは ProcessMessage 関数は使わなかったのです。
ですが今回のように、手を加えなければ永遠にループし続けるようなプログラムの場合は、ループのどこかに ProcessMessage 関数を
一つ入れるくらいはする必要があります。これは重要な事ですので覚えておいてください。
長々と書いてしまいましたが、今回はこの辺で終りです。
次は絵の表示速度を劇的に速くする方法を紹介したいと思います。
なお前回の最後に、『ジョイパッドとキーボードで操作出来るように』と言っていましたが、ジョイパッドで
操作できるようにするのは別の機会にしたいと思います。
戻る