tmx 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown DELETED
@@ -1,92 +0,0 @@
1
- # README
2
- ## WHAT IS THIS
3
-
4
- Eventually, a usable TMX map loader that works with Gosu and doesn't care
5
- whether you're using Chingu or some home-grown game engine of your own
6
- devising.
7
-
8
- ### WHY ON EARTH
9
-
10
- I like Chingu and a TMX loader already exists for it, but it's just not the
11
- right tool for what I want to do. Hopefully others will find this useful as
12
- well. :)
13
-
14
- ### WHAT IS MISSING
15
-
16
- Here's what's not: so far, map data is loaded and layers, object groups and
17
- tile sets are created.
18
-
19
- Validating the XML document to its DTD would be nice too, but I'll be buggered
20
- if I can get Nokogiri to actually load the DTD. There is inadequate or no
21
- documentation on this topic. Probably we'll just have mysterious failures on
22
- unsupported or erroneous TMX files, which is not ideal.
23
-
24
- Possible consideration for the future: move the dependency on Gosu into a
25
- separate, mixable, matchable module. Maybe add explicit Chingu support too.
26
- Handle tile set creation and drawing ops the same way we do object creation:
27
- define a callback hook and let the user take care of it. Awesome.
28
-
29
- Help is welcome, obviously.
30
-
31
- ## INSTALL
32
-
33
- Don't do it yet. The API is so unstable it does not have a half life but a
34
- quarter life.
35
-
36
- ### PREREQUISITES
37
-
38
- * ruby >= 1.9.1 (probably)
39
- * nokogiri
40
-
41
- ## LICENSE
42
-
43
- This software is available under the terms of the MIT license for no better
44
- reason than that this is the license of Gosu itself. This means that you are
45
- technically allowed to use my hard work as part of your proprietary,
46
- commercial product with no obligation to give anything back but credit where
47
- it's due. Use your discretion on that one.
48
-
49
- The full license is reproduced here for posterity:
50
-
51
- > Copyright © 2009–2010 Eris
52
- >
53
- > Permission is hereby granted, free of charge, to any person
54
- > obtaining a copy of this software and associated documentation
55
- > files (the "Software"), to deal in the Software without
56
- > restriction, including without limitation the rights to use,
57
- > copy, modify, merge, publish, distribute, sublicense, and/or sell
58
- > copies of the Software, and to permit persons to whom the
59
- > Software is furnished to do so, subject to the following
60
- > conditions:
61
- >
62
- > The above copyright notice and this permission notice shall be
63
- > included in all copies or substantial portions of the Software.
64
- >
65
- > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
66
- > EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
67
- > OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
68
- > NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
69
- > HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
70
- > WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
71
- > FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
72
- > OTHER DEALINGS IN THE SOFTWARE.
73
-
74
- ## AUTHORS
75
-
76
- * Eris <eris.discord@gmail.com>
77
- * your name here!
78
-
79
- ## SEE ALSO
80
-
81
- * [Gosu][], a 2D game development library for Ruby and C++
82
- * [Chingu][], a higher level game library built on top of Gosu
83
- * [Chipmunk][], a 2D rigid body physics engine in C
84
- * [chipmunk-ffi][], more up-to-date Ruby bindings for Chipmunk
85
- * [Tiled][], a flexible tile map editor and the origin of the TMX format (I
86
- think).
87
-
88
- [chingu]: http://github.com/ippa/chingu
89
- [chipmunk]: http://code.google.com/p/chipmunk-physics
90
- [chipmunk-ffi]: http://github.com/shawn42/chipmunk-ffi
91
- [gosu]: http://libgosu.org
92
- [tiled]: http://mapeditor.org/
data/Rakefile DELETED
@@ -1,11 +0,0 @@
1
- require 'rspec/core/rake_task'
2
- require "bundler/gem_tasks"
3
-
4
- desc 'Default: run specs.'
5
- task :default => :spec
6
-
7
- desc "Run specs"
8
- RSpec::Core::RakeTask.new do |t|
9
- # t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
10
- # Put spec opts in a file named .rspec in root
11
- end
data/data/door.png DELETED
Binary file
data/data/dude.png DELETED
Binary file
data/data/test-tiles.png DELETED
Binary file
data/data/test.tmx DELETED
@@ -1,62 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <map version="1.0" orientation="orthogonal" width="16" height="16" tilewidth="16" tileheight="16">
3
- <properties>
4
- <property name="bg1" value="#402010"/>
5
- <property name="bg2" value="#100000"/>
6
- <property name="fg1" value="#00ff0000"/>
7
- <property name="fg2" value="#10ff0000"/>
8
- <property name="display_name" value="Test Map"/>
9
- </properties>
10
- <tileset firstgid="1" name="debug" tilewidth="16" tileheight="16">
11
- <image source="test-tiles.png"/>
12
- </tileset>
13
- <layer name="background" width="16" height="16" opacity="0.75">
14
- <data encoding="base64" compression="gzip">
15
- H4sIAAAAAAAAA2NgGAXogInK5rGh0aNgFAwWAADxvIrYAAQAAA==
16
- </data>
17
- </layer>
18
- <layer name="obstacle" width="16" height="16">
19
- <data encoding="base64" compression="gzip">
20
- H4sIAAAAAAAAA82T4QqAIAyEZ1Jakb3/27YjB2MMMfvjwSHMfTp1BiIqg47sTOPKk/EXvWeCAnupLmqMDR7aa95RnVQumfye+vV6GM+PfEtgV/b9g5/p/UR4u+jEe3ncSTIx9Ia9J4/H3pvDezUmwwvbw0uN0h+658Stv4t59NIDVh+CwAAEAAA=
21
- </data>
22
- </layer>
23
- <objectgroup name="doors" width="16" height="16">
24
- <object name="door1" type="Door" x="128" y="208" width="16" height="32">
25
- <properties>
26
- <property name="image" value="door.png"/>
27
- <property name="target" value="door2"/>
28
- </properties>
29
- </object>
30
- <object name="door2" type="Door" x="64" y="32" width="16" height="32">
31
- <properties>
32
- <property name="image" value="door.png"/>
33
- <property name="target" value="door1"/>
34
- </properties>
35
- </object>
36
- </objectgroup>
37
- <objectgroup name="objects" width="16" height="16">
38
- <properties>
39
- <property name="what_is_this" value="it's boxes ok"/>
40
- </properties>
41
- <object name="cardboard_box" type="Box" x="160" y="160" width="32" height="32">
42
- <properties>
43
- <property name="image" value="tid:16"/>
44
- </properties>
45
- </object>
46
- <object name="stone_block" type="Box" x="192" y="32" width="32" height="32">
47
- <properties>
48
- <property name="image" value="tid:16"/>
49
- </properties>
50
- </object>
51
- <object name="dude" type="Dude" x="80" y="144" width="16" height="32">
52
- <properties>
53
- <property name="image" value="dude.png"/>
54
- </properties>
55
- </object>
56
- </objectgroup>
57
- <layer name="foreground" width="16" height="16" opacity="0.75">
58
- <data encoding="base64" compression="gzip">
59
- H4sIAAAAAAAAA2NgGAWjYPABRiBmIoAJATYCeCD1EwMo1U8MAADF4i9MAAQAAA==
60
- </data>
61
- </layer>
62
- </map>
@@ -1,114 +0,0 @@
1
- require 'chingu'
2
- require 'tmx'
3
- require 'opengl' # Chingu needs it for retrofy
4
-
5
- class Float
6
- INFINITY = 1.0 / 0.0 unless const_defined? :INFINITY
7
- end
8
-
9
- class Box < Chingu::GameObject
10
- # "It's just a box."
11
-
12
- # (Chingu takes care of everything we need here (it's magic))
13
- end
14
-
15
- class Door < Chingu::GameObject
16
- # this ought to take you somewhere else
17
- end
18
-
19
- class Dude < Chingu::GameObject
20
- # maybe your player logic goes here
21
- end
22
-
23
- class MapState < Chingu::GameState
24
- has_trait :viewport
25
-
26
- def initialize map_name, *rest
27
- super *rest
28
-
29
- # load our map
30
- @map = TMX::Map.new $window, map_name,
31
- :on_object => method(:create_chingu_object)
32
- @banner = Gosu::Image.from_text $window,
33
- @map.properties[:display_name],
34
- 'Helvetica', 24
35
-
36
- $window.caption = 'tmx demo - %s' % @map.properties[:display_name]
37
- end
38
-
39
- def create_chingu_object name, group, properties
40
- map = group.map
41
- obj_class = Kernel.const_get properties[:type] rescue nil
42
-
43
- # assert that the object is a valid type
44
- raise TypeError, "#{properties[:type]} is not a game object" \
45
- unless obj_class.is_a? Class \
46
- and obj_class.ancestors.include? Chingu::BasicGameObject
47
-
48
- # load image
49
- image_name = properties[:image]
50
- image = case image_name
51
- when /^tid:(\d+)$/
52
- # a tile from the map's tile set
53
- map.tile_set[Integer($1)]
54
- when nil
55
- # default image
56
- Gosu::Image['default']
57
- else
58
- # image as named
59
- Gosu::Image[File.join 'data', image_name]
60
- end
61
-
62
- # convert TMX properties to what Chingu is expecting
63
- properties.merge! \
64
- :image => image.retrofy,
65
- :x => properties[:x] + properties[:width] / 2,
66
- :y => properties[:y] + properties[:height] / 2,
67
- :factor_x => properties[:width].to_f / image.width,
68
- :factor_y => properties[:height].to_f / image.height,
69
- :zorder => 1
70
-
71
- # create and return the game object
72
- obj_class.create properties
73
- end
74
-
75
- def update
76
- super
77
- # move the map opposite the mouse pointer, with lag
78
- viewport.x = 0.9 * viewport.x + 0.1 * ($window.mouse_x - $window.width + @map.width / 2)
79
- viewport.y = 0.9 * viewport.y + 0.1 * ($window.mouse_y - $window.height + @map.height / 2)
80
- end
81
-
82
- def draw
83
- super
84
-
85
- fill_gradient \
86
- :from => @map.properties[:bg1],
87
- :to => @map.properties[:bg2],
88
- :zorder => -Float::INFINITY
89
-
90
- # map is not a game object
91
- @map.draw -viewport.x, -viewport.y
92
-
93
- fill_gradient \
94
- :from => @map.properties[:fg1],
95
- :to => @map.properties[:fg2],
96
- :zorder => Float::INFINITY
97
-
98
- @banner.draw 8, 8, Float::INFINITY
99
- end
100
- end
101
-
102
- class MapWindow < Chingu::Window
103
- def initialize
104
- super 400, 200, false
105
-
106
- # global inputs for our demo
107
- self.input = { :escape => :close }
108
-
109
- # load that map
110
- push_game_state MapState.new('data/test.tmx')
111
- end
112
- end
113
-
114
- MapWindow.new.show
data/lib/tmx/coder.rb DELETED
@@ -1,39 +0,0 @@
1
- module Tmx
2
- module Coder
3
- # default coders
4
- autoload :Base64, 'tmx/coder/base64'
5
- autoload :Gzip, 'tmx/coder/gzip'
6
-
7
- def self.encode str, *encodings
8
- encodings.reject(&:nil?).reduce(str) do |data, encoding|
9
- find_coder(encoding).encode(data)
10
- end
11
- end # encode
12
-
13
- def self.decode str, *encodings
14
- encodings.reject(&:nil?).reverse.reduce(str) do |data, encoding|
15
- find_coder(encoding).decode(data)
16
- end
17
- end # decode
18
-
19
- def self.find_coder name
20
- const_name = name.to_s.capitalize.gsub /(?:\b|_)([a-z])/, &:upcase
21
- if const_defined? const_name
22
- const_get const_name
23
- else
24
- raise NameError, "unknown coder #{name}"
25
- end
26
- end # find_coder
27
-
28
- def self.register_coder name, mod
29
- const_name = name.to_s.capitalize.gsub /(?:\b|_)([a-z])/, &:upcase
30
- if not const_defined? const_name
31
- const_set const_name, mod
32
- else
33
- raise NameError, "coder #{name} already registered"
34
- end
35
- end # register_coder
36
-
37
- end # Coder
38
-
39
- end
@@ -1,13 +0,0 @@
1
- module Tmx
2
- module Coder
3
- module Base64
4
- def self.encode str
5
- ::Base64.strict_encode64 str
6
- end
7
-
8
- def self.decode str
9
- ::Base64.decode64 str
10
- end
11
- end # Base64
12
- end
13
- end
@@ -1,21 +0,0 @@
1
- module Tmx
2
- module Coder
3
- module Gzip
4
- def self.encode str
5
- buffer = String.new
6
- writer = Zlib::GzipWriter.new(StringIO.new(buffer))
7
- writer << str
8
- writer.close
9
- buffer
10
- end
11
-
12
- def self.decode str
13
- reader = Zlib::GzipReader.new(StringIO.new(str))
14
- output = reader.read
15
- reader.close
16
- output
17
- end
18
-
19
- end # Gzip
20
- end
21
- end
@@ -1,83 +0,0 @@
1
- module Tmx
2
- # WARNING this is currently deprecated and not actually used
3
- class Map::TileCache
4
- def initialize map
5
- @map = WeakRef.new map
6
-
7
- @tile_cache = []
8
- @map_cache = []
9
-
10
- @layer_count = 0
11
-
12
- @columns, @rows = 0, 0
13
- @tile_width, @tile_height = 0, 0
14
- end # initialize
15
-
16
- def rebuild!
17
- rebuild_tile_set!
18
- rebuild_map!
19
- end
20
-
21
- def rebuild_tile_set!
22
- raise RuntimeError, "tile set information has been discarded" if @map.tile_sets.nil?
23
-
24
- @tile_cache.clear
25
- @map.tile_sets.each_value do |tile_set|
26
- @tile_cache[tile_set.range] = tile_set.tiles
27
- end
28
- end
29
-
30
- def rebuild_map!
31
- raise RuntimeError, "layer information has been discarded" if @map.layers.nil?
32
-
33
- @map_cache.clear
34
-
35
- @layer_count = @map.layers.count
36
-
37
- @columns, @rows = @map.columns, @map.rows
38
- @tile_width, @tile_height = @map.tile_width, @map.tile_height
39
-
40
- @map.layers.each_value.with_index do |layer, layer_index|
41
- (0...@rows).each do |y|
42
- (0...@columns).each do |x|
43
- index = _tile_index layer_index, x, y
44
- tile_id = layer[x, y]
45
- @map_cache[index] = @tile_cache[tile_id]
46
- end
47
- end
48
- end
49
- end # rebuild_map!
50
-
51
- def draw x_off, y_off, z_off, x_range, y_range
52
- x_range = [x_range.min, 0].max .. [x_range.max, @columns - 1].min
53
- y_range = [y_range.min, 0].max .. [y_range.max, @rows - 1].min
54
-
55
- y_range.each do |y|
56
- tile_y_off = y_off + y * @tile_height
57
-
58
- x_range.each do |x|
59
- tile_x_off = x_off + x * @tile_width
60
-
61
- range = _tile_range x, y
62
- @map_cache[range].each.with_index do |image, z|
63
- next if image.nil?
64
- image.draw tile_x_off, tile_y_off, z_off + z
65
- end
66
-
67
- end
68
- end
69
- end # draw
70
-
71
- protected
72
-
73
- def _tile_index layer_index, x, y
74
- y * @columns * @layer_count + x * @layer_count + layer_index
75
- end
76
-
77
- def _tile_range x, y
78
- first = _tile_index 0, x, y
79
- first...(first + @layer_count)
80
- end
81
-
82
- end
83
- end