dxruby_tiled 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.ja.md +10 -19
- data/README.md +7 -14
- data/dxruby_tiled.gemspec +7 -9
- data/examples/dxruby_tiled_test.rb +226 -54
- data/lib/dxruby_tiled.rb +35 -10
- data/lib/dxruby_tiled/grouplayer.rb +30 -0
- data/lib/dxruby_tiled/imagelayer.rb +40 -24
- data/lib/dxruby_tiled/layer.rb +17 -40
- data/lib/dxruby_tiled/layer_hexagonal.rb +97 -94
- data/lib/dxruby_tiled/layer_isometric.rb +33 -46
- data/lib/dxruby_tiled/layer_orthogonal.rb +29 -29
- data/lib/dxruby_tiled/layer_staggered.rb +80 -77
- data/lib/dxruby_tiled/map.rb +67 -51
- data/lib/dxruby_tiled/object.rb +263 -0
- data/lib/dxruby_tiled/objectgroup.rb +36 -15
- data/lib/dxruby_tiled/tile.rb +139 -0
- data/lib/dxruby_tiled/tilelayer.rb +116 -0
- data/lib/dxruby_tiled/tileset.rb +100 -27
- data/lib/dxruby_tiled/tilesets.rb +49 -15
- data/lib/dxruby_tiled/tmx_loader.rb +271 -0
- data/lib/dxruby_tiled/version.rb +1 -1
- metadata +29 -24
- data/LICENSE +0 -21
data/lib/dxruby_tiled.rb
CHANGED
@@ -1,25 +1,50 @@
|
|
1
|
-
require "dxruby"
|
2
|
-
require "json"
|
3
|
-
require "zlib"
|
4
|
-
require "base64"
|
1
|
+
require "dxruby" unless defined? DXRuby
|
2
|
+
require "json" unless defined? JSON
|
3
|
+
require "zlib" unless defined? Zlib
|
4
|
+
require "base64" unless defined? Base64
|
5
5
|
require "dxruby_tiled/version"
|
6
6
|
require "dxruby_tiled/map"
|
7
|
-
require "dxruby_tiled/
|
7
|
+
require "dxruby_tiled/tile"
|
8
8
|
require "dxruby_tiled/tileset"
|
9
|
+
require "dxruby_tiled/tilesets"
|
9
10
|
require "dxruby_tiled/layer"
|
11
|
+
require "dxruby_tiled/tilelayer"
|
10
12
|
require "dxruby_tiled/layer_orthogonal"
|
11
13
|
require "dxruby_tiled/layer_isometric"
|
12
14
|
require "dxruby_tiled/layer_staggered"
|
13
15
|
require "dxruby_tiled/layer_hexagonal"
|
14
|
-
require "dxruby_tiled/
|
16
|
+
require "dxruby_tiled/object"
|
17
|
+
require "dxruby_tiled/objectgroup"
|
15
18
|
require "dxruby_tiled/imagelayer"
|
19
|
+
require "dxruby_tiled/grouplayer"
|
16
20
|
|
17
21
|
module DXRuby
|
18
22
|
module Tiled
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
+
module_function
|
24
|
+
autoload :TMXLoader, "dxruby_tiled/tmx_loader"
|
25
|
+
|
26
|
+
def load(file, encoding = Encoding::UTF_8, dir = nil)
|
27
|
+
case File.extname(file)
|
28
|
+
when ".tmx", ".xml"
|
29
|
+
TMXLoader.load_tmx(file, encoding, dir)
|
30
|
+
else
|
31
|
+
load_json(file, encoding, dir)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def read_file(file, encoding = Encoding::UTF_8)
|
36
|
+
File.read(file, encoding: encoding)
|
37
|
+
end
|
38
|
+
|
39
|
+
def load_json(jsonfile, encoding = Encoding::UTF_8, dir = nil)
|
40
|
+
Map.new(read_jsonfile(jsonfile, encoding), dir || File.dirname(jsonfile))
|
41
|
+
end
|
42
|
+
|
43
|
+
def read_jsonfile(jsonfile, encoding = Encoding::UTF_8)
|
44
|
+
JSON.parse(
|
45
|
+
read_file(jsonfile, encoding),
|
46
|
+
symbolize_names: true, create_additions: false
|
47
|
+
)
|
23
48
|
end
|
24
49
|
end
|
25
50
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module DXRuby
|
2
|
+
module Tiled
|
3
|
+
class GroupLayer < Layer
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def initialize(data, map)
|
7
|
+
super
|
8
|
+
@layers = data[:layers].map do |layer|
|
9
|
+
Layer.create(layer, map)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](name)
|
14
|
+
return @layers[name] if name.is_a? Integer
|
15
|
+
return @layers.find { |layer| layer.name == name }
|
16
|
+
end
|
17
|
+
|
18
|
+
def each
|
19
|
+
@layers.each { |layer| yield layer }
|
20
|
+
end
|
21
|
+
|
22
|
+
def render(x, y, target = DXRuby::Window, z = 0, offset_x = 0, offset_y = 0, opacity = 1.0)
|
23
|
+
@layers.each do |layer|
|
24
|
+
layer.render(x, y, target, z + @z_index, offset_x + @offset_x, offset_y + @offset_y, opacity * @opacity) if layer.visible
|
25
|
+
end
|
26
|
+
end
|
27
|
+
alias_method :draw, :render
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,35 +1,51 @@
|
|
1
1
|
module DXRuby
|
2
2
|
module Tiled
|
3
|
-
class ImageLayer
|
4
|
-
|
5
|
-
attr_accessor :opacity, :visible, :offset_x, :offset_y, :fixed
|
3
|
+
class ImageLayer < Layer
|
4
|
+
attr_accessor :image, :fixed, :x_loop, :y_loop
|
6
5
|
|
7
6
|
def initialize(data, map)
|
8
|
-
|
9
|
-
@
|
7
|
+
super
|
8
|
+
@x_loop = !!@properties[:x_loop]
|
9
|
+
@y_loop = !!@properties[:y_loop]
|
10
|
+
@image = map.load_image(data[:image], data[:transparentcolor])
|
11
|
+
@map_loop = map.loop
|
12
|
+
@map_pixel_width = map.pixel_width
|
13
|
+
@map_pixel_height = map.pixel_height
|
14
|
+
end
|
15
|
+
|
16
|
+
def render(x, y, target = DXRuby::Window, z = 0, offset_x = 0, offset_y = 0, opacity = 1.0)
|
17
|
+
x_range = 0..0
|
18
|
+
if @x_loop
|
19
|
+
x0 = (@offset_x + offset_x - (@fixed? 0 : x)) % @image.width
|
20
|
+
x_range = -1..((target.width - 1) / @image.width)
|
21
|
+
elsif @fixed
|
22
|
+
x0 = @offset_x + offset_x
|
23
|
+
elsif @map_loop
|
24
|
+
x0 = (@offset_x + offset_x - x + target.width) % @map_pixel_width - target.width
|
25
|
+
else
|
26
|
+
x0 = @offset_x + offset_x - x
|
27
|
+
end
|
10
28
|
|
11
|
-
|
12
|
-
@
|
13
|
-
|
14
|
-
|
15
|
-
@
|
16
|
-
|
17
|
-
|
29
|
+
y_range = 0..0
|
30
|
+
if @y_loop
|
31
|
+
y0 = (@offset_y + offset_y - (@fixed? 0 : y)) % @image.height
|
32
|
+
y_range = -1..((target.height - 1) / @image.height)
|
33
|
+
elsif @fixed
|
34
|
+
y0 = @offset_y + offset_y
|
35
|
+
elsif @map_loop
|
36
|
+
y0 = (@offset_y + offset_y - y + target.height) % @map_pixel_height - target.height
|
37
|
+
else
|
38
|
+
y0 = @offset_y + offset_y - y
|
39
|
+
end
|
18
40
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
41
|
+
x_range.each do |i_x|
|
42
|
+
y_range.each do |i_y|
|
43
|
+
target.draw_alpha(x0 + @image.width * i_x, y0 + @image.height * i_y,
|
44
|
+
@image, 255 * opacity * @opacity, z + @z_index)
|
45
|
+
end
|
23
46
|
end
|
24
47
|
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
|
-
|
48
|
+
alias_method :draw, :render
|
33
49
|
end
|
34
50
|
end
|
35
51
|
end
|
data/lib/dxruby_tiled/layer.rb
CHANGED
@@ -1,55 +1,32 @@
|
|
1
1
|
module DXRuby
|
2
2
|
module Tiled
|
3
3
|
class Layer
|
4
|
-
attr_reader :
|
5
|
-
attr_accessor :opacity, :visible, :offset_x, :offset_y
|
4
|
+
attr_reader :name, :properties
|
5
|
+
attr_accessor :opacity, :visible, :offset_x, :offset_y, :z_index
|
6
|
+
|
7
|
+
def self.create(data, map)
|
8
|
+
case data[:type]
|
9
|
+
when "tilelayer"
|
10
|
+
map.orientation.new(data, map)
|
11
|
+
when "objectgroup"
|
12
|
+
DXRuby::Tiled::ObjectGroup.new(data, map)
|
13
|
+
when "imagelayer"
|
14
|
+
DXRuby::Tiled::ImageLayer.new(data, map)
|
15
|
+
when "group"
|
16
|
+
DXRuby::Tiled::GroupLayer.new(data, map)
|
17
|
+
end
|
18
|
+
end
|
6
19
|
|
7
20
|
def initialize(data, map)
|
8
|
-
@map = map
|
9
|
-
|
10
21
|
@name = data[:name]
|
11
|
-
@width = data[:width ] || map.width
|
12
|
-
@height = data[:height] || map.height
|
13
22
|
@opacity = data[:opacity] || 1.0
|
14
23
|
@visible = data[:visible] != false
|
15
24
|
@offset_x = data[:offsetx] || 0
|
16
25
|
@offset_y = data[:offsety] || 0
|
17
26
|
@properties = data[:properties] || {}
|
18
|
-
|
19
|
-
|
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)
|
27
|
+
@z_index = @properties[:z_index] || 0
|
28
|
+
@fixed = !!@properties[:fixed]
|
39
29
|
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
30
|
end
|
54
31
|
end
|
55
32
|
end
|
@@ -1,133 +1,136 @@
|
|
1
1
|
module DXRuby
|
2
2
|
module Tiled
|
3
|
-
class HexagonalLayer <
|
3
|
+
class HexagonalLayer < TileLayer
|
4
|
+
def initialize(data, map)
|
5
|
+
super
|
6
|
+
@stagger_axis_y = map.stagger_axis_y
|
7
|
+
@stagger_index_odd = map.stagger_index_odd
|
8
|
+
@hex_side_length = map.hex_side_length
|
9
|
+
end
|
4
10
|
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
def render(pos_x, pos_y, target = DXRuby::Window, z = @z_index, offset_x = 0, offset_y = 0, opacity = 1.0)
|
12
|
+
super
|
13
|
+
|
14
|
+
pos_x, pos_y = 0, 0 if @fixed
|
15
|
+
off_x = offset_x + @offset_x - pos_x
|
16
|
+
off_y = offset_y + @offset_y - pos_y
|
17
|
+
x1, y1 = xy_at(@tile_width - @tilesets.tile_right - off_x,
|
18
|
+
@tile_height - @tilesets.tile_bottom - off_y)
|
19
|
+
x2, y2 = xy_at(@render_target.width - @tilesets.tile_left - off_x - 1,
|
20
|
+
@render_target.height - @tilesets.tile_top - off_y - 1)
|
21
|
+
x_range = ((x1 - 1)..(x2 + 1))
|
22
|
+
y_range = ((y1 - 1)..(y2 + 1))
|
13
23
|
|
14
|
-
if @
|
15
|
-
tile_width = @
|
16
|
-
tile_height = @
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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)
|
24
|
+
if @stagger_axis_y
|
25
|
+
tile_width = @tile_width
|
26
|
+
tile_height = @tile_height - (@tile_height - @hex_side_length) / 2
|
27
|
+
y_range.public_send(@renderorder_y ? :each : :reverse_each) do |y|
|
28
|
+
x0 = @stagger_index_odd ^ y.even? ? tile_width / 2 : 0
|
29
|
+
x_range.public_send(@renderorder_x ? :each : :reverse_each) do |x|
|
30
|
+
@tilesets[self[x, y]].render(
|
31
|
+
x * tile_width + off_x + x0,
|
32
|
+
y * tile_height + off_y,
|
33
|
+
@render_target)
|
27
34
|
end
|
28
35
|
end
|
29
36
|
else
|
30
|
-
tile_width = @
|
31
|
-
tile_height = @
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
tile_width = @tile_width - (@tile_width - @hex_side_length) / 2
|
38
|
+
tile_height = @tile_height
|
39
|
+
y_range.public_send(@renderorder_y ? :each : :reverse_each) do |y|
|
40
|
+
x_range.public_send(@renderorder_x ? :each : :reverse_each) do |x|
|
41
|
+
next if @stagger_index_odd ^ x.even?
|
42
|
+
@tilesets[self[x, y]].render(
|
43
|
+
x * tile_width + off_x,
|
44
|
+
y * tile_height + off_y,
|
45
|
+
@render_target)
|
46
|
+
end
|
47
|
+
x_range.public_send(@renderorder_x ? :each : :reverse_each) do |x|
|
48
|
+
next unless @stagger_index_odd ^ x.even?
|
49
|
+
@tilesets[self[x, y]].render(
|
50
|
+
x * tile_width + off_x,
|
51
|
+
y * tile_height + off_y + tile_height / 2,
|
52
|
+
@render_target)
|
42
53
|
end
|
43
54
|
end
|
44
55
|
end
|
56
|
+
|
57
|
+
target.draw_alpha(0, 0, @render_target, @opacity * 255, z + @z_index)
|
45
58
|
end
|
59
|
+
alias_method :draw, :render
|
46
60
|
|
47
|
-
def xy_at(
|
48
|
-
if @
|
49
|
-
height = @
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
if (
|
56
|
-
|
57
|
-
|
58
|
-
elsif (
|
59
|
-
|
60
|
-
|
61
|
+
def xy_at(pos_x, pos_y)
|
62
|
+
if @stagger_axis_y
|
63
|
+
height = @tile_height - (@tile_height - @hex_side_length) / 2
|
64
|
+
y = (pos_y / height).floor
|
65
|
+
pos_x -= @tile_width / 2 if @stagger_index_odd ^ y.even?
|
66
|
+
x = (pos_x / @tile_width).floor
|
67
|
+
dx = pos_x % @tile_width
|
68
|
+
dy = pos_y % height
|
69
|
+
if (dy < (@tile_height - height) - dx * (@tile_height - height) * 2 / @tile_width)
|
70
|
+
y -= 1
|
71
|
+
x += @stagger_index_odd ^ y.even? ? -1 : 0
|
72
|
+
elsif (dy < dx * (@tile_height - height) * 2 / @tile_width - (@tile_height - height))
|
73
|
+
y -= 1
|
74
|
+
x += @stagger_index_odd ^ y.even? ? 0 : 1
|
61
75
|
end
|
62
76
|
else
|
63
|
-
width = @
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
if (
|
70
|
-
|
71
|
-
|
72
|
-
elsif (
|
73
|
-
|
74
|
-
|
77
|
+
width = @tile_width - (@tile_width - @hex_side_length) / 2
|
78
|
+
x = (pos_x / width).floor
|
79
|
+
pos_y -= @tile_height / 2 if @stagger_index_odd ^ x.even?
|
80
|
+
y = (pos_y / @tile_height).floor
|
81
|
+
dx = pos_x % width
|
82
|
+
dy = pos_y % @tile_height
|
83
|
+
if (dy * 2 < @tile_height - dx * @tile_height / (@tile_width - width))
|
84
|
+
x -= 1
|
85
|
+
y += @stagger_index_odd ^ x.even? ? -1 : 0
|
86
|
+
elsif (dy > @tile_height / 2 + dx * @tile_height / (@tile_width - width) / 2)
|
87
|
+
x -= 1
|
88
|
+
y += @stagger_index_odd ^ x.even? ? 0 : 1
|
75
89
|
end
|
76
90
|
end
|
77
|
-
return
|
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
|
91
|
+
return x, y
|
88
92
|
end
|
89
93
|
|
90
94
|
def vertexs(x, y)
|
91
|
-
if @
|
92
|
-
w, h = @
|
93
|
-
x0 = @
|
95
|
+
if @stagger_axis_y
|
96
|
+
w, h = @tile_width / 2, @tile_height - (@tile_height - @hex_side_length) / 2
|
97
|
+
x0 = @stagger_index_odd ^ y.even? ? w : 0
|
94
98
|
return [
|
95
99
|
[ x0 + x * w * 2 + w , y * h ],
|
96
|
-
[ x0 + x * w * 2 , y * h + h - @
|
100
|
+
[ x0 + x * w * 2 , y * h + h - @hex_side_length ],
|
97
101
|
[ x0 + x * w * 2 , y * h + h ],
|
98
|
-
[ x0 + x * w * 2 + w , y * h + @
|
102
|
+
[ x0 + x * w * 2 + w , y * h + @tile_height ],
|
99
103
|
[ x0 + x * w * 2 + w * 2, y * h + h ],
|
100
|
-
[ x0 + x * w * 2 + w * 2, y * h + h - @
|
104
|
+
[ x0 + x * w * 2 + w * 2, y * h + h - @hex_side_length ]
|
101
105
|
]
|
102
106
|
else
|
103
|
-
w, h = @
|
104
|
-
y0 = @
|
107
|
+
w, h = @tile_width - (@tile_width - @hex_side_length) / 2, @tile_height / 2
|
108
|
+
y0 = @stagger_index_odd ^ x.even? ? h : 0
|
105
109
|
return [
|
106
|
-
[ x * w, y0 + y * h * 2 + h
|
107
|
-
[ x * w + w - @
|
108
|
-
[ x * w + w
|
109
|
-
[ x * w + @
|
110
|
-
[ x * w + w
|
111
|
-
[ x * w + w - @
|
110
|
+
[ x * w, y0 + y * h * 2 + h , y * h ],
|
111
|
+
[ x * w + w - @hex_side_length, y0 + y * h * 2 ],
|
112
|
+
[ x * w + w , y0 + y * h * 2 ],
|
113
|
+
[ x * w + @tile_width , y0 + y * h * 2 + h ],
|
114
|
+
[ x * w + w , y0 + y * h * 2 + h * 2 ],
|
115
|
+
[ x * w + w - @hex_side_length, y0 + y * h * 2 + h * 2 ]
|
112
116
|
]
|
113
117
|
end
|
114
118
|
end
|
115
119
|
|
116
120
|
|
117
121
|
def self.pixel_width(map)
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
+
map.stagger_axis_y ?
|
123
|
+
map.tile_width * (map.tile_width - (map.tile_width - map.hex_side_length) / 2) +
|
124
|
+
(map.tile_width - map.hex_side_length) / 2 :
|
125
|
+
map.tile_width * (map.width + 1) / 2
|
122
126
|
end
|
123
127
|
|
124
128
|
def self.pixel_height(map)
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
+
map.stagger_axis_y ?
|
130
|
+
map.tile_height * (map.height + 1) / 2 :
|
131
|
+
map.tile_height * (map.tile_height - (map.tile_height - map.hex_side_length) / 2) +
|
132
|
+
(map.tile_height - map.hex_side_length) / 2
|
129
133
|
end
|
130
|
-
|
131
134
|
end
|
132
135
|
end
|
133
136
|
end
|