2013/12/12(木) [n年前の日記]
#5 [dxruby][game] DXRubyで敵キャラのフラッシュを試してみたり
今日もDXRubyを使って何か書いてみますよ。
昨日、「敵キャラ画像をフラッシュさせる方法がわからない…」みたいな結末で記事を書き終えたわけですけど。その後ググってみたら、色々やり方があるらしいと分かってきたので、そのあたりを自分なりにまとめてみることにしました。
昨日、「敵キャラ画像をフラッシュさせる方法がわからない…」みたいな結末で記事を書き終えたわけですけど。その後ググってみたら、色々やり方があるらしいと分かってきたので、そのあたりを自分なりにまとめてみることにしました。
◎ 同じ画像を加算合成で描画する方法。 :
最初に自分が思いついたのが、この方法。DXRuby は加算合成描画ができますので、敵キャラ画像をもう一度、加算合成で描画しちゃえば、少しは明るく見えるんじゃないのかなと。
メリット・デメリットは、以下になりますかね。
# 敵キャラ画像をフラッシュさせる。 # # 加算描画で、もう一枚上に重ねるやり方。 # 全てが完全に白にはならないけれど、一応光ってるようには見える。 require 'dxruby' Window.resize(320, 240) bgimg = Image.load("bg.png") img = Image.load("boss1.png") x, y = 64, 20 enemy_alpha = 0 Window.loop do break if Input.keyPush?(K_ESCAPE) # BG画像描画 Window.draw(0, 0, bgimg) # マウスボタンが押されたらフラッシュ開始 enemy_alpha = 255 if Input.mousePush?(M_LBUTTON) # 敵画像描画 Window.draw(x, y, img) if enemy_alpha > 0 # もう一枚加算描画 Window.drawEx(x, y, img, :alpha => enemy_alpha, :blend => :add) enemy_alpha -= 10 end end
メリット・デメリットは、以下になりますかね。
- 画像枚数は、1枚で済む。持つべきテクスチャ領域を節約できる。
- 加算合成描画が使えるハードウェア/ライブラリなら使える。
- 同じ画像を2枚描くので、非力なGPUでは描画時間がかかってしまって処理落ちするかもしれない。
- 白部分をたくさん含む画像なら光ってるように見えるけど、黒部分が多い画像では全然光ってるように見えない。(GIFアニメの、肩(?)の丸いところに注目。黒に近いので、全然光ってるように見えません。)
◎ あらかじめフラッシュした画像を作っておく方法。 :
事前に、フラッシュした画像を作っておいて、ソレを表示しちゃえば、そもそも容易にフラッシュ表示ができますな。プログラムで生成してもいいし、CGツールを使って事前に作業してもいいですが…。
DXRuby の、るびま記事用サンプルで、この方法を使っているようでして。プログラム内で、
DXRuby の、るびま記事用サンプルで、この方法を使っているようでして。プログラム内で、
- 元画像と同サイズの新規画像を作成。
- 元画像の透明ではない部分を、全部白いドットに置き換える。
#!ruby -Ks # -*- mode: ruby; encoding: sjis -*- # 敵キャラ画像をフラッシュさせる。 # # 事前に、フラッシュした画像を作成してしまうやり方。 # るびま記事のサンプルを参考にしました。 require 'dxruby' # フラッシュ画像を作成するメソッド def make_flush_image(img) w, h = img.width, img.height # 画像の縦横幅を取得 newimg = Image.new(w, h) # 新規画像を作成 # 縦横幅の値でループ h.times do |y| w.times do |x| # 透明度が128より大きかったら白にする newimg[x, y] = C_WHITE if img[x, y][0] > 128 end end return newimg # 生成画像を返す end Window.resize(320, 240) bgimg = Image.load("bg.png") img = Image.load("boss1.png") flushimg = make_flush_image(img) x, y = 64, 20 enemy_alpha = 0 Window.loop do break if Input.keyPush?(K_ESCAPE) # BG画像描画 Window.draw(0, 0, bgimg) # マウスボタンが押されたらフラッシュ開始 enemy_alpha = 255 if Input.mousePush?(M_LBUTTON) # 敵画像描画 if enemy_alpha <= 0 # 通常描画 Window.draw(x, y, img) else # フラッシュ画像を描画 Window.draw(x, y, flushimg) enemy_alpha -= 10 end end
- あらかじめCGツールでフラッシュ画像を作っておけば、凝った表示も可能になる。
- フラッシュ時に別画像を描画するだけなので、描画処理時間は通常時とほぼ同じで済む。
- 持つべき画像枚数が2倍になる。テクスチャ領域を圧迫してしまう。
- CGツール上で作業する時間が増える。絵描きさんに負担をかけてしまう。
- プログラムで生成する場合は、事前に画像生成するために、初期化処理の時間が増えてしまう。
◎ DXRubyのHLSL/Shader機能を使う方法。 :
DXRuby は、HLSL / Shader という、超極力な機能をサポートしてますので、ソレを使うのが DXRuby ライクな方法らしいです。
ググってみたら、そのものズバリの解説記事・サンプルを、DXRuby の作者様が公開してました…。ありがたや。
_DXRuby プロジェクトWiki - Shaderを使うためのチュートリアル02
_RGSSに近い色調整機能を持たせるSprite拡張 - mirichiの日記
自分の手元でも、解説記事のソレを丸々コピペして動作確認してみました。
ググってみたら、そのものズバリの解説記事・サンプルを、DXRuby の作者様が公開してました…。ありがたや。
_DXRuby プロジェクトWiki - Shaderを使うためのチュートリアル02
_RGSSに近い色調整機能を持たせるSprite拡張 - mirichiの日記
自分の手元でも、解説記事のソレを丸々コピペして動作確認してみました。
#!ruby -Ks # -*- mode: ruby; encoding: sjis -*- # 敵キャラ画像をフラッシュさせる。 # # HLSLを使用するやり方。 # 以下の解説記事を、ほぼ丸々コピペしてます… # # DXRuby プロジェクトWiki - Shaderを使うためのチュートリアル02 # http://dxruby.sourceforge.jp/cgi-bin/hiki.cgi?Shader%A4%F2%BB%C8%A4%A6%A4%BF%A4%E1%A4%CE%A5%C1%A5%E5%A1%BC%A5%C8%A5%EA%A5%A2%A5%EB02 require 'dxruby' # HLSLを文字列で持っておく hlsl = <<EOS texture tex0; sampler Samp0 = sampler_state { Texture =<tex0>; }; float4 PS(float2 input : TEXCOORD0) : COLOR0 { float4 output; output = tex2D( Samp0, input ); output.rgb = 1.0; return output; } technique { pass { PixelShader = compile ps_2_0 PS(); } } EOS # HLSLをSahderに渡す core = Shader::Core.new(hlsl) shader = Shader.new(core) Window.resize(320, 240) bgimg = Image.load("bg.png") img = Image.load("boss1.png") x, y = 64, 20 isFlush = 0 Window.loop do break if Input.keyPush?(K_ESCAPE) # BG画像描画 Window.draw(0, 0, bgimg) # マウスボタンが押されたらフラッシュ開始 isFlush = 255 if Input.mousePush?(M_LBUTTON) # 敵画像描画 if isFlush <= 0 # 通常描画 Window.draw(x, y, img) else # Shaderを使って描画 Window.drawShader(x, y, img, shader) isFlush -= 10 end end
- 画像枚数は、1枚で済む。持つべきテクスチャ領域を節約できる。
- GPUに仕事をさせているので、おそらくは処理時間も速い(と思われる)。
- Shader機能相当があるライブラリじゃないと使えない。
- HLSL / GLSL の知識が必要になるので、Ruby の書き方しか知らない場合は、若干ハードルが高い。(コピペで済ませてる分には問題無し)
◎ 他にも色々ありそう。 :
とりあえず、ググってみて知った方法を並べてみましたが、他にも色々な方法があるのだろうなーと想像しております。まあ、今後も、研究課題ということで一つ…。
ベンチマークを取ってみたらどうなるのかなとも思いましたが、さて、こういうソレって、どうやったら測定できるんですかね…。そのあたりも、自分にとっては、今後の課題・宿題ですな。
とりあえず、画像とソースも置いときます。後半2つは、既存サンプルの引用に近い気もするのでアレですけど。
_enemyflush.zip
ベンチマークを取ってみたらどうなるのかなとも思いましたが、さて、こういうソレって、どうやったら測定できるんですかね…。そのあたりも、自分にとっては、今後の課題・宿題ですな。
とりあえず、画像とソースも置いときます。後半2つは、既存サンプルの引用に近い気もするのでアレですけど。
_enemyflush.zip
[ ツッコむ ]
以上です。