nuri_game-tmx_reader 0.1.1

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
+ SHA256:
3
+ metadata.gz: bafedf74686bf3db56b4075b3ee9dba4474f255cc4fe3d08c46c5bd6d2dd588a
4
+ data.tar.gz: 55d792e678149e79724ce7e70313be8a0be4c400d603c501db60d756bd0da5de
5
+ SHA512:
6
+ metadata.gz: 01ae0b8d7d024a892859268448299f17e2a597a8de4466f6057b44ac668a80c5489d3d77016f1db3d562b8cd92a939d37b9a18c271466a2523af36d1dc447cb1
7
+ data.tar.gz: 10d5816b916b005a63130674539a7eb7b04c1db9e5cc2eec7db60a17e60f52bb8a53656842733a543ba56cf8ac54926de4bbadb50a3df6d29730832f660669a4
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in nuri_game-tmx_reader.gemspec
6
+ gemspec
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # NuriGame::TmxReader
2
+
3
+ TMXReader that convert .tmx files to a ruby object
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'nuri_game-tmx_reader'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install nuri_game-tmx_reader
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ require 'nuri_game/tmx_reader'
25
+
26
+ # [...]
27
+
28
+ map = NuriGame::TmxReader.new('mapname.tmx')
29
+ # access here to map.layers, map.tilesets, map.width, map.height, map.tilewidth or map.tileheight
30
+ ```
31
+
32
+ ## Development
33
+
34
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
35
+
36
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
37
+
38
+ ## Contributing
39
+
40
+ Bug reports and pull requests are welcome at https://gitlab.com/NuriYuri/nuri_game-tmx_reader.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "nuri_game/tmx_reader"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,5 @@
1
+ module NuriGame
2
+ class TmxReader
3
+ VERSION = "0.1.1"
4
+ end
5
+ end
@@ -0,0 +1,164 @@
1
+ require 'nuri_game/tmx_reader/version'
2
+ require 'rexml/document'
3
+ require 'zlib'
4
+ require 'base64'
5
+
6
+ # NuriGame namespace containing all the utility made by Nuri Yuri in order to make Games.
7
+ module NuriGame
8
+ # class that converts TMX file to Ruby object
9
+ class TmxReader
10
+
11
+ # Definition of a tileset
12
+ Tileset = Struct.new(:firstgid, :source)
13
+
14
+ # Constant holding the list of map information
15
+ MAP_INFOS = ['width', 'height', 'tilewidth', 'tileheight'].freeze
16
+
17
+ # @return [Integer] width of the map
18
+ attr_reader :width
19
+
20
+ # @return [Integer] height of the map
21
+ attr_reader :height
22
+
23
+ # @return [Integer] width of a tile on the map
24
+ attr_reader :tilewidth
25
+
26
+ # @return [Integer] height of a tile on the map
27
+ attr_reader :tileheight
28
+
29
+ # @return [Array<Tileset>] tilesets of the map
30
+ attr_reader :tilesets
31
+
32
+ # @return [Hash{String => Array<Integer>}] layers of the map (name => grid)
33
+ attr_reader :layers
34
+
35
+ # Create a new TmxReader
36
+ # @param filename [String] name of the tmx file to read
37
+ def initialize(filename)
38
+ contents = File.read(filename).force_encoding(Encoding::UTF_8)
39
+ map = REXML::Document.new(contents).root
40
+ @tilesets = []
41
+ @layers = {}
42
+ validate_map(map)
43
+ load_map_infos(map)
44
+ load_tilesets(map)
45
+ load_layers(map)
46
+ end
47
+
48
+ private
49
+
50
+ # Validate the map informations
51
+ # @parma map [REXML::Element]
52
+ def validate_map(map)
53
+ raise 'Invalid TMX data, root element is not a <map>' if map.name != 'map'
54
+ raise 'Invalid TMX orientation, expect orthogonal' if xml_value(map, 'orientation') != 'orthogonal'
55
+ raise 'Invalid TMX renderorder, expect left-up' if xml_value(map, 'renderorder') != 'left-up'
56
+ raise 'Invalid TMX map format, should not be infinite' if xml_value(map, 'infinite').to_i != 0
57
+ end
58
+
59
+ # Load the map informations
60
+ # @param map [REXML::Element]
61
+ def load_map_infos(map)
62
+ MAP_INFOS.each { |name| instance_variable_set(:"@#{name}", xml_value(map, name).to_i) }
63
+ end
64
+
65
+ # Load the map tilesets
66
+ # @param map [REXML::Element]
67
+ def load_tilesets(map)
68
+ tilesets = @tilesets
69
+ map.each_element('tileset') do |tileset|
70
+ tilesets << Tileset.new(xml_value(tileset, 'firstgid').to_i, xml_value(tileset, 'source').to_s)
71
+ end
72
+ end
73
+
74
+ # Load the map layers (flattened)
75
+ # @param map [REXML::Element]
76
+ def load_layers(map)
77
+ map.each_element_with_attribute('name') do |layer|
78
+ if layer.name == 'group'
79
+ load_layer_group(layer, xml_value(layer, 'name'))
80
+ elsif layer.name == 'layer'
81
+ @layers[xml_value(layer, 'name')] = load_layer(layer)
82
+ end
83
+ end
84
+ end
85
+
86
+ # Load the layer from a group
87
+ # @param group [REXML::Element]
88
+ # @param groupname [String]
89
+ def load_layer_group(group, groupname)
90
+ group.each_element do |layer|
91
+ if layer.name == 'group'
92
+ load_layer_group(layer, File.join(groupname, xml_value(layer, 'name')))
93
+ elsif layer.name == 'layer'
94
+ name = File.join(groupname, xml_value(layer, 'name'))
95
+ @layers[name] = load_layer(layer)
96
+ end
97
+ end
98
+ end
99
+
100
+ # Load the layer data
101
+ # @param layer [REXML::Element]
102
+ def load_layer(layer)
103
+ data = get_layer_data(layer)
104
+ # Perform stuff if there's offset & co (but shouldn't happen since we don't allow infinite maps)
105
+ return data
106
+ end
107
+
108
+ # Get the layer data
109
+ # @source https://github.com/shawn42/tmx/blob/master/lib/tmx/parsers/tmx-rexml.rb
110
+ # @param layer [REXML::Element]
111
+ def get_layer_data(layer)
112
+ data = REXML::XPath.first(layer, 'data')
113
+ enc = xml_value(data, 'encoding')
114
+ comp = xml_value(data, 'compression')
115
+ layer_data = REXML::XPath.first(layer, 'data').text.strip
116
+ layer_data = Base64.decode64(layer_data) if enc == 'base64'
117
+
118
+ case comp
119
+ when 'zlib'
120
+ return unpack_data(zlib_decompress(layer_data))
121
+ when 'gzip'
122
+ return unpack_data(gzip_decompress(layer_data))
123
+ else
124
+ case enc
125
+ when 'base64'
126
+ return unpack_data(layer_data)
127
+ when 'csv'
128
+ return layer_data.split(',').collect(&:to_i)
129
+ end
130
+ end
131
+ REXML::XPath.match(layer, "data/tile").map { |tile| tile.attributes["gid"].to_i }
132
+ end
133
+
134
+ # Decompress using Zlib
135
+ # @param data [String]
136
+ # @return [String]
137
+ def zlib_decompress(data)
138
+ Zlib::Inflate.inflate(data)
139
+ end
140
+
141
+ # Decompress using Gzip
142
+ # @param data [String]
143
+ # @return [String]
144
+ def gzip_decompress(data)
145
+ Zlib::GzipReader.new(StringIO.new(data)).read
146
+ end
147
+
148
+ # Convert data into valid Ruby Data
149
+ # @param data [String]
150
+ # @return [Array<Integer>]
151
+ def unpack_data(data)
152
+ data.unpack('V*')
153
+ end
154
+
155
+ # Return an xml value
156
+ # @param element [REXML::Element]
157
+ # @param value_name [String]
158
+ # @return [String, nil] nil means no value
159
+ def xml_value(element, value_name)
160
+ val = element.attribute(value_name)
161
+ return val ? val.value : nil
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,27 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "nuri_game/tmx_reader/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "nuri_game-tmx_reader"
8
+ spec.version = NuriGame::TmxReader::VERSION
9
+ spec.authors = ["Nuri Yuri"]
10
+ spec.email = ["hostmaster@pokemonworkshop.com"]
11
+
12
+ spec.summary = %q{TMXReader that convert .tmx files to a ruby object}
13
+ spec.homepage = "https://gitlab.com/NuriYuri/nuri_game-tmx_reader"
14
+
15
+ # Specify which files should be added to the gem when it is released.
16
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
17
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+ spec.required_ruby_version = '>= 2.5.0'
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.16"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nuri_game-tmx_reader
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Nuri Yuri
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-09-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description:
42
+ email:
43
+ - hostmaster@pokemonworkshop.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - README.md
51
+ - Rakefile
52
+ - bin/console
53
+ - bin/setup
54
+ - lib/nuri_game/tmx_reader.rb
55
+ - lib/nuri_game/tmx_reader/version.rb
56
+ - nuri_game-tmx_reader.gemspec
57
+ homepage: https://gitlab.com/NuriYuri/nuri_game-tmx_reader
58
+ licenses: []
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 2.5.0
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 2.7.3
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: TMXReader that convert .tmx files to a ruby object
80
+ test_files: []