サンプルコードのダウンロード
では、まずサンプルコードをダウンロードし、解凍してください。
私はVisual C++6.0でコンパイルしているので、お持ちの方はVisual C++でプロジェクトファイルを開いてください(「effec_08.dsw」をダブルクリックすれば開けます)。
圧縮ファイルに含まれる「effec_08.exe」をダブルクリックし、実行してみてください(何かキーを押すと終了します)。
どうでしょう?画面が切り替わり、Takabo Softの文字が徐々にデロ~ンと熔けて(?)いくと思います。
というわけで、今回は画像を溶かすような処理について説明していきたいと思います。
早速サンプルコードの解説
というわけで、今回も順番に説明していきまーす。
//----------[ メイン関数 ]---------------------------------------------------------------------- int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow){ 略 //DirectDraw開始 StartDirectDraw(hw); //パレット設定 LoadPalette("takabo.bmp"); //ビットマップを作業用サーフェイスへ読み込む LoadBitmap(lpWork,"takabo.bmp",0,0,548,90);//46,195
んで、まずメインループ内で使用するデータを初期化します。
int i; //画像の高さが90だから90個分用意する float dy[90],dy_add[90]; int dy_count[90]; //準備 for(i=0;i<90;i++){ dy[i]=i+195.f; //画面中央にくるように補正しておく dy_add[i]=0.f; dy_count[i]=(89-i)*3+60*2; }
今回は、画像の横一列(548 x 1)につき1つのデータを作成し、高さが90あるので、90個分のデータを
作成します。「dy」はy座標、「dy_add」は(y座標の)毎ループ毎の増加量、「dy_count」は
処理を開始するまでの残りカウントです。
int y; DWORD tim; while(1){ tim=timeGetTime(); //疑似タイマー処理 ClearScreen(lpBack); //バックバッファクリア //座標更新 for(i=0;i<<90;i++){ if(dy_count[i]==0){ dy_add[i]+=0.02f; //加速 dy[i]+=dy_add[i]; } else dy_count[i]--; }
ここ(↑)でまずデータの座標を更新します。
dy_addに適当な定数を加えていくことで「重力」っぽい処理が再現できます。
(ゲーム制作基礎でもやりましたね)
//表示 for(i=0;i<90;i++){ //一番下の画像は普通に表示 if(i==89){ y=(int)dy[i]; if(y<480) Blt(lpBack,46,y,548,1,lpWork,0,i,FALSE); } //それ以外は、一つ下の画像の座標まで補間(謎 else { for(y=(int)dy[i];y<(int)dy[i+1];y++) if(y<480) Blt(lpBack,46,y,548,1,lpWork,0,i,FALSE); } }
データの座標を更新し終えたら次は表示です。
そのまま「dy」の示す座標に画像を貼り付けていくと、「穴」が空きます。
ですから、その穴を埋めるようにfor文とかで間を補ってやります。
Flip(); //フリッピング do{ //メッセージループ while(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)){ if(!GetMessage(&msg,NULL,0,0)) Quit(); TranslateMessage(&msg); DispatchMessage(&msg); } }while(timeGetTime()<tim+16); //1000/60=16.666(60FPS) } return(FALSE); }
前回に比べれば簡単ですね(^^;
あんまり「熔ける」という感じでは無いですが(爆
これを更に1ドットずつに区切って処理すればもっと本物っぽくなるかなぁ?