サンプルコードのダウンロード
では、まずサンプルコードをダウンロードし、解凍してください。
私は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がありますが、これはもう説明するまでもありませんね。







