ShimmerPlugin概要: 時間変化と共にレイヤー上の画像をゆがませるプラグイン。陽炎(かげろう)や 水のゆらめきを表現するために作成した。SSE2を使っているので、 Pentium4以上じゃないと動かない。そのCPUでSSE2が使えるかどうかは、 拙作SysInfo.dll使って判断するよろし。 使い方: scenario/Override.tjsを用意し、その中で、提供している layerExShimmer.dllを以下の一行で読み込み。 Plugins.link("layerExShimmer.dll"); で、scenario/first.ks の先頭あたりで、プラグイン本体を以下のように 呼び出す。 [call storage="ShimmerPlugin.ks"] ゲーム中で、baseの表画面を「マップファイル.png」に従って揺らがせる には、以下のように実行する。 [shimmer_init] [shimmer_start page=fore layer=base mapfile=マップファイル] ちょっとした概念: shimmerは、現在のKAGレイヤーにくっつく形で画面を揺らがせる。 揺らいでいる最中は、内部では元の画像を覚えて、割り込みごとに画面を 更新しているので、[image]タグなどでそのレイヤの画像を更新しても、 それはすぐに上書きされてしまう。[image]タグで画像を読む時は、 そのレイヤーのshimmerを[shimmer_stop]しておくこと。 [backlay]で裏画面のレイヤーにもコピーされる。このため、[backlay]して [trans]するなら、[backlay]直後に[shimmer_stop]しないと、shimmer しっぱなしのものがトランジションされてくる。狙ってるならいいけど。 タグリファレンス: [shimmer_init reset=] 説明: shimmerを初期化する。動作中だったshimmerは全て削除され、全レイヤーが ゆがまなくなる 引数: reset= shimmer実行中だったレイヤを停止した際に、そのレイヤの画像を 元に戻すかどうか。def=false [shimmer_start page= layer= ...] 説明: 指定したレイヤに新たにshimmerを追加し、開始する。開始直前に、 レイヤに表示されていた画像を内部的に保存し、タイマごとにそれをゆがめて 表示する。以前同じレイヤで実行されていたshimmerは削除される。 引数: page= ルールを登録するページを指定する。省略すると'fore'となる layer= ルールを登録するレイヤを指定する。省略すると'base'となる ※その他の引数は[shimmer_opts]と同一 [shimmer_stop page= layer= reset=] 説明: 指定したレイヤのshimmerを停止し、削除する。 引数: page= ルールを変更するページを指定する。省略すると全ページが対象に なる layer= ルールを変更するレイヤを指定する。省略すると全レイヤが対象に なる reset= 停止した際に、そのレイヤの画像を元に戻すかどうか。def=false [shimmer_opts page= layer= mapfile= mapvx= mapvy= map2file= map2vx= map2vy= maskfile= scalex= scaley= interval=] 説明: 動作中のshimmerの状態を動的に変更する。 引数: page= ルールを変更するページを指定する。省略すると全ページが対象に なる layer= ルールを変更するレイヤを指定する。省略すると全レイヤが対象に なる mapfile=ゆがみマップ画像を指定する。ゆがみマップ画像は白黒の上下左右 ループ画像であり、この白黒の隣り合うドット間の差異が、そのまま 画像のゆがみ具合となる。各ページ・レイヤに一度は指定必須 ある画像Sにマップ画像Mを適用した場合のゆがみ画像Pは、以下の 式で表される。 P(x,y) = S((x+輝度(x+1)-輝度(x-1))*scalex, (y+輝度(y+1)-輝度(y-1))*scaley) マップ画像のサイズは任意でよいが、描画原点はクリッピング ボックス左上となることに注意。 クリッピングボックスサイズはマップ画像の整数倍の大きさにする ことを薦める。さもなければ、マップ画像がループしていても一部 マップが不連続になる。 mapvx= マップ画像を線形移動させる早さ(X方向) def=0.0 mapvy= マップ画像を線形移動させる早さ(Y方向) def=0.0 map2file=二枚目のマップ画像(任意)。二枚までのマップ画像を合成して できる。def=指定なし map2vx= 二枚目のマップ画像を線形移動させる早さ(X方向) def=0.0 map2vy= 二枚目のマップ画像を線形移動させる早さ(Y方向) def=0.0 maskfile=マスク画像を指定する。マスク画像は白黒画像であり、マップ画像に よるゆがみの適用場所を指定する。白なら適用、黒なら非適用、 中間色は適用割合を表す。def=指定なし マスク画像のサイズはクリッピングボックスより大きくなければ ならない。描画原点はクリッピングボックス左上となることに注意 scalex= マップ画像に従い、X方向にどれだけゆがませるかを指定する def=1.0 scaley= マップ画像に従い、Y方向にどれだけゆがませるかを指定する def=1.0 interval=画面の更新間隔(ms, def=50)。50なら1000/50 = 20回更新/秒 clipx= クリッピングボックスの左上X座標を指定する。def=0 clipy= クリッピングボックスの左上Y座標を指定する。def=0 clipw= クリッピングボックスの横幅を指定する。def=0(対象レイヤ幅と同じ) cliph= クリッピングボックスの縦幅を指定する。def=0(対象レイヤ幅と同じ) 実現方法: layerExShimmer.dllにより、Layerクラスに以下の関数を追加しており、 これらを使って画像をゆがませている。 shimmerBuildMap(maplayer1, map1x, map1y, maplayer2, map2x, map2y) 現在のレイやに、二つのマップ画面を合成したマップを作成する shimmer(srclayer, maplayer, msklayer, scalex, scaley, clipx, clipy, clipw, cliph) srclayerにある画像を、maplayerとmsklayerに従って、scalex/y でゆがませつつ clipx/clipy/clipw/cliph 領域中に書き込む ソースコードは layerExShimmer_src/main.cpp を参照。コンパイル方法は その近所のHowToBuild.txt を参照。 現在、KThraedPool.hでは、スレッドの終了待ちを while(そのスレッドが動作中) Sleep(0); というアツい実装にしている(Sleep(0)の意味はMSDNのマニュアル参照)。 この方がスレッド数に応じた速度が出る(WaitForSingleObject()すると そこの反応が遅くなるので回避する)ため。そんかしCPU%をちょっと喰う ようになった。だからといって重くなったわけじゃないことに注意。 注意事項: ・クリッピングボックスは小さければ小さいほど処理速度が向上する ・マスク画像で0の部分、マップ画像で変化がない部分など、画像上  変更しなくて済む部分が多くても、(内部的には処理しているので、)  処理速度は向上しない。