ページ 11

キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 12:29
by Fimbul

上記のサイトでゼロナイトメア(赤いキャラ)がダメージを受ける時に白っぽく点滅しています。
具体的にどうやっているのでしょうか。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 12:41
by softya(ソフト屋)
描画は何を使っているのでしょうか?
DirectX、DXライブラリ、Win32API?

半透明加算が出来るなら加算するだけで出来ます。
マスク画像があるなら、マスク画像をOR合成する方法もあります。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 17:42
by ISLe
加算合成じゃなくて、アルファ合成(半透明合成)じゃないでしょうか。

エックスの溜めにも青色や緑色で同じ効果使ってますね。
ついでに、ダッシュ時の影にも使い回してます。

プレステはパレットインデックステクスチャが使えたはずなので、通常パターンをひと組と複数パレットの組み合わせで実装できますが、いまのパソコンでそっくり再現するとなるとちょいとめんどうです。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 18:12
by Fimbul
描写はDXライブラリを用いています。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 18:25
by softya(ソフト屋)
DrawGraph()で書いたキャラクタの上に、SetDrawBlendMode()で半透明加算(DX_BLENDMODE_ADD)に切り替えてもう一度同じキャラクタをDrawGraph()すれば白っぽくなるはずです(実験してませんが多分大丈夫)。SetDrawBright()で色を変えることも出来ます。SetDrawBlendMode()を戻すのを忘れないで下さいね。

[補足]動画に近いイメージにするにはISLeさんの手法が良いですが合成用マスク画像を用意しておく必要があります(全パターン分必要)。

あとGraphFilterと言うフィルターもあります。こっちはシェーダーモデル2.0を使うのでGPU性能にかなり依存します。
「DXライブラリ置き場 リファレンスページ」
http://homepage2.nifty.com/natupaji/DxL ... html#R3N26

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 18:42
by beatle
まったく未経験分野なので興味で便乗質問ですが、マスク画像を全キャラクタ分用意する代わりに、
正方形の画像を用意しておいて、キャラクタ画像の透過部分を正方形の画像に転写して
キャラクタと同じ形の画像を生成する、という手法は使えますか?

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 18:46
by softya(ソフト屋)
beatle さんが書きました:まったく未経験分野なので興味で便乗質問ですが、マスク画像を全キャラクタ分用意する代わりに、
正方形の画像を用意しておいて、キャラクタ画像の透過部分を正方形の画像に転写して
キャラクタと同じ形の画像を生成する、という手法は使えますか?
使えますがCPUで転写処理のコストはそれなりに必要なのでアセンブラ化の必要があるかも知れません。
透過部分だけ転写を行うことがGPUだけで出来ると速くなるとは思います。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 18:53
by softya(ソフト屋)
とりあえず別の手法としてZバッファを使った方法が出来たので貼っておきます。
DXLIBのリファレンス未掲載の関数であるZバッファ系を使っています。

コード:

#include "DxLib.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定

	int x = 0;
	int Handle; 	// 画像格納用ハンドル
	Handle = LoadGraph( "char.png" ); // 画像のロード

	// while( 裏画面を表画面に反映, メッセージ処理, 画面クリア )
	while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){

		// Zバッファを有効にする
		SetUseZBufferFlag( TRUE );

		//	画像の描画
		DrawGraph( x, 100, Handle, TRUE );

		// Zバッファをつかってに画像の形でマスクを刳り貫く
		DrawBoxToZBuffer( 0,0,640,480, 1,DX_ZWRITE_MASK ); //全画面を描画マスクする。
		DrawGraphToZBuffer( x, 100, Handle, DX_ZWRITE_CLEAR );//画像の形に切り抜く

		// 描画ブレンドモードをアルファブレンド(50%)にする
		SetDrawBlendMode( DX_BLENDMODE_ALPHA , 128 ) ;

		//	白いマスク画像
		DrawBox( x, 100, x+64, 100+64, GetColor(255,255,255), TRUE );//サイズは適当なので調整して下さい。

		// 描画ブレンドモードをノーブレンドにする
		SetDrawBlendMode( DX_BLENDMODE_NOBLEND , 0 ) ;

		// Zバッファを無効にする
		SetUseZBufferFlag( FALSE );

		x = x + 1; // xを増やす
	}

	DxLib_End(); // DXライブラリ終了処理
	return 0;
}

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 19:19
by ISLe
別の方法を思い出したので書いておきます。

コード:

#include "DxLib.h"
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int) {
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK);
	int x = 0;
	int Handle = LoadGraph("char.png");
	while (ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0) {
		SetDrawBright(255,  0,  0); // 赤っぽくなる
		SetDrawBlendMode(DX_BLENDMODE_INVSRC, 255);
		DrawGraph( x, 100, Handle, TRUE );
		SetDrawBlendMode(DX_BLENDMODE_ADD,    255);
		DrawGraph( x, 100, Handle, TRUE );
		SetDrawBright(255,255,255);
		SetDrawBlendMode( DX_BLENDMODE_ALPHA, 128);
		DrawGraph( x, 100, Handle, TRUE );
		SetDrawBlendMode( DX_BLENDMODE_NOBLEND , 0 ) ;
		x = x + 1;
	}
	DxLib_End();
	return 0;
}

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 19:21
by ISLe
beatle さんが書きました:まったく未経験分野なので興味で便乗質問ですが、マスク画像を全キャラクタ分用意する代わりに、
正方形の画像を用意しておいて、キャラクタ画像の透過部分を正方形の画像に転写して
キャラクタと同じ形の画像を生成する、という手法は使えますか?
動的にテクスチャを生成するということなら良くある手法です。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 19:22
by Fimbul
softya(ソフト屋) さんが書きました: DrawGraph()で書いたキャラクタの上に、SetDrawBlendMode()で半透明加算(DX_BLENDMODE_ADD)に切り替えてもう一度同じキャラクタをDrawGraph()すれば白っぽくなるはずです(実験してませんが多分大丈夫)。SetDrawBright()で色を変えることも出来ます。
私のやり方が悪いのか、この方法ではうまくできませんでした。
Zバッファの方法を試したいのですが、マスク、Zバッファとは何なのでしょうか。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 19:24
by Fimbul
ISLeさんの方法も試してみたいのですが、どういう処理をしているのでしょうか。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 19:37
by beatle
便乗質問なのにお答えいただきありがとうございました。
よくある手法ということで、理解しました。コストは確かに高そうですが、画像ファイル全てに対応するマスクを
最初に一気に生成して保持しておけば、そんなに気にするコストでもなさそうだな、と思いました。
ISLeさんの方法を脳内で解読しようとして挫折しました(笑)

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 19:37
by softya(ソフト屋)
Zバッファは本来3D描画の時に使うものでピクセル単位で奥行き情報を持つことで手前に位置するピクセルを描画したら奥のピクセルを描画しないって仕組みです。
マスクは昔からある用語で塗りたいところと塗りたくないところを作るって事ですね。マスクは塗り分けるための形そのもので、動作はマスキングと言ったほうが正しい気がします。クルマやフィギュアの塗装でも使う言葉です。

今回の場合は画像の有無を奥行き情報の代わりに使って画像の透明部分はDX_ZWRITE_MASKで画像の映像のある部分はDX_ZWRITE_CLEARにしています。DX_ZWRITE_MASKの所は何を書いても描画されなくなり、DX_ZWRITE_CLEARのところだけに描画できます。形を無視して四角形に書いても画像の形にくり抜かれるってことです。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 21:36
by Fimbul
softyaさんありがとうございます。
Zバッファの本来の使い方ではないが、マスクとして使えると言う事でしょうか。
試してみました所、綺麗に光らす事が出来ました。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月06日(火) 23:22
by ISLe
DX_BLENDMODE_INVSRC→DX_BLENDMODE_ADD
でマスク画像一色で塗り潰した状態になります。
そこにDX_BLENDMODE_ALPHAで元画像を合成します。

元画像に色を重ねるのではなく、色に元画像を重ねているわけです。
14行目をコメントアウトして動かしてみたら7~11行目のコードで何が起きているか分かりますよ。

同じ画像を何回も描画して重そうに見えますけどZバッファやマスクを使うより軽いのではないかと思います。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月07日(水) 22:15
by Fimbul
白っぽくするには輝度を変更しなければいいんですよね。
試してみたら白っぽくなったのですが、反転した後に加算ブレンドするとなぜ白くなるのでしょうか。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月07日(水) 22:40
by ISLe
あるピクセルのRGB要素がそれぞれr,g,bとします。
反転すると255-r,255-g,255-bです。
元の要素を加算すると、(255-r)+r,(255-g)+g,(255-b)+b。
r,g,bはプラマイゼロで、255,255,255が残ります。

輝度を設定しておけばその色になります。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月07日(水) 22:55
by naohiro19
ゲームプログラミングの館においてあるプロジェクトを利用する場合は

コード:

int Handle = LoadGraph("char.png");

コード:

int Handle = LoadGraph("画像/char.png");
に置き換える必要があります。

Re: キャラがダメージを受けた時の点滅について

Posted: 2011年12月08日(木) 21:36
by Fimbul
ISLeさんありがとうございます。
納得です。

返信して下さった方、ありがとうございました。