airsprite 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.
- data/.gemtest +0 -0
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +26 -0
- data/LICENSE +20 -0
- data/README.md +55 -0
- data/Rakefile +19 -0
- data/airsprite.gemspec +26 -0
- data/bin/airsprite +8 -0
- data/lib/airsprite.rb +8 -0
- data/lib/airsprite/base.rb +279 -0
- data/lib/airsprite/config.rb +34 -0
- data/lib/airsprite/version.rb +3 -0
- data/spec/base_spec.rb +46 -0
- data/spec/spec_helper.rb +11 -0
- metadata +98 -0
data/.gemtest
ADDED
File without changes
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.9.2@gems
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
bbcoder (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.1.2)
|
10
|
+
rr (1.0.2)
|
11
|
+
rspec (2.4.0)
|
12
|
+
rspec-core (~> 2.4.0)
|
13
|
+
rspec-expectations (~> 2.4.0)
|
14
|
+
rspec-mocks (~> 2.4.0)
|
15
|
+
rspec-core (2.4.0)
|
16
|
+
rspec-expectations (2.4.0)
|
17
|
+
diff-lcs (~> 1.1.2)
|
18
|
+
rspec-mocks (2.4.0)
|
19
|
+
|
20
|
+
PLATFORMS
|
21
|
+
ruby
|
22
|
+
|
23
|
+
DEPENDENCIES
|
24
|
+
bbcoder!
|
25
|
+
rr
|
26
|
+
rspec
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 John "asceth" Long
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
'Software'), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
17
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
18
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
19
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
20
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
Overview
|
2
|
+
--------
|
3
|
+
airsprite makes single png spritesheets from a directory struture and outputs parseable itx files for the http://www.madewithmarmalade.com (Marmalade SDK).
|
4
|
+
|
5
|
+
|
6
|
+
Give a directory as an argument. Each folder underneath that directory is considered its own spritesheet.
|
7
|
+
|
8
|
+
Each png file underneath the spritesheet folder is a sprite in of itself (single frame) and constructs a default animation, default frame of that sprite. If a folder is encounted a sprite is created named after the folder.
|
9
|
+
|
10
|
+
Inside the sprite folder, png files are considered animations with single frames with the name of the png file. A folder is considered an animation called the name of the folder and each png file underneath the animation is a series of frames, sorted alphabetically.
|
11
|
+
|
12
|
+
Examples:
|
13
|
+
|
14
|
+
path/sprite.png
|
15
|
+
/foo/bar.png
|
16
|
+
|
17
|
+
* creates a sprite called "sprite" with the "default" animation and a single frame called "idle".
|
18
|
+
* creates a sprite called "foo" with the "bar" animation and a single frame called "bar".
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
path/cranky/idle/0.png
|
23
|
+
idle/1.png
|
24
|
+
|
25
|
+
path/cranky/run/0.png
|
26
|
+
run/1.png
|
27
|
+
|
28
|
+
* creates a sprite named "cranky" with the "idle" and "run" animations each with two frames called "0" and "1".
|
29
|
+
|
30
|
+
|
31
|
+
Usage
|
32
|
+
--------
|
33
|
+
|
34
|
+
airsprite path/to/dir
|
35
|
+
|
36
|
+
Install
|
37
|
+
-------
|
38
|
+
|
39
|
+
gem install airsprite
|
40
|
+
|
41
|
+
|
42
|
+
Deps
|
43
|
+
-------
|
44
|
+
|
45
|
+
gem install rmagick
|
46
|
+
|
47
|
+
* used to create the spritesheet png
|
48
|
+
|
49
|
+
|
50
|
+
Author
|
51
|
+
------
|
52
|
+
|
53
|
+
Original author: John "asceth" Long
|
54
|
+
|
55
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "bundler"
|
2
|
+
Bundler.setup
|
3
|
+
|
4
|
+
require "rspec"
|
5
|
+
require "rspec/core/rake_task"
|
6
|
+
|
7
|
+
Rspec::Core::RakeTask.new(:spec)
|
8
|
+
|
9
|
+
gemspec = eval(File.read(File.join(Dir.pwd, "bbcoder.gemspec")))
|
10
|
+
|
11
|
+
task :build => "#{gemspec.full_name}.gem"
|
12
|
+
|
13
|
+
task :test => :spec
|
14
|
+
|
15
|
+
file "#{gemspec.full_name}.gem" => gemspec.files + ["bbcoder.gemspec"] do
|
16
|
+
system "gem build bbcoder.gemspec"
|
17
|
+
system "gem install bbcoder-#{BBCoder::VERSION}.gem"
|
18
|
+
end
|
19
|
+
|
data/airsprite.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "airsprite/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "airsprite"
|
6
|
+
s.version = Airsprite::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["John 'asceth' Long"]
|
9
|
+
s.email = ["machinist@asceth.com"]
|
10
|
+
s.homepage = "http://github.com/asceth/airsprite"
|
11
|
+
s.summary = "Marmalade SDK Sprite Sheet generator"
|
12
|
+
s.description = "A gem for creating sprite sheets for the Marmalade SDK"
|
13
|
+
|
14
|
+
s.rubyforge_project = "airsprite"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency 'rmagick'
|
22
|
+
|
23
|
+
s.add_development_dependency 'rspec'
|
24
|
+
s.add_development_dependency 'rr'
|
25
|
+
end
|
26
|
+
|
data/bin/airsprite
ADDED
data/lib/airsprite.rb
ADDED
@@ -0,0 +1,279 @@
|
|
1
|
+
module Airsprite
|
2
|
+
module Base
|
3
|
+
def run
|
4
|
+
Airsprite::Config.parse_config_file
|
5
|
+
|
6
|
+
# each directory underneath Airsprite::Config.path is a sheet
|
7
|
+
Dir["#{Airsprite::Config.path}/*/"].each do |dir|
|
8
|
+
spritesheet = SpriteSheet.new(dir.split('/').last, dir)
|
9
|
+
spritesheet.place
|
10
|
+
spritesheet.output
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def twos
|
15
|
+
[
|
16
|
+
2,
|
17
|
+
4,
|
18
|
+
8,
|
19
|
+
16,
|
20
|
+
32,
|
21
|
+
64,
|
22
|
+
128,
|
23
|
+
256,
|
24
|
+
512,
|
25
|
+
1024,
|
26
|
+
2048
|
27
|
+
]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
extend Base
|
31
|
+
end
|
32
|
+
|
33
|
+
module Airsprite
|
34
|
+
class SpriteSheet
|
35
|
+
attr_accessor :name, :path, :sprites
|
36
|
+
attr_accessor :surface, :max_side, :width, :height
|
37
|
+
|
38
|
+
def initialize(name, directory)
|
39
|
+
self.name = name
|
40
|
+
self.path = directory
|
41
|
+
self.sprites = []
|
42
|
+
|
43
|
+
Dir["#{self.path}*/"].each do |dir|
|
44
|
+
self.sprites += [Sprite.new(self, dir.split('/').last, dir)]
|
45
|
+
end
|
46
|
+
|
47
|
+
Dir["#{self.path}*.png"].each do |file|
|
48
|
+
self.sprites += [Sprite.new(self, File.basename(file, '.png'), file)]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_s
|
53
|
+
<<-EOS
|
54
|
+
SpriteSheet
|
55
|
+
{
|
56
|
+
name "#{name}"
|
57
|
+
|
58
|
+
#{sprites.map(&:to_s).join}
|
59
|
+
}
|
60
|
+
EOS
|
61
|
+
end
|
62
|
+
|
63
|
+
def place
|
64
|
+
# biggest first
|
65
|
+
frames = sprites.map(&:animations).flatten.map(&:frames).flatten.sort_by(&:area).reverse
|
66
|
+
|
67
|
+
# figure out lowest possible power of 2
|
68
|
+
@surface = frames.map(&:area).inject(0) {|sum, area| sum + area}
|
69
|
+
@max_side = [frames.map(&:width), frames.map(&:height)].flatten.sort.last
|
70
|
+
@width = 0
|
71
|
+
@height = 0
|
72
|
+
|
73
|
+
STDERR.puts "surface needed: #{@surface}"
|
74
|
+
Airsprite.twos.map do |power_of_two|
|
75
|
+
# lowest two must be >= biggest sprite size
|
76
|
+
next unless power_of_two >= @max_side
|
77
|
+
|
78
|
+
if (@surface / power_of_two) <= power_of_two
|
79
|
+
if (power_of_two * Airsprite.twos[Airsprite.twos.index(power_of_two) - 1]) > @surface
|
80
|
+
@width = power_of_two
|
81
|
+
@height = Airsprite.twos[Airsprite.twos.index(power_of_two) - 1]
|
82
|
+
else
|
83
|
+
@width = power_of_two
|
84
|
+
@height = power_of_two
|
85
|
+
end
|
86
|
+
STDERR.puts "surface generated: #{@width * @height}"
|
87
|
+
break
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# set these sprite frames up!
|
92
|
+
rects = [Rect.new(@width, @height, 0, 0)]
|
93
|
+
|
94
|
+
# place frames
|
95
|
+
frames.map do |frame|
|
96
|
+
# find first square that can contain this sprite
|
97
|
+
raise "No rects left to fill" if rects.empty?
|
98
|
+
|
99
|
+
STDERR.puts "\n\n"
|
100
|
+
STDERR.puts frame.to_short_s
|
101
|
+
STDERR.puts rects.map(&:to_s).join("\n")
|
102
|
+
rects.map do |rect|
|
103
|
+
if rect.area >= frame.area && rect.width >= frame.width && rect.height >= frame.height
|
104
|
+
frame.x = rect.x
|
105
|
+
frame.y = rect.y
|
106
|
+
|
107
|
+
# delete rect from list
|
108
|
+
rects.delete(rect)
|
109
|
+
unless rect.height == frame.height && rect.width == frame.width
|
110
|
+
if rect.height == frame.height
|
111
|
+
rects << Rect.new(rect.width - frame.width, rect.height, rect.x + frame.width, rect.y)
|
112
|
+
elsif rect.width == frame.width
|
113
|
+
rects << Rect.new(rect.width, rect.height - frame.height, rect.x, rect.y + frame.height)
|
114
|
+
else
|
115
|
+
rects << Rect.new(frame.width, rect.height - frame.height, rect.x, rect.y + frame.height)
|
116
|
+
rects << Rect.new(rect.width - frame.width, rect.height, rect.x + frame.width, rect.y)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
break
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def output
|
126
|
+
frames = sprites.map(&:animations).flatten.map(&:frames).flatten.sort_by(&:area)
|
127
|
+
|
128
|
+
draw = Magick::Draw.new
|
129
|
+
image = Magick::Image.new(@width, @height)
|
130
|
+
draw.matte(0, 0, Magick::ResetMethod)
|
131
|
+
|
132
|
+
frames.map do |frame|
|
133
|
+
next if frame.x.nil? || frame.y.nil?
|
134
|
+
#draw.composite(frame.data, frame.x, frame.y, Magick::CopyCompositeOp)
|
135
|
+
draw.composite(frame.x, frame.y, frame.width, frame.height, frame.data, Magick::CopyCompositeOp)
|
136
|
+
#image.store_pixels(frame.x, frame.y, frame.width, frame.height, frame.data.get_pixels(0, 0, frame.width, frame.height))
|
137
|
+
end
|
138
|
+
STDERR.puts "writing to #{self.path[0..-2]}.itx"
|
139
|
+
File.open("#{self.path[0..-2]}.itx", 'w') {|f| f.write(self.to_s)}
|
140
|
+
STDERR.puts "writing to #{self.path[0..-2]}.png"
|
141
|
+
image.set_channel_depth(Magick::AllChannels, 8)
|
142
|
+
draw.draw(image)
|
143
|
+
image.write("#{self.path[0..-2]}.png")
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
class Rect
|
148
|
+
attr_accessor :width, :height, :x, :y
|
149
|
+
|
150
|
+
def initialize(width, height, offset_x, offset_y)
|
151
|
+
@width = width
|
152
|
+
@height = height
|
153
|
+
@x = offset_x
|
154
|
+
@y = offset_y
|
155
|
+
end
|
156
|
+
|
157
|
+
def area
|
158
|
+
width * height
|
159
|
+
end
|
160
|
+
|
161
|
+
def to_s
|
162
|
+
"rect: #{width} x #{height} = #{area} (#{x}, #{y})"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
class Sprite
|
167
|
+
attr_accessor :sheet, :name
|
168
|
+
attr_accessor :animations
|
169
|
+
|
170
|
+
def initialize(sheet, name, path)
|
171
|
+
@name = name
|
172
|
+
@animations = []
|
173
|
+
|
174
|
+
if File.directory?(path)
|
175
|
+
Dir["#{path}*/"].each do |dir|
|
176
|
+
@animations += [SpriteAnimation.new(dir.split('/').last, dir)]
|
177
|
+
end
|
178
|
+
else
|
179
|
+
@animations += [SpriteAnimation.new('idle', path)]
|
180
|
+
end
|
181
|
+
|
182
|
+
if @animations.map(&:frames).flatten.map(&:width).uniq.size > 1
|
183
|
+
raise "Widths of frames for a sprite must be the same width"
|
184
|
+
end
|
185
|
+
|
186
|
+
if @animations.map(&:frames).flatten.map(&:height).uniq.size > 1
|
187
|
+
raise "Widths of frames for a sprite must be the same height"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def to_s
|
192
|
+
<<-EOS
|
193
|
+
Sprite
|
194
|
+
{
|
195
|
+
name "#{name}"
|
196
|
+
|
197
|
+
#{animations.map(&:to_s).join}
|
198
|
+
}
|
199
|
+
EOS
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
class SpriteAnimation
|
204
|
+
attr_accessor :name
|
205
|
+
attr_accessor :frames
|
206
|
+
|
207
|
+
def initialize(name, path)
|
208
|
+
@name = name
|
209
|
+
@frames = []
|
210
|
+
|
211
|
+
if File.directory?(path)
|
212
|
+
Dir["#{path}*.png"].each do |file|
|
213
|
+
@frames << SpriteFrame.new(File.basename(file, '.png'), file)
|
214
|
+
end
|
215
|
+
else
|
216
|
+
@frames << SpriteFrame.new(File.basename(path, '.png'), path)
|
217
|
+
end
|
218
|
+
|
219
|
+
@frames.sort_by(&:name).inject(0) do |position, frame|
|
220
|
+
frame.position = position
|
221
|
+
position + 1
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def to_s
|
226
|
+
<<-EOS
|
227
|
+
SpriteAnimation
|
228
|
+
{
|
229
|
+
name "#{name}"
|
230
|
+
|
231
|
+
#{frames.sort_by(&:position).map(&:to_s).join}
|
232
|
+
}
|
233
|
+
EOS
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
class SpriteFrame
|
238
|
+
attr_accessor :name, :data, :position, :speed
|
239
|
+
attr_accessor :width, :height, :area, :x, :y
|
240
|
+
|
241
|
+
def initialize(name, path)
|
242
|
+
split_name = name.split('-')
|
243
|
+
|
244
|
+
if split_name.size == 1
|
245
|
+
@name = split_name[0]
|
246
|
+
@speed = 0
|
247
|
+
else
|
248
|
+
@name = split_name.shift
|
249
|
+
@speed = split_name.join.to_i
|
250
|
+
end
|
251
|
+
|
252
|
+
@data = Magick::Image::read(path).first
|
253
|
+
@width = @data.columns.to_i
|
254
|
+
@height = @data.rows.to_i
|
255
|
+
@area = @width * @height
|
256
|
+
end
|
257
|
+
|
258
|
+
def to_s
|
259
|
+
<<-EOS
|
260
|
+
SpriteFrame
|
261
|
+
{
|
262
|
+
name "#{name}"
|
263
|
+
speed #{speed}
|
264
|
+
position #{position}
|
265
|
+
width #{width}
|
266
|
+
height #{height}
|
267
|
+
area #{area}
|
268
|
+
x #{x}
|
269
|
+
y #{y}
|
270
|
+
}
|
271
|
+
EOS
|
272
|
+
end
|
273
|
+
|
274
|
+
def to_short_s
|
275
|
+
"frame: #{width} x #{height} = #{area} (#{x}, #{y})"
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Airsprite
|
2
|
+
module Config
|
3
|
+
|
4
|
+
CONFIG_FILENAME="airsprite.yml"
|
5
|
+
|
6
|
+
|
7
|
+
module ModuleMethods
|
8
|
+
def path=(value)
|
9
|
+
@@path = value
|
10
|
+
end
|
11
|
+
def path
|
12
|
+
@@path
|
13
|
+
end
|
14
|
+
|
15
|
+
def scales=(value)
|
16
|
+
@@scales = value
|
17
|
+
end
|
18
|
+
def scales
|
19
|
+
@@scales
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_config_file
|
23
|
+
self.path = Dir.pwd
|
24
|
+
|
25
|
+
if File.exists?(CONFIG_FILENAME)
|
26
|
+
YAML.load(File.read(CONFIG_FILENAME)).each {|(name, value)| send "#{name}=", value }
|
27
|
+
else
|
28
|
+
self.scales = [1.0]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
extend ModuleMethods
|
33
|
+
end
|
34
|
+
end
|
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BBCoder do
|
4
|
+
|
5
|
+
subject { BBCoder.new("[p]Text and now [b]bolded.[/b][/p]") }
|
6
|
+
|
7
|
+
context "#configuration" do
|
8
|
+
it "should return the same object for multiple calls" do
|
9
|
+
BBCoder.configuration.should == BBCoder.configuration
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "#buffer" do
|
14
|
+
it "should return the same object for multiple calls" do
|
15
|
+
subject.buffer.should == subject.buffer
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "#configure" do
|
20
|
+
it "should fail without a block" do
|
21
|
+
lambda { BBCoder.configure }.should raise_error
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should instance_eval the block onto configuration" do
|
25
|
+
block = Proc.new { tag :p }
|
26
|
+
mock(BBCoder).configuration.stub!.instance_eval(&block)
|
27
|
+
BBCoder.configure(&block)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "#initialize" do
|
32
|
+
it "should split tags up properly" do
|
33
|
+
subject.raw.should == ["[p]", "Text and now ", "[b]", "bolded.", "[/b]", "[/p]"]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "#parse" do
|
38
|
+
it "should loop through raw elements and join the buffer" do
|
39
|
+
mock(subject).raw.stub!.each {nil}
|
40
|
+
mock(subject).buffer.stub!.join {"output"}
|
41
|
+
|
42
|
+
subject.parse
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: airsprite
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- John 'asceth' Long
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-07 00:00:00.000000000 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rmagick
|
17
|
+
requirement: &17197820 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *17197820
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rspec
|
28
|
+
requirement: &17197340 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *17197340
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rr
|
39
|
+
requirement: &17196800 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *17196800
|
48
|
+
description: A gem for creating sprite sheets for the Marmalade SDK
|
49
|
+
email:
|
50
|
+
- machinist@asceth.com
|
51
|
+
executables:
|
52
|
+
- airsprite
|
53
|
+
extensions: []
|
54
|
+
extra_rdoc_files: []
|
55
|
+
files:
|
56
|
+
- .gemtest
|
57
|
+
- .gitignore
|
58
|
+
- .rspec
|
59
|
+
- .rvmrc
|
60
|
+
- Gemfile
|
61
|
+
- Gemfile.lock
|
62
|
+
- LICENSE
|
63
|
+
- README.md
|
64
|
+
- Rakefile
|
65
|
+
- airsprite.gemspec
|
66
|
+
- bin/airsprite
|
67
|
+
- lib/airsprite.rb
|
68
|
+
- lib/airsprite/base.rb
|
69
|
+
- lib/airsprite/config.rb
|
70
|
+
- lib/airsprite/version.rb
|
71
|
+
- spec/base_spec.rb
|
72
|
+
- spec/spec_helper.rb
|
73
|
+
has_rdoc: true
|
74
|
+
homepage: http://github.com/asceth/airsprite
|
75
|
+
licenses: []
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubyforge_project: airsprite
|
94
|
+
rubygems_version: 1.6.2
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: Marmalade SDK Sprite Sheet generator
|
98
|
+
test_files: []
|