dxruby_tiled 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 988c6ed19ed82d78b9ccc6b7008715bbfa3c77ba
4
+ data.tar.gz: 10d757dfb2fc8fbad7096ad8e963a715b73cd655
5
+ SHA512:
6
+ metadata.gz: 4a9926855f6b9eb883a07277e17fb472541755b895dc498661b9e9ef4c7e07b5075dc56ade5d60cad263a04773fe8495ec96d8d67f1f49cc2d2dd5c3ffca7e40
7
+ data.tar.gz: cbc1023393139166e5bc420605629ddff1237351d79e932ad03bb45dbfe8886ac3eb7f4a7af49abdf1b4404a40481c5d0651c324c9f4230cea0bcdb01f083a14
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in dxruby_tiled.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 nodai2hITC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 TODO: Write your name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.ja.md ADDED
@@ -0,0 +1,58 @@
1
+ # DXRuby::Tiled
2
+
3
+ [DXRuby](http://dxruby.osdn.jp/) を用いて、[Tiled Map Editor](http://www.mapeditor.org/) のデータを描画するライブラリです。
4
+
5
+
6
+ ## インストール
7
+
8
+ $ gem install dxruby_tiled
9
+
10
+
11
+ ## 使用方法
12
+
13
+ require "dxruby_tiled"
14
+
15
+ x, y = 0, 0
16
+ map = DXRuby::Tiled.load_json("tiledmapeditorfile.json")
17
+
18
+ Window.loop do
19
+ map.draw(x, y)
20
+ end
21
+
22
+ 詳しくは、 examples/dxruby_tiled_test.rb 等をご参照あれ。
23
+
24
+
25
+ ## カスタムプロパティ
26
+
27
+ - map - x_loop, y_loop
28
+ -- x方向、y方向に関してループするマップになります。
29
+ - imagelayer - fixed
30
+ -- スクロールしない固定表示になります。
31
+
32
+ ## サポート状況
33
+
34
+ ### サポート済
35
+
36
+ - タイルレイヤー(□型、◇型、六角形型)
37
+ - 画像レイヤー
38
+ - タイルのアニメーション
39
+
40
+ ### サポート予定
41
+
42
+ - オブジェクトレイヤー
43
+ - 当たり判定
44
+
45
+ ### サポート予定なし
46
+
47
+ - TMX ファイルの読み込み
48
+
49
+
50
+ ## Contributing
51
+
52
+ Bug reports and pull requests are welcome on GitHub at https://github.com/nodai2hITC/dxruby_tiled.
53
+
54
+
55
+ ## ライセンス
56
+
57
+ [MIT License](http://opensource.org/licenses/MIT).
58
+
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # DXRuby::Tiled
2
+
3
+ DXRuby::Tiled is a ruby library that draw [Tiled Map Editor](http://www.mapeditor.org/) data by using [DXRuby](http://dxruby.osdn.jp/)
4
+
5
+
6
+ ## Install
7
+
8
+ $ gem install dxruby_tiled
9
+
10
+
11
+ ## How to use
12
+
13
+ require "dxruby_tiled"
14
+
15
+ x, y = 0, 0
16
+ map = DXRuby::Tiled.load_json("tiledmapeditorfile.json")
17
+
18
+ Window.loop do
19
+ map.draw(x, y)
20
+ end
21
+
22
+ For more information, examples/dxruby_tiled_test.rb
23
+
24
+
25
+ ## Custom properties
26
+
27
+ - map - x_loop, y_loop(bool)
28
+ - imagelayer - fixed(bool)
29
+
30
+ ## Support status
31
+
32
+ ### Supported
33
+
34
+ - tile layer (orthogonal, isometric, staggered, hexagonal)
35
+ - image layer
36
+ - animation
37
+
38
+ ### Will support
39
+
40
+ - object layer
41
+ - collision
42
+
43
+ ### Unsupported
44
+
45
+ - load .tmx file
46
+
47
+
48
+ ## Contributing
49
+
50
+ Bug reports and pull requests are welcome on GitHub at https://github.com/nodai2hITC/dxruby_tiled.
51
+
52
+
53
+ ## License
54
+
55
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
56
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dxruby_tiled/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "dxruby_tiled"
8
+ spec.version = DXRuby::Tiled::VERSION
9
+ spec.authors = ["nodai2h-ITC"]
10
+
11
+ spec.summary = %q{Draw TiledMapEditor JSON data by using DXRuby.}
12
+ spec.description = %q{Draw TiledMapEditor JSON data by using DXRuby.}
13
+ spec.homepage = "https://github.com/nodai2hITC/dxruby_tiled"
14
+ spec.license = "MIT"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_dependency 'dxruby'
27
+ spec.add_dependency 'json'
28
+
29
+ spec.add_development_dependency "bundler", "~> 1.14"
30
+ spec.add_development_dependency "rake", "~> 10.0"
31
+ end
@@ -0,0 +1,83 @@
1
+ require "dxruby_tiled"
2
+
3
+ puts "DXRuby::tiled example - ver 1.0.0"
4
+ if ARGV[0] == "--help" || ARGV[0] == "-h"
5
+ puts " usage: ruby dxruby_tiled_test.rb [jsonfile] [WindowWidth] [WindowHeight]"
6
+ exit
7
+ end
8
+ puts "Arrow Key: move (pressing the Shift key, slowly move)"
9
+ puts "M: Display the mouseover tile."
10
+ puts "L: Display layers."
11
+
12
+ filename = ARGV[0] || Window.open_filename([["JSONファイル(*.json)", "*.json"]], "Tiled Map Editor の JSON ファイルを選択")
13
+ exit unless filename
14
+
15
+ map = DXRuby::Tiled.load_json(filename)
16
+ Window.width = ARGV[1].to_i if ARGV[1]
17
+ Window.height = ARGV[2].to_i if ARGV[2]
18
+
19
+ x, y = 0, 0
20
+ draw_mouseovertile = true
21
+ draw_layers = false
22
+
23
+ font = Font.new(16)
24
+
25
+ mouseover_image = Image.new(32, 32, [128,128,128,255])
26
+
27
+ max_tile_width = map.tilesets.tile_images.max{|image| image.width }.width
28
+ max_tile_height = map.tilesets.tile_images.max{|image| image.height }.height
29
+
30
+ Window.loop do
31
+ x += Input.x * (!Input.key_down?(K_LSHIFT) ? 5 : 1)
32
+ y += Input.y * (!Input.key_down?(K_LSHIFT) ? 5 : 1)
33
+ map.draw(x, y)
34
+
35
+ tilelayer = map.layers.find{|layer| layer.is_a? DXRuby::Tiled::Layer }
36
+ pos_x, pos_y = tilelayer.xy_at(x + Input.mouse_x, y + Input.mouse_y)
37
+ vertexs = tilelayer.vertexs(pos_x, pos_y)
38
+ if vertexs.size == 4
39
+ Window.draw_morph(vertexs[0][0] - x, vertexs[0][1] - y,
40
+ vertexs[1][0] - x, vertexs[1][1] - y,
41
+ vertexs[2][0] - x, vertexs[2][1] - y,
42
+ vertexs[3][0] - x, vertexs[3][1] - y, mouseover_image)
43
+ else
44
+ Window.draw_morph(vertexs[0][0] - x, vertexs[0][1] - y,
45
+ vertexs[1][0] - x, vertexs[1][1] - y,
46
+ vertexs[2][0] - x, vertexs[2][1] - y,
47
+ vertexs[3][0] - x, vertexs[3][1] - y, mouseover_image)
48
+ Window.draw_morph(vertexs[3][0] - x, vertexs[3][1] - y,
49
+ vertexs[4][0] - x, vertexs[4][1] - y,
50
+ vertexs[5][0] - x, vertexs[5][1] - y,
51
+ vertexs[0][0] - x, vertexs[0][1] - y, mouseover_image)
52
+ end
53
+
54
+ draw_mouseovertile = !draw_mouseovertile if Input.key_push?(K_M)
55
+ if draw_mouseovertile
56
+ Window.draw_box_fill(Window.width - max_tile_width - 8, 0, Window.width, max_tile_height + 8, [92,92,92])
57
+ image = map.tilesets.tile_images[tilelayer[pos_x, pos_y]]
58
+ Window.draw(Window.width - max_tile_width / 2 - image.width / 2 - 4,
59
+ max_tile_height / 2 - image.height / 2 + 4, image)
60
+ end
61
+
62
+ draw_layers = !draw_layers if Input.key_push?(K_L)
63
+ if draw_layers
64
+ tmp_y = Window.height
65
+ map.layers.each do |layer|
66
+ tmp_y -= 20
67
+ Window.draw_font(23 , tmp_y + 1, layer.name.to_s, font, color: [0,0,0])
68
+ Window.draw_font(22 , tmp_y, layer.name.to_s, font)
69
+ Window.draw_box_fill(2, tmp_y + 2, 18, tmp_y + 18, [255,255,255])
70
+ Window.draw_box_fill(3, tmp_y + 3, 17, tmp_y + 17, [0,0,0])
71
+
72
+ if layer.visible
73
+ Window.draw_circle_fill(10, tmp_y + 10, 6, [255,255,255])
74
+ end
75
+ if Input.mouse_push?(M_LBUTTON) && Input.mouse_x >= 2 && Input.mouse_x <= 18 && Input.mouse_y >= tmp_y+2 && Input.mouse_y <= tmp_y+18
76
+ layer.visible = !layer.visible
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+ Window.caption = "DXRuby_tiled - FPS:#{Window.real_fps} FILE:#{filename}"
83
+ end
@@ -0,0 +1,25 @@
1
+ require "dxruby"
2
+ require "json"
3
+ require "zlib"
4
+ require "base64"
5
+ require "dxruby_tiled/version"
6
+ require "dxruby_tiled/map"
7
+ require "dxruby_tiled/tilesets"
8
+ require "dxruby_tiled/tileset"
9
+ require "dxruby_tiled/layer"
10
+ require "dxruby_tiled/layer_orthogonal"
11
+ require "dxruby_tiled/layer_isometric"
12
+ require "dxruby_tiled/layer_staggered"
13
+ require "dxruby_tiled/layer_hexagonal"
14
+ require "dxruby_tiled/objectgroup" # unsupported
15
+ require "dxruby_tiled/imagelayer"
16
+
17
+ module DXRuby
18
+ module Tiled
19
+ def self.load_json(jsonfile, encoding = "UTF-8", dir = nil)
20
+ return Map.new(JSON.load(File.read(jsonfile, encoding: encoding), nil,
21
+ symbolize_names: true, create_additions: false),
22
+ dir || File.dirname(jsonfile))
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ module DXRuby
2
+ module Tiled
3
+ class ImageLayer
4
+ attr_reader :data, :name, :properties
5
+ attr_accessor :opacity, :visible, :offset_x, :offset_y, :fixed
6
+
7
+ def initialize(data, map)
8
+ @original_data = data
9
+ @map = map
10
+
11
+ @name = data[:name]
12
+ @opacity = data[:opacity] || 1.0
13
+ @visible = data[:visible] != false
14
+ @offset_x = data[:offsetx] || 0
15
+ @offset_y = data[:offsety] || 0
16
+ @properties = data[:properties] || {}
17
+ @fixed = @properties[:fixed]
18
+
19
+ @image = @map.load_image(data[:image])
20
+ if data[:transparentcolor]
21
+ color = data[:transparentcolor].sub("#", "").scan(/../).map{|c| c.to_i(16) }
22
+ @image.set_color_key(color)
23
+ end
24
+ end
25
+
26
+ def draw(x, y, target = DXRuby::Window)
27
+ x = (x + target.width) % @map.pixel_width - target.width if @map.x_loop
28
+ y = (y + target.height) % @map.pixel_height - target.height if @map.y_loop
29
+ target.draw_alpha(@offset_x - (@fixed ? 0 : x), @offset_y - (@fixed? 0 : y),
30
+ @image, (255 * @opacity).to_i)
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,55 @@
1
+ module DXRuby
2
+ module Tiled
3
+ class Layer
4
+ attr_reader :data, :name, :width, :height, :properties
5
+ attr_accessor :opacity, :visible, :offset_x, :offset_y
6
+
7
+ def initialize(data, map)
8
+ @map = map
9
+
10
+ @name = data[:name]
11
+ @width = data[:width ] || map.width
12
+ @height = data[:height] || map.height
13
+ @opacity = data[:opacity] || 1.0
14
+ @visible = data[:visible] != false
15
+ @offset_x = data[:offsetx] || 0
16
+ @offset_y = data[:offsety] || 0
17
+ @properties = data[:properties] || {}
18
+
19
+ case data[:encoding]
20
+ when "base64"
21
+ tmp = Base64.decode64(data[:data])
22
+ case data[:compression]
23
+ when "gzip" # unsupported
24
+ when "zlib"
25
+ tmp = Zlib::Inflate.inflate(tmp).unpack("l*")
26
+ else
27
+ tmp = tmp.unpack("l*")
28
+ end
29
+ else
30
+ tmp = data[:data]
31
+ end
32
+ @data = tmp.each_slice(@width).to_a
33
+ end
34
+
35
+ def [](x, y)
36
+ x = @map.x_loop ? x % @width : x < 0 ? @width : x
37
+ y = @map.y_loop ? y % @height : y < 0 ? @height : y
38
+ return @data.fetch(y, []).fetch(x, 0)
39
+ end
40
+
41
+ def []=(x, y, value)
42
+ x = @map.x_loop ? x % @width : x < 0 ? @width : x
43
+ y = @map.y_loop ? y % @height : y < 0 ? @height : y
44
+ @data[y][x] = value
45
+ end
46
+
47
+ def include?(x, y)
48
+ return (@map.x_loop || (0...@width).include?(x)) &&
49
+ (@map.y_loop || (0...@height).include?(y))
50
+ end
51
+ alias_method :member?, :include?
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,133 @@
1
+ module DXRuby
2
+ module Tiled
3
+ class HexagonalLayer < Layer
4
+
5
+ def draw(x, y, target = DXRuby::Window)
6
+ tile_images = @map.tilesets.tile_images
7
+ left, top = xy_at(x - @offset_x, y - @offset_x)
8
+ left -= 1
9
+ top -= 1
10
+ off_x = x - @map.tile_width / 2 + @offset_x
11
+ off_y = y - @map.tile_height / 2 + @offset_y
12
+ alpha = (@opacity * 255).floor
13
+
14
+ if @map.stagger_axis_y
15
+ tile_width = @map.tile_width
16
+ tile_height = @map.tile_height - (@map.tile_height - @map.hex_side_length) / 2
17
+ x_range = left..(left + target.width / tile_width + 3).floor
18
+ y_range = top..(top + target.height / tile_height + 2).floor
19
+
20
+ y_range.each do |y2|
21
+ x0 = @map.stagger_index_odd ^ y2.even? ? tile_width / 2 : 0
22
+ x_range.each do |x2|
23
+ image = tile_images[self[x2, y2]]
24
+ target.draw_alpha(x0 + x2 * tile_width - off_x - image.width / 2,
25
+ y2 * tile_height - off_y - image.height / 2,
26
+ image, alpha)
27
+ end
28
+ end
29
+ else
30
+ tile_width = @map.tile_width - (@map.tile_width - @map.hex_side_length) / 2
31
+ tile_height = @map.tile_height
32
+ x_range = left..(left + target.width / tile_width + 2).floor
33
+ y_range = top..(top + target.height / tile_height + 3).floor
34
+
35
+ y_range.each do |y2|
36
+ x_range.each do |x2|
37
+ y0 = @map.stagger_index_odd ^ x2.even? ? tile_height / 2 : 0
38
+ image = tile_images[self[x2, y2]]
39
+ target.draw_alpha( x2 * tile_width - off_x - image.width / 2,
40
+ y0 + y2 * tile_height - off_y - image.height / 2,
41
+ image, alpha)
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ def xy_at(x, y)
48
+ if @map.stagger_axis_y
49
+ height = @map.tile_height - (@map.tile_height - @map.hex_side_length) / 2
50
+ y2 = y / height
51
+ x -= @map.tile_width / 2 if @map.stagger_index_odd ^ y2.even?
52
+ x2 = x / @map.tile_width
53
+ x0 = x % @map.tile_width
54
+ y0 = y % height
55
+ if (y0 < (@map.tile_height - height) - x0 * (@map.tile_height - height) * 2 / @map.tile_width)
56
+ y2 -= 1
57
+ x2 += @map.stagger_index_odd ^ y2.even? ? -1 : 0
58
+ elsif (y0 < x0 * (@map.tile_height - height) * 2 / @map.tile_width - (@map.tile_height - height))
59
+ y2 -= 1
60
+ x2 += @map.stagger_index_odd ^ y2.even? ? 0 : 1
61
+ end
62
+ else
63
+ width = @map.tile_width - (@map.tile_width - @map.hex_side_length) / 2
64
+ x2 = x / width
65
+ y -= @map.tile_height / 2 if @map.stagger_index_odd ^ x2.even?
66
+ y2 = y / @map.tile_height
67
+ x0 = x % width
68
+ y0 = y % @map.tile_height
69
+ if (y0 < @map.height / 2 - x0 * @map.tile_height / (@map.tile_width - width) / 2)
70
+ x2 -= 1
71
+ y2 += @map.stagger_index_odd ^ x2.even? ? -1 : 0
72
+ elsif (y0 > @map.height / 2 + x0 * @map.tile_height / (@map.tile_width - width) / 2)
73
+ x2 -= 1
74
+ y2 += @map.stagger_index_odd ^ x2.even? ? 0 : 1
75
+ end
76
+ end
77
+ return x2, y2
78
+ end
79
+
80
+ def at(x, y)
81
+ tmp_x, tmp_y = xy_at(x, y)
82
+ return self[tmp_x, tmp_y]
83
+ end
84
+
85
+ def change_at(x, y, value)
86
+ tmp_x, tmp_y = xy_at(x, y)
87
+ self[tmp_x, tmp_y] = value
88
+ end
89
+
90
+ def vertexs(x, y)
91
+ if @map.stagger_axis_y
92
+ w, h = @map.tile_width / 2, @map.tile_height - (@map.tile_height - @map.hex_side_length) / 2
93
+ x0 = @map.stagger_index_odd ^ y.even? ? w : 0
94
+ return [
95
+ [ x0 + x * w * 2 + w , y * h ],
96
+ [ x0 + x * w * 2 , y * h + h - @map.hex_side_length ],
97
+ [ x0 + x * w * 2 , y * h + h ],
98
+ [ x0 + x * w * 2 + w , y * h + @map.tile_height ],
99
+ [ x0 + x * w * 2 + w * 2, y * h + h ],
100
+ [ x0 + x * w * 2 + w * 2, y * h + h - @map.hex_side_length ]
101
+ ]
102
+ else
103
+ w, h = @map.tile_width - (@map.tile_width - @map.hex_side_length) / 2, @map.tile_height / 2
104
+ y0 = @map.stagger_index_odd ^ x.even? ? h : 0
105
+ return [
106
+ [ x * w, y0 + y * h * 2 + h , y * h ],
107
+ [ x * w + w - @map.hex_side_length, y0 + y * h * 2 ],
108
+ [ x * w + w , y0 + y * h * 2 ],
109
+ [ x * w + @map.tile_width , y0 + y * h * 2 + h ],
110
+ [ x * w + w , y0 + y * h * 2 + h * 2 ],
111
+ [ x * w + w - @map.hex_side_length, y0 + y * h * 2 + h * 2 ]
112
+ ]
113
+ end
114
+ end
115
+
116
+
117
+ def self.pixel_width(map)
118
+ return map.stagger_axis_y ?
119
+ map.tile_width * (map.tile_width - (map.tile_width - map.hex_side_length) / 2) +
120
+ (map.tile_width - map.hex_side_length) / 2 :
121
+ map.tile_width * (map.width + 1) / 2
122
+ end
123
+
124
+ def self.pixel_height(map)
125
+ return map.stagger_axis_y ?
126
+ map.tile_height * (map.height + 1) / 2 :
127
+ map.tile_height * (map.tile_height - (map.tile_height - map.hex_side_length) / 2) +
128
+ (map.tile_height - map.hex_side_length) / 2
129
+ end
130
+
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,69 @@
1
+ require "pry"
2
+
3
+ module DXRuby
4
+ module Tiled
5
+ class IsometricLayer < Layer
6
+
7
+ def draw(x, y, target = DXRuby::Window)
8
+ tile_width2, tile_height2 = @map.tile_width / 2, @map.tile_height / 2
9
+ tile_images = @map.tilesets.tile_images
10
+ left, top = xy_at(x - @offset_x, y - @offset_x)
11
+ left -= 1
12
+ top -= 1
13
+ x_range = 0..(target.width / tile_width2 / 2 + 1).floor
14
+ y_range = 0..(target.height / tile_height2 + 3).floor
15
+ off_x = x - @map.pixel_width / 2 + @offset_x
16
+ off_y = y - tile_height2 + @offset_y
17
+ alpha = (@opacity * 255).to_i
18
+
19
+ y_range.each do |yy|
20
+ x_range.each do |xx|
21
+ x2 = left + xx + yy / 2
22
+ y2 = top - xx + (yy + 1) / 2
23
+ image = tile_images[self[x2, y2]]
24
+ target.draw_alpha(x2 * tile_width2 - y2 * tile_width2 - off_x - image.width / 2,
25
+ y2 * tile_height2 + x2 * tile_height2 - off_y - image.height / 2,
26
+ image, alpha)
27
+ end
28
+ end
29
+ end
30
+
31
+ def xy_at(tmp_x, y)
32
+ x = tmp_x - @map.pixel_width / 2
33
+ return (1.0 * x / @map.tile_width + 1.0 * y / @map.tile_height).floor,
34
+ (1.0 * y / @map.tile_height - 1.0 * x / @map.tile_width).floor
35
+ end
36
+
37
+ def at(x, y)
38
+ tmp_x, tmp_y = xy_at(x, y)
39
+ return self[tmp_x, tmp_y]
40
+ end
41
+
42
+ def change_at(x, y, value)
43
+ tmp_x, tmp_y = xy_at(x, y)
44
+ self[tmp_x, tmp_y] = value
45
+ end
46
+
47
+ def vertexs(x, y)
48
+ x0 = @map.pixel_width / 2
49
+ w, h = @map.tile_width / 2, @map.tile_height / 2
50
+ return [
51
+ [ x0 + x * w - y * w , y * h + x * h ],
52
+ [ x0 + x * w - y * w - w, y * h + x * h + h ],
53
+ [ x0 + x * w - y * w , y * h + x * h + h * 2 ],
54
+ [ x0 + x * w - y * w + w, y * h + x * h + h ]
55
+ ]
56
+ end
57
+
58
+
59
+ def self.pixel_width(map)
60
+ return map.tile_width * (map.width + map.height) / 2
61
+ end
62
+
63
+ def self.pixel_height(map)
64
+ return map.tile_height * (map.width + map.height) / 2
65
+ end
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,59 @@
1
+ module DXRuby
2
+ module Tiled
3
+ class OrthogonalLayer < Layer
4
+
5
+ def draw(x, y, target = DXRuby::Window)
6
+ tile_width, tile_height = @map.tile_width, @map.tile_height
7
+ tile_images = @map.tilesets.tile_images
8
+ left, top = xy_at(x - @offset_x, y - @offset_x)
9
+ x_range = left..(left + (target.width / tile_width + 1).floor)
10
+ y_range = top..(top + (target.height / tile_height + 1).floor)
11
+ off_x = left * tile_width + (x - @offset_x) % tile_width - tile_width / 2
12
+ off_y = top * tile_height + (y - @offset_y) % tile_height - tile_height / 2
13
+ alpha = (@opacity * 255).floor
14
+ x_range = x_range.to_a.reverse if @map.renderorder_x
15
+ y_range = y_range.to_a.reverse if @map.renderorder_y
16
+
17
+ y_range.each do |yy|
18
+ x_range.each do |xx|
19
+ image = tile_images[self[xx, yy]]
20
+ target.draw_alpha(xx * tile_width - off_x - image.width / 2,
21
+ yy * tile_height - off_y - image.height / 2,
22
+ image, alpha)
23
+ end
24
+ end
25
+ end
26
+
27
+ def xy_at(x, y)
28
+ return x / @map.tile_width, y / @map.tile_height
29
+ end
30
+
31
+ def at(x, y)
32
+ return self[x / @map.tile_width, y / @map.tile_height]
33
+ end
34
+
35
+ def change_at(x, y, value)
36
+ self[x / @map.tile_width, y / @map.tile_height] = value
37
+ end
38
+
39
+ def vertexs(x, y)
40
+ w, h = @map.tile_width, @map.tile_height
41
+ return [
42
+ [ x * w , y * h ],
43
+ [ x * w , y * h + h ],
44
+ [ x * w + w, y * h + h ],
45
+ [ x * w + w, y * h ]
46
+ ]
47
+ end
48
+
49
+ def self.pixel_width(map)
50
+ return map.tile_width * map.width
51
+ end
52
+
53
+ def self.pixel_height(map)
54
+ return map.tile_height * map.height
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,121 @@
1
+ module DXRuby
2
+ module Tiled
3
+ class StaggeredLayer < Layer
4
+
5
+ def draw(x, y, target = DXRuby::Window)
6
+ tile_width2, tile_height2 = @map.tile_width / 2, @map.tile_height / 2
7
+ tile_images = @map.tilesets.tile_images
8
+ left, top = xy_at(x - @offset_x, y - @offset_x)
9
+ left -= 1
10
+ top -= 1
11
+ off_x = x - tile_width2 + @offset_x
12
+ off_y = y - tile_height2 + @offset_y
13
+ alpha = (@opacity * 255).floor
14
+
15
+ if @map.stagger_axis_y
16
+ x_range = left..(left + target.width / tile_width2 / 2 + 1).floor
17
+ y_range = top..(top + target.height / tile_height2 + 3).floor
18
+
19
+ y_range.each do |y2|
20
+ x0 = @map.stagger_index_odd ^ y2.even? ? tile_width2 : 0
21
+ x_range.each do |x2|
22
+ image = tile_images[self[x2, y2]]
23
+ target.draw_alpha(x0 + x2 * tile_width2 * 2 - off_x - image.width / 2,
24
+ y2 * tile_height2 - off_y - image.height / 2,
25
+ image, alpha)
26
+ end
27
+ end
28
+ else
29
+ x_range = left..(left + target.width / tile_width2 + 3).floor
30
+ y_range = top..(top + target.height / tile_height2 / 2 + 1).floor
31
+
32
+ y_range.each do |y2|
33
+ x_range.each do |x2|
34
+ y0 = @map.stagger_index_odd ^ x2.even? ? tile_height2 : 0
35
+ image = tile_images[self[x2, y2]]
36
+ target.draw_alpha( x2 * tile_width2 - off_x - image.width / 2,
37
+ y0 + y2 * tile_height2 * 2 - off_y - image.height / 2,
38
+ image, alpha)
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def xy_at(x, y)
45
+ if @map.stagger_axis_y
46
+ y2 = y * 2 / @map.tile_height
47
+ x -= @map.tile_width / 2 if @map.stagger_index_odd ^ y2.even?
48
+ x2 = x / @map.tile_width
49
+ x0 = x % @map.tile_width
50
+ y0 = y % (@map.tile_height / 2)
51
+ if (y0 < @map.tile_height / 2 - x0 * @map.tile_height / @map.tile_width)
52
+ y2 -= 1
53
+ x2 += @map.stagger_index_odd ^ y2.even? ? -1 : 0
54
+ elsif (y0 < x0 * @map.tile_height / @map.tile_width - @map.tile_height / 2)
55
+ y2 -= 1
56
+ x2 += @map.stagger_index_odd ^ y2.even? ? 0 : 1
57
+ end
58
+ else
59
+ x2 = x * 2 / @map.tile_width
60
+ y -= @map.tile_height / 2 if @map.stagger_index_odd ^ x2.even?
61
+ y2 = y / @map.tile_height
62
+ x0 = x % (@map.tile_width / 2)
63
+ y0 = y % @map.tile_height
64
+ if (y0 < @map.tile_height / 2 - x0 * @map.tile_height / @map.tile_width)
65
+ x2 -= 1
66
+ y2 += @map.stagger_index_odd ^ x2.even? ? -1 : 0
67
+ elsif (y0 > x0 * @map.tile_height / @map.tile_width + @map.tile_height / 2)
68
+ x2 -= 1
69
+ y2 += @map.stagger_index_odd ^ x2.even? ? 0 : 1
70
+ end
71
+ end
72
+ return x2, y2
73
+ end
74
+
75
+ def at(x, y)
76
+ tmp_x, tmp_y = xy_at(x, y)
77
+ return self[tmp_x, tmp_y]
78
+ end
79
+
80
+ def change_at(x, y, value)
81
+ tmp_x, tmp_y = xy_at(x, y)
82
+ self[tmp_x, tmp_y] = value
83
+ end
84
+
85
+ def vertexs(x, y)
86
+ w, h = @map.tile_width / 2, @map.tile_height / 2
87
+ if @map.stagger_axis_y
88
+ x0 = @map.stagger_index_odd ^ y.even? ? w : 0
89
+ return [
90
+ [ x0 + x * w * 2 + w , y * h ],
91
+ [ x0 + x * w * 2 , y * h + h ],
92
+ [ x0 + x * w * 2 + w , y * h + h * 2 ],
93
+ [ x0 + x * w * 2 + w * 2, y * h + h ]
94
+ ]
95
+ else
96
+ y0 = @map.stagger_index_odd ^ x.even? ? h : 0
97
+ return [
98
+ [ x * w + w , y0 + y * h * 2 ],
99
+ [ x * w , y0 + y * h * 2 + h ],
100
+ [ x * w + w , y0 + y * h * 2 + h * 2 ],
101
+ [ x * w + w * 2, y0 + y * h * 2 + h ]
102
+ ]
103
+ end
104
+ end
105
+
106
+
107
+ def self.pixel_width(map)
108
+ return map.stagger_axis_y ?
109
+ map.tile_width * map.width + map.tile_width / 2 :
110
+ map.tile_width * (map.width + 1) / 2
111
+ end
112
+
113
+ def self.pixel_height(map)
114
+ return map.stagger_axis_y ?
115
+ map.tile_height * (map.height + 1) / 2 :
116
+ map.tile_height * map.height + map.tile_height / 2
117
+ end
118
+
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,91 @@
1
+ module DXRuby
2
+ module Tiled
3
+ class Map
4
+ attr_reader :data_dir, :tilesets, :layers,
5
+ :version, :orientation, :renderorder_x, :renderorder_y,
6
+ :width, :height, :tile_width, :tile_height,
7
+ :hex_side_length, :stagger_axis_y, :stagger_index_odd,
8
+ :next_object_id, :properties, :x_loop, :y_loop
9
+ attr_accessor :background_color
10
+
11
+ def initialize(data, data_dir)
12
+ @data_dir = data_dir
13
+
14
+ @version = data[:version]
15
+ @orientation = case data[:orientation]
16
+ when "isometric"
17
+ IsometricLayer
18
+ when "staggered"
19
+ StaggeredLayer
20
+ when "hexagonal"
21
+ HexagonalLayer
22
+ else
23
+ OrthogonalLayer
24
+ end
25
+ @width = data[:width] || 100
26
+ @height = data[:height] || 100
27
+ @tile_width = data[:tilewidth] || 32
28
+ @tile_height = data[:tileheight] || 32
29
+ @hex_side_length = data[:hexsidelength] || 0
30
+ @stagger_axis_y = data[:staggeraxis] != "x"
31
+ @stagger_index_odd = data[:staggerindex] != "even"
32
+ @next_object_id = data[:nextobjectid] || 1
33
+ @properties = data[:properties] || {}
34
+ @x_loop = !!@properties[:x_loop]
35
+ @y_loop = !!@properties[:y_loop]
36
+ @renderorder_x = false
37
+ @renderorder_y = false
38
+ case data[:renderorder]
39
+ when "left-down"
40
+ @renderorder_x = true
41
+ when "right-up"
42
+ @renderorder_y = true
43
+ when "left-up"
44
+ @renderorder_x = true
45
+ @renderorder_y = true
46
+ end
47
+ @background_color = nil
48
+ if data[:backgroundcolor]
49
+ @background_color = data[:backgroundcolor].sub("#", "").scan(/../).map do |color|
50
+ color.to_i(16)
51
+ end
52
+ end
53
+
54
+ @layers = data[:layers].map do |layer|
55
+ case layer[:type]
56
+ when "tilelayer"
57
+ @orientation.new(layer, self)
58
+ when "objectgroup"
59
+ ObjectGroup.new(layer, self)
60
+ when "imagelayer"
61
+ ImageLayer.new(layer, self)
62
+ end
63
+ end
64
+ def @layers.name(name)
65
+ return self.find{|layer| layer.name == name}
66
+ end
67
+
68
+ @tilesets = Tilesets.new(data[:tilesets], self)
69
+ end
70
+
71
+ def draw(x, y, target = DXRuby::Window)
72
+ target.draw_box_fill(0, 0, target.width, target.height, @background_color) if @background_color
73
+ tilesets.animation()
74
+ @layers.each{|layer| layer.draw(x, y, target) if layer.visible }
75
+ end
76
+
77
+ def load_image(filename)
78
+ return DXRuby::Image.load(File.join(@data_dir, filename))
79
+ end
80
+
81
+ def pixel_width()
82
+ return @orientation.pixel_width(self)
83
+ end
84
+
85
+ def pixel_height()
86
+ return @orientation.pixel_height(self)
87
+ end
88
+
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,26 @@
1
+ module DXRuby
2
+ module Tiled
3
+ class ObjectGroup # unsupported
4
+ attr_reader :data, :name, :width, :height, :properties
5
+ attr_accessor :opacity, :visible, :offset_x, :offset_y
6
+
7
+ def initialize(data, map)
8
+ @original_data = data
9
+ @map = map
10
+
11
+ @name = data[:name]
12
+ @color = data[:color] || [128, 128, 128]
13
+ @opacity = data[:opacity] || 1
14
+ @visible = data[:visible] != false
15
+ @offset_x = data[:offsetx] || 0
16
+ @offset_y = data[:offsety] || 0
17
+ @properties = data[:properties] || {}
18
+ @draworder = data[:draworder] || "topdown"
19
+ end
20
+
21
+ def draw(x, y, target = DXRuby::Window)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,71 @@
1
+ module DXRuby
2
+ module Tiled
3
+ class Tileset
4
+ attr_reader :firstgid, :name, :tile_width, :tile_height,
5
+ :spacing, :margin, :tile_count, :columns, :tile_offset, :properties,
6
+ :tile_images, :animations
7
+
8
+ def initialize(data, map)
9
+ @data = data
10
+ @map = map
11
+
12
+ @firstgid = data[:firstgid] || 1
13
+ @name = data[:name]
14
+ @tile_width = data[:tilewidth] || map.tile_width
15
+ @tile_height = data[:tileheight] || map.tile_height
16
+ @spacing = data[:spacing] || 0
17
+ @margin = data[:margin] || 0
18
+ @tile_count = data[:tilecount]
19
+ @columns = data[:columns]
20
+ @tile_offset = data[:tileoffset] # unsupported
21
+ @properties = data[:properties] || {}
22
+
23
+ image = @map.load_image(data[:image])
24
+ if data[:transparentcolor]
25
+ color = data[:transparentcolor].sub("#", "").scan(/../).map{|c| c.to_i(16) }
26
+ image.set_color_key(color)
27
+ end
28
+ image_width = data[:imagewidth] || image.width
29
+ image_height = data[:imageheight] || image.height
30
+
31
+ @tile_images = []
32
+ i = 0
33
+ col = 1
34
+ x = @margin
35
+ y = @margin
36
+ loop do
37
+ if x + @tile_width > image_width || (@columns && col > @columns)
38
+ x = @margin
39
+ y += @tile_height + @spacing
40
+ col = 1
41
+ end
42
+ break if y + @tile_height > image_height
43
+
44
+ @tile_images[i] = image.slice(x, y, @tile_width, @tile_height)
45
+ x += @tile_width + @spacing
46
+ i += 1
47
+ col += 1
48
+ break if @tile_count && i >= @tile_count
49
+ end
50
+ @tile_count = i unless @tile_count
51
+ image.dispose()
52
+
53
+ @animations = {}
54
+ (data[:tiles] || {}).each_pair do |key, value|
55
+ next unless value.has_key?(:animation)
56
+ anim_time = []
57
+ anim_image = []
58
+ time = 0
59
+ value[:animation].each do |anim|
60
+ anim_time.push(time)
61
+ anim_image.push(@tile_images[anim[:tileid]])
62
+ time += anim[:duration]
63
+ end
64
+ anim_time.push(time)
65
+ @animations[@firstgid + key.to_s.to_i] = { time: anim_time, image: anim_image }
66
+ end
67
+ end
68
+
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,34 @@
1
+ module DXRuby
2
+ module Tiled
3
+ class Tilesets
4
+ attr_reader :tile_images
5
+
6
+ def initialize(data, map)
7
+ @data = data
8
+ @map = map
9
+
10
+ @last_time = 0
11
+ @tile_images = [DXRuby::Image.new(32, 32)]
12
+ @tilesets = @data.map{|tileset| Tileset.new(tileset, @map)}
13
+ @animations = {}
14
+
15
+ @tilesets.each do |tileset|
16
+ gid = tileset.firstgid || @tile_images.size
17
+ tileset.tile_images.each_index{|i| @tile_images[gid + i] = tileset.tile_images[i] }
18
+ @animations.merge!(tileset.animations)
19
+ end
20
+ end
21
+
22
+ def animation()
23
+ return if @last_time == DXRuby::Window::running_time
24
+ @last_time = DXRuby::Window::running_time
25
+
26
+ @animations.each_pair do |key, anim|
27
+ time = @last_time % anim[:time].last
28
+ @tile_images[key] = anim[:image][anim[:time].rindex{|t| time >= t }]
29
+ end
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,5 @@
1
+ module DXRuby
2
+ module Tiled
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dxruby_tiled
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - nodai2h-ITC
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-02-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dxruby
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.14'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.14'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description: Draw TiledMapEditor JSON data by using DXRuby.
70
+ email:
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".gitignore"
76
+ - Gemfile
77
+ - LICENSE
78
+ - LICENSE.txt
79
+ - README.ja.md
80
+ - README.md
81
+ - Rakefile
82
+ - dxruby_tiled.gemspec
83
+ - examples/dxruby_tiled_test.rb
84
+ - lib/dxruby_tiled.rb
85
+ - lib/dxruby_tiled/imagelayer.rb
86
+ - lib/dxruby_tiled/layer.rb
87
+ - lib/dxruby_tiled/layer_hexagonal.rb
88
+ - lib/dxruby_tiled/layer_isometric.rb
89
+ - lib/dxruby_tiled/layer_orthogonal.rb
90
+ - lib/dxruby_tiled/layer_staggered.rb
91
+ - lib/dxruby_tiled/map.rb
92
+ - lib/dxruby_tiled/objectgroup.rb
93
+ - lib/dxruby_tiled/tileset.rb
94
+ - lib/dxruby_tiled/tilesets.rb
95
+ - lib/dxruby_tiled/version.rb
96
+ homepage: https://github.com/nodai2hITC/dxruby_tiled
97
+ licenses:
98
+ - MIT
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 2.6.10
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: Draw TiledMapEditor JSON data by using DXRuby.
120
+ test_files: []