mieki256's diary



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 というライブラリも必要らしくて、一緒にインストールされる。

下のような感じで使えるみたい。勘で試したので自信無いけど。
#!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つほど。

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 のほうが良さそうかなと。ファイル数が多くてちとアレではあるのだけど。

導入手順メモ。 :

syntaxhighlighter_3.0.83.zip をDL・解凍して、scripts と styles フォルダを、hnsのあるフォルダにコピー。

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のサイトが寂しい状態になってる…

_http://www.pygame.org/

HDDが壊れたと書いてある…。SDL2.0対応どころじゃなさそうだな…。

#4 [movie] トランスフォーマー実写版3を視聴

TV放映されてたので見てみたり。

参りました。技術的に。無茶苦茶な映像に、ただただ圧倒されてしまったり。

アナログ特撮時代は、こうやって作ってるのかなあ、てな想像がある程度は出来たものだけど。3DCGは、何をどうしたらこんな映像が作れるのか、そのへんさっぱり分かりませんな…。もっとも、宙を舞う車が、実写なのかミニチュアなのか3DCGなのか、それすらも分からないんだけど。

そういや、比較的最近のダイハードで、実車を本当に吹き飛ばして合成素材にしてたのに、監督(おそらくドラマ部分担当)が3DCGと思い込んでたという話もあったっけ。その映画を作ってる監督ですら判別ができないのだから、観客側にも分からないよな…。

以上、1 日分です。

過去ログ表示

Prev - 2013/09 - 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

カテゴリで表示

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


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

Powered by hns-2.19.6, HyperNikkiSystem Project