mieki256's diary



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 の、るびま記事用サンプルで、この方法を使っているようでして。プログラム内で、
  • 元画像と同サイズの新規画像を作成。
  • 元画像の透明ではない部分を、全部白いドットに置き換える。
といった処理をしているように見えました。
#!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の日記

自分の手元でも、解説記事のソレを丸々コピペして動作確認してみました。
#!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
HLSLでフラッシュさせる方法

  • 画像枚数は、1枚で済む。持つべきテクスチャ領域を節約できる。
  • GPUに仕事をさせているので、おそらくは処理時間も速い(と思われる)。
  • Shader機能相当があるライブラリじゃないと使えない。
  • HLSL / GLSL の知識が必要になるので、Ruby の書き方しか知らない場合は、若干ハードルが高い。(コピペで済ませてる分には問題無し)

他にも色々ありそう。 :

とりあえず、ググってみて知った方法を並べてみましたが、他にも色々な方法があるのだろうなーと想像しております。まあ、今後も、研究課題ということで一つ…。

ベンチマークを取ってみたらどうなるのかなとも思いましたが、さて、こういうソレって、どうやったら測定できるんですかね…。そのあたりも、自分にとっては、今後の課題・宿題ですな。

とりあえず、画像とソースも置いときます。後半2つは、既存サンプルの引用に近い気もするのでアレですけど。

_enemyflush.zip

以上です。

過去ログ表示

Prev - 2013/12 - Next
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project