サンプルコードのダウンロード

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

記事検索

アーカイブ