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
[ ツッコむ ]
以上です。