2013/09/22(日) [n年前の日記]
#1 [ruby] Rubyにもtmxファイルを読み込むライブラリがあるらしい
マップエディタ
_Tiled Map Editor
の保存ファイル ―― tmxファイルを読み込んで解析するライブラリが Ruby にもあるらしいと知ったので、ちょっと試してみたり。環境は、Windows7 x64 + ruby 1.9.3p429 mingw32 版。
_tmx | RubyGems.org | your community gem host
_shawn42/tmx - GitHub
ライセンスは、MIT License の模様。
とりあえず、gem install tmx でインストールできた。 _nokogiri と _oj というライブラリも必要らしくて、一緒にインストールされる。
下のような感じで使えるみたい。勘で試したので自信無いけど。
分かった範囲で注意点が2つほど。
_dxruby_and_tmx_20130922.zip
最初、Window.drawTile() の sizex,sizey に、100,100 とか入れちゃって、めちゃくちゃ処理が重くなってしまった。画面サイズ程度を指定しないといかんのですな…。
Flixel に比べると、DXRuby は _カメラ が無い分、スクロール処理が面倒臭い印象も。
_tmx | RubyGems.org | your community gem host
_shawn42/tmx - GitHub
ライセンスは、MIT License の模様。
とりあえず、gem install tmx でインストールできた。 _nokogiri と _oj というライブラリも必要らしくて、一緒にインストールされる。
下のような感じで使えるみたい。勘で試したので自信無いけど。
#!ruby -Ks # Tmxライブラリを利用して、Tmxを読み込んでみるサンプル require 'tmx' tmx = Tmx.load("./assets/maps/mylevel1.tmx") # マップサイズ(縦横のタイル個数)を取得 puts "map size : #{tmx.width} x #{tmx.height}" # タイル1つの縦横サイズを取得 puts "tile size : #{tmx.tilewidth} x #{tmx.tileheight}" # レイヤー枚数を取得 puts "layers length : #{tmx.layers.length}" # 全レイヤー(タイルレイヤー)の情報にアクセス tmx.layers.each do |layer| name = layer.name # レイヤー名 w = layer.width # レイヤーサイズ h = layer.height ltype = layer.type # レイヤー種類 data = layer.data # レイヤーのマップテーブル puts "name = #{name} , #{w} x #{h} , type : #{ltype} , Data length : #{data.length}" end # オブジェクトレイヤーの情報にアクセス tmx.object_groups.each do |objg| puts "object layer name : #{objg.name}" objg.objects.each do |o| name = o.name x = o.x y = o.y puts "#{name} , (#{x},#{y})" end end先日作った tmx で試したら、以下の情報が得られた。これなら使えそう。
map size : 100 x 100 tile size : 32 x 32 layers length : 4 name = layer4 , 100 x 100 , type : tilelayer , Data length : 10000 name = layer3 , 100 x 100 , type : tilelayer , Data length : 10000 name = layer2 , 100 x 100 , type : tilelayer , Data length : 10000 name = layer1 , 100 x 100 , type : tilelayer , Data length : 10000 object layer name : objlayer ruby , (1281,160) ruby , (32,192) ruby , (33,351) (中略) ruby , (3135,1087) ruby , (2601,127) banana , (2592,1056) banana , (2160,2428) banana , (269,256) door , (3093,3136) playerborn , (161,119)
分かった範囲で注意点が2つほど。
- Tiled は、タイル番号0番が空白、タイル番号1番がタイルの一番左上のタイルなので、そのままではえてして使えない。フツー、その手の2Dゲーム用ライブラリは、一番左上のタイルを0番として扱うので、番号が1つずれちゃう。番号をずらしたデータを作り直す等の工夫が必要。
- このライブラリは、オブジェクトレイヤー上にタイルを置いていてもポリゴンデータとして変換してしまうようで、gid ―― タイル番号は得られない。各オブジェクトにつけた名前で種類を判断する等の工夫が必要。
◎ DXRubyで表示してみた。 :
#!ruby -Ks # Tmxファイルを読み込んでDXRubyで描画するサンプル require 'dxruby' require 'tmx' # BGマップデータ(二次元配列)を取得 def get_map_data(tmx, layer_name) mapw = tmx.width maph = tmx.height mapdata = [] i = 0 tmx.layers.each do |layer| next if layer.name != layer_name maph.times do |my| lines = [] mapw.times do |mx| n = layer.data[i] lines.push((n <= 0)? 0 : n - 1) i += 1 end mapdata.push(lines) end return mapdata end end tmx = Tmx.load("mylevel1.tmx") # tmxファイルを読み込み・解析 # マップ用画像(32x32,256x768)とオブジェクト用画像(24x24,192x96)を読み込み imgarr = Image.loadTiles("mylevel1_tiles.png", 256/32, 768/32) objimgs = Image.loadTiles("item_mix_all.png", 192/24, 96/24) # BGマップデータ(二次元配列)を取得 layers = [] layers.push(get_map_data(tmx, "layer4")) layers.push(get_map_data(tmx, "layer3")) layers.push(get_map_data(tmx, "layer2")) # layers.push(get_map_data(tmx, "layer1")) # アタリ判定用 # BGマップのスクロール最大値を取得 bgxmax = tmx.tilewidth * tmx.width - 640 bgymax = tmx.tileheight * tmx.height - 480 # 画面縦横幅がタイル何個分かを取得 bgtw = 640 / tmx.tilewidth bgth = 480 / tmx.tileheight # オブジェクトレイヤー情報を取得 sprs = [] tmx.object_groups[0].objects.each do |obj| x = obj.x + 16 - 12 # 配置したタイルの左下座標が得られる。左上座標ではない。 y = obj.y - 16 - 12 case obj.name when "ruby" sprs.push(Sprite.new(x, y, objimgs[6])) when "banana" sprs.push(Sprite.new(x, y, objimgs[8])) when "playerborn" sprs.push(Sprite.new(x, y, objimgs[16])) when "door" sprs.push(Sprite.new(x, y, objimgs[24])) end end bx, by = 0, 0 font = Font.new(26) framecount = 0 # メインループ Window.loop do break if Input.keyPush?(K_ESCAPE) # キー入力でスクロール old_bx = bx old_by = by spd = 8 bx -= spd if Input.keyDown?(K_LEFT) bx += spd if Input.keyDown?(K_RIGHT) by -= spd if Input.keyDown?(K_UP) by += spd if Input.keyDown?(K_DOWN) bx = 0 if bx < 0 by = 0 if by < 0 bx = bgxmax if bx > bgxmax by = bgymax if by > bgymax # スクロール移動量を記録しておく bx_diff = bx - old_bx by_diff = by - old_by # BGマップを描画 bgspd = [0.25, 0.5, 1.0, 1.0] # 各BGレイヤーのスクロール速度 layers.each_with_index do |dt, i| bgx = bx * bgspd[i] bgy = by * bgspd[i] Window.drawTile(0, 0, dt, imgarr, bgx, bgy, bgtw, bgth) end # オブジェクト座標をスクロール移動量で変更 sprs.each do |spr| spr.x -= bx_diff spr.y -= by_diff end # オブジェクトを描画 Sprite.draw(sprs) if (framecount & 0x04 == 0) # メッセージ描画 Window.drawFont(4, 4, "←→↑↓でスクロール", font) framecount += 1 endこんな感じに。 一応画像も含めて置いときます。Public domain ってことで。
_dxruby_and_tmx_20130922.zip
最初、Window.drawTile() の sizex,sizey に、100,100 とか入れちゃって、めちゃくちゃ処理が重くなってしまった。画面サイズ程度を指定しないといかんのですな…。
Flixel に比べると、DXRuby は _カメラ が無い分、スクロール処理が面倒臭い印象も。
[ ツッコむ ]
#2 [hns] ソースコードに色付けをするようにしてみたり
この日記を出力している hns に、ソースコードの色分け・強調をする JavaScript を追加してみようと思い立った。検索した感じでは、以下が使えそうだなと。
_highlight.js
_highlight.jsの使い方 - MWソフト
_SyntaxHighlighter
_ソースコードの装飾表示方法 SyntaxHighlighter
一応両方試してみたのだけど、行番号を表示してくれる SyntaxHighlighter のほうが良さそうかなと。ファイル数が多くてちとアレではあるのだけど。
_highlight.js
_highlight.jsの使い方 - MWソフト
_SyntaxHighlighter
_ソースコードの装飾表示方法 SyntaxHighlighter
一応両方試してみたのだけど、行番号を表示してくれる SyntaxHighlighter のほうが良さそうかなと。ファイル数が多くてちとアレではあるのだけど。
◎ 導入手順メモ。 :
syntaxhighlighter_3.0.83.zip をDL・解凍して、scripts と styles フォルダを、hnsのあるフォルダにコピー。
hns の theme.ph 内の package HNS::ExtHTML; 以下のあたりに、css や JavaScript のソレを追加。
lib/HNS/Hnf/Command.pm の PRE のあたりを書き換え。
元々の記述。
↓ 修正後。
hnf中で、以下の書き方ができるようになった。
自分で付け加えといてなんだけど、たぶん数日後には書き方を忘れてそう。
hns の theme.ph 内の package HNS::ExtHTML; 以下のあたりに、css や JavaScript のソレを追加。
$Head = qq( <link rel="shortcut icon" href="icons/favicon.ico"> <link rel="alternate" type="application/rss+xml" title="RSS" href="${HNS::System::MyDiaryURI}rss.cgi"> <META http-equiv="Content-Style-Type" content="text/css"> <link rel="stylesheet" href="./import.css" type="text/css" media="all"> <script type="text/javascript" src="scripts/shCore.js"></script> <script type="text/javascript" src="scripts/shBrushAS3.js"></script> <script type="text/javascript" src="scripts/shBrushCss.js"></script> <script type="text/javascript" src="scripts/shBrushJScript.js"></script> <script type="text/javascript" src="scripts/shBrushPerl.js"></script> <script type="text/javascript" src="scripts/shBrushPlain.js"></script> <script type="text/javascript" src="scripts/shBrushPython.js"></script> <script type="text/javascript" src="scripts/shBrushRuby.js"></script> <script type="text/javascript" src="scripts/shBrushRuby.js"></script> <script type="text/javascript" src="scripts/shBrushXml.js"></script> <link type="text/css" rel="stylesheet" href="styles/shCoreDefault.css"> <script type="text/javascript">SyntaxHighlighter.all();</script> );
lib/HNS/Hnf/Command.pm の PRE のあたりを書き換え。
元々の記述。
# PRE package HNS::Hnf::Command::PRE; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd); @ISA = qw(HNS::Hnf::Command::Cite); $AllowCommands = [$HNS::Hnf::Command::Entities{'Inline'}]; $Template = "<pre>"; $EndTemplate = "</pre>";
↓ 修正後。
# PRE package HNS::Hnf::Command::PRE; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd $TemplateWithCode $EndTemplateWithCode $TemplateWithoutCode $EndTemplateWithoutCode); @ISA = qw(HNS::Hnf::Command::Cite); $NumAttr = 1; $Template = qq(<pre class="plain">); $EndTemplate = qq(</pre>); $TemplateWithoutCode = qq(<pre class="plain">); $EndTemplateWithoutCode = qq(</pre>); $TemplateWithCode = qq(<pre class="brush: %1">); $EndTemplateWithCode = "</pre>"; # $TemplateWithCode = qq(<pre><code>); # $EndTemplateWithCode = qq(</code></pre>); $AllowCommands = [$HNS::Hnf::Command::Entities{'Inline'}]; sub AsHTML ($$$){ my ($self, $start, $params) = @_; my $codelang = $self->{attr}->[1]; if ( $codelang ) { $Template = $TemplateWithCode; $EndTemplate = $EndTemplateWithCode; } else { $Template = $TemplateWithoutCode; $EndTemplate = $EndTemplateWithoutCode; } return $self->SUPER::AsHTML($start, $params); }後は hns.css を少し修正したり等。… hns.css って、公式版に含まれてたかな? 自分で勝手に付け加えたのかもしれない。
hnf中で、以下の書き方ができるようになった。
PRE ruby Rubyソースコード /PRE PRE perl Perlソースコード /PRE
自分で付け加えといてなんだけど、たぶん数日後には書き方を忘れてそう。
[ ツッコむ ]
#3 [python] PyGameのサイトが寂しい状態になってる…
[ ツッコむ ]
#4 [movie] トランスフォーマー実写版3を視聴
TV放映されてたので見てみたり。
参りました。技術的に。無茶苦茶な映像に、ただただ圧倒されてしまったり。
アナログ特撮時代は、こうやって作ってるのかなあ、てな想像がある程度は出来たものだけど。3DCGは、何をどうしたらこんな映像が作れるのか、そのへんさっぱり分かりませんな…。もっとも、宙を舞う車が、実写なのかミニチュアなのか3DCGなのか、それすらも分からないんだけど。
そういや、比較的最近のダイハードで、実車を本当に吹き飛ばして合成素材にしてたのに、監督(おそらくドラマ部分担当)が3DCGと思い込んでたという話もあったっけ。その映画を作ってる監督ですら判別ができないのだから、観客側にも分からないよな…。
参りました。技術的に。無茶苦茶な映像に、ただただ圧倒されてしまったり。
アナログ特撮時代は、こうやって作ってるのかなあ、てな想像がある程度は出来たものだけど。3DCGは、何をどうしたらこんな映像が作れるのか、そのへんさっぱり分かりませんな…。もっとも、宙を舞う車が、実写なのかミニチュアなのか3DCGなのか、それすらも分からないんだけど。
そういや、比較的最近のダイハードで、実車を本当に吹き飛ばして合成素材にしてたのに、監督(おそらくドラマ部分担当)が3DCGと思い込んでたという話もあったっけ。その映画を作ってる監督ですら判別ができないのだから、観客側にも分からないよな…。
[ ツッコむ ]
以上、1 日分です。