サンプルコードのダウンロード
では、まずサンプルコードをダウンロードし、解凍してください。
私はVisual C++6.0でコンパイルしているので、お持ちの方はVisual C++でプロジェクトファイルを開いてください(「effec_02.dsw」をダブルクリックすれば開けます)。
圧縮ファイルに含まれる「effec_02.exe」をダブルクリックし、実行してみてください(何かキーを押すと終了します)。
どうでしょう?画面が切り替わり、うねうね揺れた地球の画像が3パターン表示されると思います。
というわけで今回は、サインカーブを使用して画像を揺らす方法ついて説明したいと思います。
三角関数は怖くない(謎
三角関数というと、なんだか難しく考える人もいるかもしれませんが、今回は別にムツカシー計算をするわけではありません。
右の図を見てください。
これはだいぶ いびつ ではありますが、サインカーブっぽいものです。
ここでまず覚えて欲しいのは、sin関数は「波形」という事と、最大値・最小値が+1・-1という事です。
それから前にも書きましたが、C言語の場合sin関数の引数の単位はラジアンなので、
360度=2π
1度=π/180
となります(今回はあんまり関係ありませんが)。
地球を歪ませる
さて、ここらでサンプルプログラムを見てみましょう。
今回は、画面中に3パターンの歪む地球を表示させています。
また、DirectDrawに関しては、「DirectDraw基礎 第10回」のサンプルコードを使用しています。
//----------[ メイン関数 ]---------------------------------------------------------------------- int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow){ 略 //パレット設定 LoadPalette("earth.bmp"); //ビットマップを作業用サーフェイスへ読み込む LoadBitmap(lpWork,"earth.bmp",60,15,200,210); int count=0,i; float width=0.f,width_max=50,width_add=0.15f; DWORD tim; while(1){ tim=timeGetTime(); //疑似タイマー処理 ClearScreen(lpBack); //バックバッファクリア count++; //カウンタ //ゆれの大きさを時間によって変化させる(各パターン共通) if(width_add>0){ if((width+=width_add)>width_max) width_add=-width_add; } else { if((width+=width_add)<0){ width=0; width_add=-width_add; } } //ゆらすパターン1 SetClipArea(0,0,320,240); for(i=0;i<240;i++) BltClip(lpBack,int(sin((count+i)/10.f)*width), i,320,1,lpWork,0,i,FALSE); //ゆらすパターン2 SetClipArea(320,0,320,240); for(i=0;i<320;i++) BltClip(lpBack,320+i,int(sin((count+i)/10.f)*width), 1,240,lpWork,i,0,FALSE); //ゆらすパターン3 SetClipArea(0,240,320,240); for(i=0;i<240;i++) BltClip(lpBack, ((i%2)?-1:1)*int(sin((count+i)/10.f)*width), 240+i,320,1,lpWork,0,i,FALSE); 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(秒間60回更新予定) } return(FALSE); }
順番に説明していきましょうか。
まずパレットを読み込み、地球の画像をlpWorkサーフェイスへ読み込んでおきます。
//パレット設定 LoadPalette("earth.bmp"); //ビットマップを作業用サーフェイスへ読み込む LoadBitmap(lpWork,"earth.bmp",60,15,200,210);
ここで、画像は320×240内の中央へ来るように、読み込んだ画像の転送先をずらしています(60,15)。
(解りやすくなると思ったので(^^;))
そんでもって今日の本題の部分
//ゆらすパターン1 SetClipArea(0,0,320,240); for(i=0;i<240;i++) BltClip(lpBack,int(sin((count+i)/10.f)*width),i,320,1,lpWork,0,i,FALSE);
1つ前の段落でサインカーブについて触れましたが、ここではサインカーブの図を90度右へ回転させたような感じで見ると直ぐに解ると思います(下図参照)。
ここでは画像を、ズバシュァァァ!!と薄く横に切り刻みまくり、それらを横にずらしながら置いていく感じです(謎)。
毎回countをインクリメントする事で、使用する波形の「開始位置」をずらす事が出来ます。
これにより、「動く」うねりを実現出来ます。また、・・・)/10.fと適当に割っていますが、大きな数字で割ると、波の間隔が広くなります。
まぁ、いろいろ変数をいじってみて、「どこを変えるとどうなる」というのを試してみてください(^^;説明するより、そうした方が早いです。
あと、パターン2・パターン3がありますが、これはもう説明するまでもありませんね。