■ 新・ゲーム開発講座




■ へっぽこプログラミング入門♪


■第24夜:画面切替えA(放射状タイプ)

カーテン式画面切替えが実現したところで、#g_change コマンドを拡張してみましょう。

■書式:#g_change type

背景画面からバックサーフェイスに画面内容を遅延込みで転送する。転送タイプは CURTAIN、SPREAD のシンボルで判別する。



カーテンタイプの他に放射状タイプを実装し、タイプ指定パラメータで切り替えようという次第です。とりあえず CURTAIN(カーテン)、SPREAD(広がる)のシンボル文字列で区別することにしましょう。ソースは
こちらを参照下さい。

■フラグ

main.cpp
_Mode_stat のメンバに変更はありません。

■コマンド解釈部

ここも変更はありません(コマンドが増えるわけではないので ^^)。

■撃つ

基本は同じですが、パラメータ解釈部分が加わります。エフェクトのタイプを格納する変数 g_change_type を用意して、読み込んだパラメータに応じた値をセットしています。また、不正なパラメータが渡された場合は強制終了(笑)するようにしてみました。


DWORD g_change_timer; //大麻・・・じゃなくてタイマ
DWORD g_change_wait = 20; //Wait値
int g_change_frame_counter; //フレームカウンタ
int g_change_type; //エフェクトタイプ

#define TYPE_CURTAIN 0
#define TYPE_SPREAD 1

int Com_g_change()
{

char str[256],msg_str[256];

//パラメータ解析
TEXT++;
strcpy( str, Kaiseki_TextStr() );

if( strcmp( str,"CURTAIN" )==0 ){
g_change_type = TYPE_CURTAIN;

}else if( strcmp( str,"SPREAD" )==0 ){
g_change_type = TYPE_SPREAD;

}else{
sprintf( msg_str,"シンボル [%s] は不正です。強制終了〜♪",str );
msg( msg_str,"Com_g_change_task()");
PostQuitMessage(0);

}

//テキスト表示を停止する
Mode_stat.flag_text = OFF;

//画面切替えのフラグを立てる
Mode_stat.flag_g_change = ON;

//フレームカウンタをゼロクリア
g_change_frame_counter = 0;

//タイマーショット
HLS_timer_start(&g_change_timer);

return 0;


}


■回す/締める

さて、タスク部分は2種類のエフェクトによって動作を切り替えなくてはなりません。まずは、タスク部分のエントリ関数 Com_g_change() は、処理の振り分けだけに専念してもらって、中身はサブ関数に分離しましょう。


int Com_g_change_task()
{
switch( g_change_type ) {
case TYPE_CURTAIN:
sub_Com_g_change_task_1(); //前回のカーテン式はこちらに分離♪
break;

case TYPE_SPREAD:
sub_Com_g_change_task_2();
break;
}

return 0;
}

サブ関数のうち、sub_Com_g_change_task_1() は前回のカーテン式タスクのそっくりコピーですので解説は省略します。今回は sub_Com_g_change_task_2() のほうで放射状切替えエフェクトを作ります。中身は以下のようなものです。

int sub_Com_g_change_task_2()
{
static int A[]={
34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34, //00 33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33, //01
32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, //02
31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, //03
30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30, //04
29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29, //05
28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28, //06
27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, //07
26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19,20,21,22,23,24,25, //08
25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19,20,21,22,23,24, //09
24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19,20,21,22,23, //10
23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19,20,21,22, //11
22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19,20,21, //12
21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19,20, //13
20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19, //14
19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18, //15
19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18, //16
20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19, //17
21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19,20, //18
22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19,20,21, //19
23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19,20,21,22, //20
24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19,20,21,22,23, //21
25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 6, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19,20,21,22,23,24, //22
26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 7, 8, 9,10,11,12,13,14,15,16,16,17,18,19,20,21,22,23,24,25, //23
27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, //24
28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28, //25
29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29, //26
30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30, //27
31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, //28
32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, //29
33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33, //30
34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34, //31
};

int x,y;

//タイマーチェック
if( HLS_timer_check( g_change_timer,g_change_wait )==false )return 0;

//タイマーショット
HLS_timer_start(&g_change_timer);

for( y=0;y<32;y++ ){
for( x=0;x<40;x++ ){
if( A[y*40+x] == g_change_frame_counter ){
StretchBlt( Back_DC,x*16+7,y*16+7, 2, 2,BG_DC,x*16+4,y*16+4,2,2,SRCCOPY);
}
if( A[y*40+x] == g_change_frame_counter-2 ){
StretchBlt( Back_DC,x*16+6,y*16+6, 4, 4,BG_DC,x*16+6,y*16+6,4,4,SRCCOPY);
}
if( A[y*40+x] == g_change_frame_counter-4 ){
StretchBlt( Back_DC,x*16+4,y*16+4, 6, 6,BG_DC,x*16+4,y*16+4,6,6,SRCCOPY);
}
if( A[y*40+x] == g_change_frame_counter-6 ){
StretchBlt( Back_DC,x*16+3,y*16+3, 8, 8,BG_DC,x*16+3,y*16+3,8,8,SRCCOPY);
}
if( A[y*40+x] == g_change_frame_counter-8 ){
StretchBlt( Back_DC,x*16+2,y*16+2,12,12,BG_DC,x*16+2,y*16+2,12,12,SRCCOPY);
}
if( A[y*40+x] == g_change_frame_counter-10 ){
StretchBlt( Back_DC,x*16 ,y*16 ,16,16,BG_DC,x*16,y*16,16,16,SRCCOPY);
}
}
}

if( g_change_frame_counter < 45 ){
g_change_frame_counter++;

}else{

//終了条件

//テキスト表示を再開する
Mode_stat.flag_text = ON;

//画面切替えのフラグをクリア
Mode_stat.flag_g_change = OFF;

//文字表示位置を初期化しておく
TEXT_X = TEXT_AREA.left;
TEXT_Y = TEXT_AREA.top;

}

return 0;

}



な、な、なんだこの巨大な配列は〜〜〜〜っ・・・と、驚いた方もいるかもしれませんが(笑)、これは640×480の画面を32×40のメッシュ状に分割したものです。中央から周囲にむかって 0,1,2,3・・・と数字が並んでいますが、実はフレームカウンタとこのマップを照合して、転送作業をおこなっているのです。原理が分かってしまえば 「な〜んだ」 ですが、この方式はメッシュ内の数値を変更するだけで様々なパターンに応用できます。

ちなみにこの関数では単純な BitBlt() ではなく StretchBlt() を用いて多少のお化粧をし、フレームナンバに多少の遅延要素を付け加えていたりもします。まあ、こんな方法もあるとゆーことで♪(^^)




次回は、縦/横ストレッチの予定です。