dxruby_tiled 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []