■ 新・ゲーム開発講座 |
■ へっぽこプログラミング入門♪ |
■第52夜:画面を揺らす LOAD/SAVEが一通りできるようになったところで、いよいよ本講座も終わりが近づいてきました。ここからは、講座の最終章「起動時メニュー」の前に、追加的な演出効果についていくつか解説しようと思います。今回は、比較的軽い内容として「画面を揺らす演出」を取り上げます。ソースはこちらです。 ■画面を揺らすには 画面を揺らすのはとても簡単です。バックサーフェイスから表画面に画像を転送する際、その座標を小刻みに変えてやるだけです(・ω・)ノ。最初は大きめに、そしてだんだん振幅を小さく…というタスク処理を行えば良い訳ですね。
■Mode_stat フラグ構造体 Mode_stat (main.h) にタスク制御用のフラグを追加します。フラグの値は揺れている=ON、処理中でない=OFF としましょう。ところで本稿のソースでは #define OFF 0 となっています。グローバル変数は自動的に初期値がゼロクリアされますので、 Mode_stat のメンバは明示的に初期化しなくても自動的に初期値=0、つまり OFF となります。 |
//プログラムの制御用FLAG構造体 struct _Mode_stat {
extern _Mode_stat Mode_stat; |
■コマンド解釈部 もう御馴染み?の TexitEngine.cpp の Command_call() です。コマンド文字列と実行部の関数名を追加します。 |
void Command_call() {
|
■Mainloop() では main.cpp の Mainloop() に細工をしましょう。この部分の動作については第13夜で解説しましたが、十分な速さのマシン上では Maonloop() はおよそ60fpsでシュッ、シュッ…と駆け抜けているはずです。駆け抜ける間に、フラグ構造体 Mode_stat のメンバを参照してそれぞれのタスク処理部分を呼んでゲームの処理を進めています。そして駆け抜ける最後の瞬間に BitBlt() でバックサーフェイス(裏画面)の内容をディスプレイに表示されている表画面に転送しています。 今回は、このバックサーフェイス → 表画面に転送する部分に小細工をします。まず、グローバル変数で G_OFFSET_X、G_OFFSET_Y というオフセット値を格納する変数をつくります。そして通常は (x,y)=(0,0)、つまり画面左肩を指定している BitBlt() の転送先座標をこの変数で置き換えてしまいます。これで、プログラムのどこかで G_OFFSET_X、G_OFFSET_Y を書き換えてやれば、その値ぶんだけズレた位置に画面が転送されるようになります。 |
//画面表示位置オフセット void Mainloop(void)
|
■コマンド実行部(撃つ) では、その G_OFFSET_X、G_OFFSET_Y を変更する部分を作りましょう(Text_Com_04.cpp)。まずはコマンドの起動部分です。グローバル変数でエフェクトのタイプを格納する shake_type (値は SHAKE_X,SHAKE_Y,SHAKE_XY)、タイマー変数 shake_timer、そしてカウンタの shake_counter を宣言します。 起動関数 Com_shake() では、 まずコマンドオプションの解析を行います。Kaiseki_TextStr() はテキストファイルから文字列を切り出す関数で TextEngine.cpp に記述してあるものを利用しています。この切り出した文字列から shake_type にそれぞれの値を設定します。 続いてフラグ設定を行います。まず揺れる効果が続いている間にテキスト表示が続いてしまうのを防ぐため Mode_stat.flag_text = OFF とします。続いて画面揺れ効果のフラグを立て、カウンタをクリアして最後に揺れの時間処理をするためにタイマーを撃ちます。 Mode_stat.flag_shake のフラグを立てたので、次回以降 Main_loop() からは揺れ効果のタスク処理部分がぐるぐると呼ばれるようになります。 |
int shake_type; DWORD shake_timer; int shake_counter; #define SHAKE_X 0 #define SHAKE_Y 1 #define SHAKE_XY 2 int Com_shake() {
|
■回す/締める ではコマンドのタスク部分=回す処理です。揺れ効果は3タイプ実装することになっていましたので、タイプ別に処理関数を分けて呼ぶようにしています。 |
void Com_shake_task() {
|
まずはX方向から参りましょうか。 そして、次が肝心なのですが、カウンタの値を参照しながら G_OFFSET_X の値をプラス、マイナスに交互に書き換えています。ここが「揺れ」の大きさを表します。ここではだんだん値を小さくしながら16段階にわたってオフセットを変化させ、最後の17段階目でオフセットを0に戻してフラグのクリアをしています(いわゆる「締め」の処理)。揺れフラグを OFF にしたことで、もう次のコマンド発行がなされるまで Main_loop() からタスクが呼ばれることはなく、コマンドは終了したことになります。そしてテキストフラグを ON にすることで、スクリプト解釈が再開します。非常にシンプルですね(^^) |
void Com_shake_task_X() {
|
続いてY方向ですが、これも操作するオフセットが G_OFFSET_Y になるだけで内容は一緒です。 |
void Com_shake_task_Y() {
|
続いてXYですが、これも G_OFFSET_X、G_OFFSET_Y を同時に書き換えているだけで内容はまったく一緒です。 |
void Com_shake_task_XY() {
|
#shake コマンドは、単独で使用しても良いですが、直前に「ドカッ」「バキッ」等の効果音のWAVを流しておくと効果が倍増?すると思います。ソースに付属のサンプルスクリプトでぜひ動作確認してみてください(・ω・)ノ |