mieki256's diary



2014/01/27(月) [n年前の日記]

#1 [dxruby] タイトル画面をグネグネするアレを書いてみたり

DXRuby の Shader を使って、タイトル画面がグネグネするアレを書いてみたりして。

タイトル画面がグネグネするアレ

与えるパラメータの適切な値がよく分からなくて、オリジナルのソレとはどうも動きが違うのですけど…。それでもまあ、原理と言うか、仕組みとしては、こういう感じなのかなと。

_mbraster.rb
require 'dxruby'

#
# Shaderを使ってMETALBLACKのタイトル画面っぽい処理をするクラス
#
class MbRaster

  @@hlsl = <<EOS
  float ang;
  float lvl;
  float spd;
  float alpha;
  texture tex0;

  sampler Samp = sampler_state
  {
    Texture =<tex0>;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    MipFilter = LINEAR;
    AddressU = WRAP;
    AddressV = WRAP;
    // AddressV = BORDER;
  };

  struct PixelIn
  {
    float2 UV : TEXCOORD0;
  };
  struct PixelOut
  {
    float4 Color : COLOR0;
  };

  PixelOut PS1(PixelIn input)
  {
    PixelOut output;
    // input.UV.x = input.UV.x + sin(radians(input.UV.x * 360 * spd + ang)) * lvl * 0.25;
    input.UV.y = input.UV.y + sin(radians(input.UV.y * 360 * spd - ang)) * lvl;
    output.Color = tex2D( Samp, input.UV );
    output.Color.a *= alpha;
    return output;
  }

  technique MbRasScroll
  {
   pass P0
   {
    PixelShader = compile ps_2_0 PS1();
   }
  }
EOS

  attr_accessor :core, :shader, :image, :w, :h, :tilew, :tileh
  attr_accessor :rt, :rt_w, :rt_h, :rt_scaley

  #
  # 初期化処理
  #
  # @param [Image] image 使用する画像
  # @param [int] w 描画横幅。nilならウインドウ横幅
  # @param [int] h 描画縦幅。nilならウインドウ縦幅
  #
  def initialize(image, w=nil, h=nil)
    self.core = Shader::Core.new(@@hlsl,
                                 {:ang=>:float, :lvl=>:float,
                                   :spd=>:float, :alpha=>:float})
    self.shader = Shader.new(self.core, "MbRasScroll")

    @image = image
    @w = (w == nil)? Window.width : w
    @h = (h == nil)? Window.height : h

    # 画面を覆い隠すタイル数を求める
    @tilew = @w.quo(@image.width).ceil
    @tileh = @h.quo(@image.height).ceil

    # RenderTarget の必要サイズを求める
    @rt_w = @image.width * @tilew
    @rt_h = @image.height * @tileh

    # y方向で拡大縮小して描画縦横幅に合わせる
    @rt_scaley = @h.quo(@rt_h)

    # Rendertarget生成
    @rt = RenderTarget.new(@rt_w, @rt_h)
  end

  #
  # 描画処理
  #
  # @param [int] x 描画位置x
  # @param [int] y 描画位置y
  # @param [float] u 横方向スクロール位置
  # @param [float] v 縦方向スクロール位置
  # @param [float] ang sinの開始角度。単位は度
  # @param [float] lvl sinの振幅幅
  # @param [float] spd sinの角度変化量
  # @param [Hash] opts オプション
  # @option opts [int] z 描画奥行情報
  # @option opts [float] alpha 透明度。0.0で透明。1.0で不透明
  # @option opts [Object] blend 合成方法。:add や :alpha が使えるはず
  #
  def draw(x, y, u, v, ang, lvl, spd, opts={})
    alpha = (opts.has_key?(:alpha))? opts[:alpha] : 1.0
    blend = (opts.has_key?(:blend))? opts[:blend] : :alpha
    z = (opts.has_key?(:z))? opts[:z] : 0

    self.shader.ang = ang
    self.shader.lvl = lvl
    self.shader.spd = spd
    self.shader.alpha = alpha

    # Shader が参照する画像を RenderTarget に作成
    @rt.draw_tile(0, 0, [[0]], [@image], u, v, @tilew, @tileh).update

    # Shader を使って描画
    Window.drawEx(x, y, @rt, :shader=>self.shader,
                  :scaley=>@rt_scaley, :z=>z, :blend=>blend)
  end

  #
  # 動作確認用。グリッド画像を生成して返す
  #
  # @param [int] w 画像横幅
  # @param [int] h 画像縦幅
  # @return [Image] 生成した画像
  #
  def self.get_grid_image(w, h)
    image = Image.new(w, h, [0, 255, 0])
    image.box_fill(0, 0, w / 2 - 1, h / 2 - 1, [150,250,150])
    image.box_fill(w / 2, 0, w - 1, h / 2 - 1, [100,250,100])
    image.box_fill(0, h / 2, w / 2 - 1, h - 1, [200,250,200])
    image.box_fill(w / 2, h / 2, w - 1, h - 1, [0,220,0])
    return image
  end
end

# ----------------------------------------
# 以下は使用例

if __FILE__ == $0

  image = Image.load("logo.png")
  bg = MbRaster.new(image)

  x = 0
  y = 0
  u = 0
  v = 0
  ang = 360
  lvldef = 0.35
  lvl = lvldef
  spd = 1.0
  cnt = 0

  font = Font.new(14)

  Window.loop do
    break if Input.keyPush?(K_ESCAPE)

    # マウスカーソル座標でパラメータを変えてみる
    ang = Input.mousePosX * 360 / 640.0
    lvl = Input.mousePosY / 240.0  - 1.0
    # spd = Input.mousePosY / 480.0

    bg.draw(x, y, u, v, ang, lvl, spd)
    # u += 1
    # v += 2

    Window.drawFont(4, 4, "ang=#{ang} , lvl=#{lvl} , spd=#{spd}", font)
    Window.drawFont(4, 20, "Please move mouse cursor", font)
    cnt += 1
  end
end
テスト用の画像も置いときます。

_logo.png

スクリプト単体でも実行できるけど、他のスクリプトから呼び出して使うこともできるはず。

スクリプトも画像も、Public Domain / CC0 ってことで。

#2 [dxruby] DXRubyでSTGサンプルを作成

とりあえず、ゲームとしての全体の流れはできたような気がするので、一応公開。

ソースは、Ruby初心者が書いたソレだから、もうグチャグチャで全然参考にならないと思いますが、でもまあ、「DXRubyを使えばこういう感じのゲームも作れそうですよ」という一つの事例・サンプルにはなるかもしれない、と。

ScreenShot0

ScreenShot1

ScreenShot2

ScreenShot3

Windows、かつ、 _Ruby_DXRuby_tmxライブラリ がインストール済みの環境なら、解凍して、ruby main.rb で実行できる…はずです。

_stg_sample01.zip (ソースと画像一式。2.1MB)

Ruby等をインストールしてない環境でも動かせるように、exe化した版も置いときます。(※ 2014/02/02、ドキュメントも同梱)

_stg_sample01_exe_20140202.zip (実行形式。6.4MB)

解凍して、main.exe をダブルクリックすれば、実行できるかなと。一応、RubyをインストールしてないサブPC上でも、動作することは確認しました。

ソースも画像も、Public Domain / CC0 ということで。

ただ、exe版のほうは、tmxライブラリその他を含んでしまってるので、ライセンスはどうなるのか分かりません…。まあ、DLして動作確認する程度なら怒られないのでは、てな気もするのですけど。MITライセンス等のライブラリを実行形式に含む場合は、どういう条件を満たしておけばいいんだろう?

結局、サウンドはつけませんでした。手持ちの素材の中にソレっぽいデータが既にあれば鳴らしてたところなのだけど、どれもなんだかSTG向けのデータじゃなくて…。

画像とBGマップについて。 :

画像とBGマップは、 _OpenGameArt.org にもアップしておきました。ライセンスは CC0 にしておきましたので、自由に使ってください。マップデータの tmx ファイルも入ってますので、 _Tiled Map Editor を使って、マップや敵発生位置を変更・調整したら、そこそこ遊べるゲームになったり…するのかな。どうなんだろう。うーん。

_STG Object Image | OpenGameArt.org
_Side scroll STG BG tile map | OpenGameArt.org

所詮、プログラマーが作った画像なので、どれも正直、出来はイマイチですけど。それでもまあ、サンプルで何かのソースを書く際、テスト用画像としては一応使えるんじゃないのかなと。でも、やっぱり自機が、あまりにもダサイ…。モブ子さんを飛ばしておいた方が良かったのだろうか…?

DXRuby開発版について。 :

※ 2014/02/02追記。 _DXRuby プロジェクトWiki - ファイル置き場 で、過去のDXRuby開発版も公開していただけるようになってました。作者様、対応ありがとうございます。なので、以下は古い情報です。


手元の環境では、Ruby 1.9.3 + DXRuby 1.5.8dev で動かしてたのですけど。

今現在、DXRuby の Wiki から入手できる DXRuby開発版は、Ruby 2.0対応版のみなので…。念のため、自分がDLして手元に残してた、Ruby 1.9対応のDXRuby開発版を、Dropbox にも(勝手に)置いときます。コレ、何か問題があったら、言ってもらえれば消しときますので…。

_dxruby158dev-test-mswin32-ruby19.zip
_dxruby157dev-mswin32-ruby19.zip
_dxruby156dev-mswin32-ruby19.zip

1.5.8dev は .so ファイルしか入ってないので…。1.5.7dev 版もDL・解凍して、.so だけを 1.5.8dev のソレで上書きしてから、ruby install.rb すればインストールできた…ような気がするけど記憶が怪しいです。

ちなみに上記は、Ruby 1.9.x を使ってる場合の話で…。Ruby 2.0 環境なら、 _DXRuby プロジェクトWiki - ファイル置き場 から開発版が入手できますので、そちらを導入してみてもらえればと。

余談。DXRuby開発版って、バージョンによってはバグがあったりするものの、機能がかなり強化されてるので、できれば過去の版もどこかしらで公開しておいてくれると大変ありがたいのですけど。

ていうか、過去版が入手できないと、バグを見つけたとしても、どの版でエンバグしたのかエンドユーザレベルで検証作業ができないことに今頃気づいたりもして。…いや待て。もしかして、SourceForge のソースを眺めて云々、とかすればいいのだろうか。しかしソレ、ちょっとレベル高過ぎて、自分如きでは無理っぽい予感。

tmxライブラリについて。 :

tmxライブラリは、ネットに繋がってる環境で、
gem install tmx
をすれば導入できるはず、です。

2014/02/02追記。 :

コメント欄で、「MITライセンスのライブラリも含める場合は、ドキュメントのどこかに『○○ライブラリ使ってるよ』と書いてけば、まあ大体の場合はヨサゲ」と教えていただいたので、exe版にドキュメントを同梱して、そこに明記しておきました。たぶんこれで問題無い…はず。アドバイス、ありがとうございます。

2017/03/19追記。 :

Dorpboxのpublicフォルダが死んだのでファイルの置き場所を変更。

この記事へのツッコミ

Re: DXRubyでSTGサンプルを作成 by mirichi    2014/01/30 22:36
mirichiです。
tmxはMITライセンスですが、これを含む場合の条件については人によって色々な感じです。
例えばmrubyはMITライセンスで、使う場合にはライセンス表記も特にいらないという立場です。
DXRubyは元MITライセンスで、俺個人の解釈では文面からするとライセンス表記が必要なはずだということで、それが必要無いzlib/libpngライセンスに移行しました。http://ja.wikipedia.org/wiki/MIT_License
これの1に該当するという話ですね。
たぶん、MITライセンスを選択するような人はライセンス表記うんぬんで怒ることは無いと思います。tmxを含むバイナリを配布する場合は「tmx使ってまーす」って書いておけばよいぐらいじゃないでしょうか。

以上、1 日分です。

過去ログ表示

Prev - 2014/01 - 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