rmagick-sprite 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +21 -0
- data/README.md +66 -0
- data/Rakefile +32 -0
- data/VERSION +1 -0
- data/lib/sprite/action.rb +69 -0
- data/lib/sprite/frame.rb +37 -0
- data/lib/sprite.rb +108 -0
- data/rmagick-sprite.gemspec +35 -0
- metadata +106 -0
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use --create ruby-1.9.3@rmagick-sprite
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rmagick-sprite (0.0.3)
|
5
|
+
dsl (~> 0.2.2)
|
6
|
+
rmagick (~> 2.13.1)
|
7
|
+
version (~> 1.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
dsl (0.2.2)
|
13
|
+
version (~> 1.0.0)
|
14
|
+
rmagick (2.13.1)
|
15
|
+
version (1.0.0)
|
16
|
+
|
17
|
+
PLATFORMS
|
18
|
+
ruby
|
19
|
+
|
20
|
+
DEPENDENCIES
|
21
|
+
rmagick-sprite!
|
data/README.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# RMagick-Sprite
|
2
|
+
|
3
|
+
## Example
|
4
|
+
|
5
|
+
In this example, I have one character printed on one spritesheet with only one line of
|
6
|
+
evenly spaced/sized sprites.
|
7
|
+
|
8
|
+
Here it is:
|
9
|
+
|
10
|
+
[Example Spritesheet](http://cl.ly/image/2k320Z2X231T)
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
sprite = Sprite.new do
|
14
|
+
filename 'foo/bar/character_spritesheet.png'
|
15
|
+
|
16
|
+
# The default action that the Sprite will use
|
17
|
+
default_action :standing
|
18
|
+
|
19
|
+
# These options will be reverse-merged into each frame
|
20
|
+
default_frame_options width: 16, height: 25, y: 0
|
21
|
+
|
22
|
+
standing do
|
23
|
+
frame x: 16 * 1 # Frame 1
|
24
|
+
# x: 0, y: 0 is the top-left corner..
|
25
|
+
# I'm lazy, so I'm just taking the default_frame_options width and multiplying it by the
|
26
|
+
# frame index to calculate the x coordinate.
|
27
|
+
end
|
28
|
+
|
29
|
+
walking do
|
30
|
+
frame x: 16 * 0 # Frame 1
|
31
|
+
frame x: 16 * 1 # Frame 2
|
32
|
+
frame x: 16 * 2 # Frame 3
|
33
|
+
frame x: 16 * 1 # Frame 4
|
34
|
+
end
|
35
|
+
|
36
|
+
running do
|
37
|
+
frame x: 16 * 3 # Frame 1
|
38
|
+
frame x: 16 * 4 # Frame 2
|
39
|
+
frame x: 16 * 5 # Frame 3
|
40
|
+
frame x: 16 * 4 # Frame 4
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Standing only has one frame so next_image will loop over the same frame
|
45
|
+
p sprite.next_image # => Second Image (Magick::Image) same as: sprite.next_frame.image
|
46
|
+
p sprite.next_image # => Second Image
|
47
|
+
|
48
|
+
sprite.action = :walking
|
49
|
+
|
50
|
+
# Here, we loop through the walking animation.. pump these images right into Gosu or your favorite gaming library
|
51
|
+
p sprite.next_image # => First Image
|
52
|
+
p sprite.next_image # => Second Image
|
53
|
+
p sprite.next_image # => Third Image
|
54
|
+
p sprite.next_image # => Second Image
|
55
|
+
p sprite.next_image # => First Image
|
56
|
+
|
57
|
+
# Save each action's frame as a separate image
|
58
|
+
sprite.actions.each do |action_name, action|
|
59
|
+
action.frames.each_with_index do |frame, index|
|
60
|
+
frame.image.write "foo/bar/#{action_name}_#{index}.png"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Saving an action as a gif (note: looks wonky with transparent backgrounds)
|
65
|
+
sprite.actions[:running].write 'foo/bar/running.gif'
|
66
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rake/version_task'
|
2
|
+
require 'rubygems/package_task'
|
3
|
+
|
4
|
+
spec = Gem::Specification.new do |s|
|
5
|
+
s.name = 'rmagick-sprite'
|
6
|
+
s.author = 'Ryan Scott Lewis'
|
7
|
+
s.email = 'ryan@rynet.us'
|
8
|
+
|
9
|
+
s.homepage = "http://github.com/c00lryguy/#{s.name}"
|
10
|
+
s.description = 'Encapsulates a "Sprite" in RMagick.'
|
11
|
+
s.summary = 'Slice up spritesheets into Objects and export as images/animations or use with your favorite gaming library.'
|
12
|
+
s.version = File.read( File.expand_path('./VERSION') )
|
13
|
+
|
14
|
+
s.require_path = 'lib'
|
15
|
+
s.files = `git ls-files`.lines.collect { |line| line.strip }
|
16
|
+
s.executables = Dir['bin/*'].find_all { |file| File.executable?(file) }.collect { |file| File.basename(file) }
|
17
|
+
|
18
|
+
s.add_dependency('rmagick', '~> 2.13.1')
|
19
|
+
s.add_dependency('version', '~> 1.0')
|
20
|
+
s.add_dependency('dsl', '~> 0.2.2')
|
21
|
+
end
|
22
|
+
|
23
|
+
Rake::VersionTask.new do |t|
|
24
|
+
t.with_git_tag = true
|
25
|
+
t.with_gemspec = spec
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
Gem::PackageTask.new(spec) do |t|
|
30
|
+
t.need_zip = true
|
31
|
+
t.need_tar = true
|
32
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.4
|
@@ -0,0 +1,69 @@
|
|
1
|
+
class Sprite
|
2
|
+
|
3
|
+
class Action
|
4
|
+
class DSL < ::DSL
|
5
|
+
def frame(options)
|
6
|
+
@parent.add_frame(options)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :sprite, :frames
|
11
|
+
attr_accessor :current_index
|
12
|
+
|
13
|
+
def initialize(options, &blk)
|
14
|
+
raise 'options must be a Hash' unless options.respond_to?(:to_hash) || options.respond_to?(:to_h)
|
15
|
+
options = options.to_hash rescue options.to_h
|
16
|
+
|
17
|
+
raise 'options[:sprite] must be given' if options[:sprite].nil?
|
18
|
+
raise 'options[:sprite] must be a Sprite' unless options[:sprite].instance_of?(Sprite)
|
19
|
+
|
20
|
+
@sprite = options[:sprite]
|
21
|
+
@current_index, @frames = 0, []
|
22
|
+
|
23
|
+
DSL.call(self, &blk)
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_frame(options)
|
27
|
+
raise 'options must be a Hash' unless options.respond_to?(:to_hash) || options.respond_to?(:to_h)
|
28
|
+
options = options.to_hash rescue options.to_h
|
29
|
+
options = { action: self }.merge(@sprite.default_frame_options).merge(options)
|
30
|
+
@frames << Frame.new(options)
|
31
|
+
end
|
32
|
+
|
33
|
+
def current_frame
|
34
|
+
@frames[@current_index]
|
35
|
+
end
|
36
|
+
|
37
|
+
def current_image
|
38
|
+
current_frame.image
|
39
|
+
end
|
40
|
+
|
41
|
+
def increase_index
|
42
|
+
@current_index += 1
|
43
|
+
@current_index = 0 if @current_index >= @frames.length
|
44
|
+
end
|
45
|
+
|
46
|
+
def next_frame
|
47
|
+
increase_index
|
48
|
+
current_frame
|
49
|
+
end
|
50
|
+
|
51
|
+
def next_image
|
52
|
+
increase_index
|
53
|
+
current_image
|
54
|
+
end
|
55
|
+
|
56
|
+
def write(filename, &blk)
|
57
|
+
image_list = Magick::ImageList.new
|
58
|
+
@frames.each do |frame|
|
59
|
+
image = frame.image
|
60
|
+
image_list << image
|
61
|
+
end
|
62
|
+
|
63
|
+
blk.call(image_list) if block_given?
|
64
|
+
|
65
|
+
image_list.write(filename)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/lib/sprite/frame.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
class Sprite
|
2
|
+
|
3
|
+
class Frame
|
4
|
+
attr_reader :sprite, :action, :x, :y, :width, :height
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
raise 'options must be a Hash' unless options.respond_to?(:to_hash) || options.respond_to?(:to_h)
|
8
|
+
options = options.to_hash rescue options.to_h
|
9
|
+
|
10
|
+
raise 'options[:action] must be given' if options[:action].nil?
|
11
|
+
raise 'options[:action] must be an Action' unless options[:action].instance_of?(Action)
|
12
|
+
raise 'options[:x] must be given' if options[:x].nil?
|
13
|
+
raise 'options[:x] must be a Integer-like object' unless options[:x].respond_to?(:to_i)
|
14
|
+
raise 'options[:y] must be given' if options[:y].nil?
|
15
|
+
raise 'options[:y] must be a Integer-like object' unless options[:y].respond_to?(:to_i)
|
16
|
+
raise 'options[:width] must be given' if options[:width].nil?
|
17
|
+
raise 'options[:width] must be a Integer-like object' unless options[:width].respond_to?(:to_i)
|
18
|
+
raise 'options[:height] must be given' if options[:height].nil?
|
19
|
+
raise 'options[:height] must be a Integer-like object' unless options[:height].respond_to?(:to_i)
|
20
|
+
|
21
|
+
@action = options[:action]
|
22
|
+
@x, @y, @width, @height = options.values_at(:x, :y, :width, :height).collect(&:to_i)
|
23
|
+
@sprite = @action.sprite
|
24
|
+
end
|
25
|
+
|
26
|
+
def image
|
27
|
+
reload if @image.nil?
|
28
|
+
|
29
|
+
@image
|
30
|
+
end
|
31
|
+
|
32
|
+
def reload
|
33
|
+
@image = @sprite.image.excerpt(@x, @y, @width, @height)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/lib/sprite.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'dsl'
|
4
|
+
require 'rmagick'
|
5
|
+
|
6
|
+
Dir[ Pathname(__FILE__).join('..', 'sprite', '**', '*.rb').expand_path ].each { |filename| require(filename) }
|
7
|
+
|
8
|
+
class Sprite
|
9
|
+
class DSL < ::DSL
|
10
|
+
def_dsl_delegator :filename, :default_action, :default_action_options, :default_frame_options
|
11
|
+
|
12
|
+
def method_missing(meth, options={}, &blk)
|
13
|
+
@parent.add_action(meth, options, &blk)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :actions, :action, :filename
|
18
|
+
attr_reader :default_action, :default_action_options, :default_frame_options
|
19
|
+
|
20
|
+
def initialize(&blk)
|
21
|
+
@actions, @default_action_options, @default_frame_options = {}, {}, {}
|
22
|
+
|
23
|
+
DSL.call(self, &blk)
|
24
|
+
end
|
25
|
+
|
26
|
+
def filename=(filename)
|
27
|
+
raise 'filename must be a String-like object' unless filename.respond_to?(:to_s)
|
28
|
+
filename = filename.to_s
|
29
|
+
raise 'filename must not be empty' if filename.empty?
|
30
|
+
raise "file '#{filename}' does not exist" unless File.exist?(filename)
|
31
|
+
|
32
|
+
@filename = filename
|
33
|
+
reload
|
34
|
+
|
35
|
+
@filename
|
36
|
+
end
|
37
|
+
|
38
|
+
def default_action_options=(options)
|
39
|
+
raise 'options must be a Hash-like object' unless options.respond_to?(:to_h) || options.respond_to?(:to_hash)
|
40
|
+
|
41
|
+
@default_action_options = options.to_hash rescue options.to_h
|
42
|
+
end
|
43
|
+
|
44
|
+
def default_frame_options=(options)
|
45
|
+
raise 'options must be a Hash-like object' unless options.respond_to?(:to_h) || options.respond_to?(:to_hash)
|
46
|
+
|
47
|
+
@default_frame_options = options.to_hash rescue options.to_h
|
48
|
+
end
|
49
|
+
|
50
|
+
def default_action=(action)
|
51
|
+
raise 'action must be a Symbol-like object' unless action.respond_to?(:to_sym)
|
52
|
+
|
53
|
+
@default_action = action.to_sym
|
54
|
+
end
|
55
|
+
|
56
|
+
def action=(action_name)
|
57
|
+
raise 'action_name must be a Symbol-like object' unless action_name.respond_to?(:to_sym)
|
58
|
+
action_name = action_name.to_sym
|
59
|
+
raise 'action does not exist' unless @actions.has_key?(action_name)
|
60
|
+
|
61
|
+
@action = @actions[action_name]
|
62
|
+
@action.current_index = 0
|
63
|
+
|
64
|
+
@action
|
65
|
+
end
|
66
|
+
|
67
|
+
def action
|
68
|
+
@action ||= @actions[@default_action]
|
69
|
+
end
|
70
|
+
|
71
|
+
def add_action(name, options={}, &blk)
|
72
|
+
raise 'options must be a Hash' unless options.respond_to?(:to_hash) || options.respond_to?(:to_h)
|
73
|
+
options = options.to_hash rescue options.to_h
|
74
|
+
options = { sprite: self }.merge(@default_action_options).merge(options)
|
75
|
+
|
76
|
+
@actions[name] = Action.new(options, &blk)
|
77
|
+
end
|
78
|
+
|
79
|
+
def image
|
80
|
+
raise 'filename must be set' if @filename.nil?
|
81
|
+
reload if @image.nil?
|
82
|
+
|
83
|
+
@image
|
84
|
+
end
|
85
|
+
|
86
|
+
def reload
|
87
|
+
@image = Magick::Image.read(@filename).first
|
88
|
+
@actions.each { |name, action| action.frames.each(&:reload) }
|
89
|
+
|
90
|
+
@image
|
91
|
+
end
|
92
|
+
|
93
|
+
def current_frame
|
94
|
+
action.current_frame
|
95
|
+
end
|
96
|
+
|
97
|
+
def current_image
|
98
|
+
action.current_image
|
99
|
+
end
|
100
|
+
|
101
|
+
def next_frame
|
102
|
+
action.next_frame
|
103
|
+
end
|
104
|
+
|
105
|
+
def next_image
|
106
|
+
action.next_image
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "rmagick-sprite"
|
5
|
+
s.version = "0.0.4"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Ryan Scott Lewis"]
|
9
|
+
s.date = "2012-11-05"
|
10
|
+
s.description = "Encapsulates a \"Sprite\" in RMagick."
|
11
|
+
s.email = "ryan@rynet.us"
|
12
|
+
s.files = [".rvmrc", "Gemfile", "Gemfile.lock", "README.md", "Rakefile", "VERSION", "lib/sprite.rb", "lib/sprite/action.rb", "lib/sprite/frame.rb", "rmagick-sprite.gemspec"]
|
13
|
+
s.homepage = "http://github.com/c00lryguy/rmagick-sprite"
|
14
|
+
s.require_paths = ["lib"]
|
15
|
+
s.rubygems_version = "1.8.24"
|
16
|
+
s.summary = "Slice up spritesheets into Objects and export as images/animations or use with your favorite gaming library."
|
17
|
+
|
18
|
+
if s.respond_to? :specification_version then
|
19
|
+
s.specification_version = 3
|
20
|
+
|
21
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
22
|
+
s.add_runtime_dependency(%q<rmagick>, ["~> 2.13.1"])
|
23
|
+
s.add_runtime_dependency(%q<version>, ["~> 1.0"])
|
24
|
+
s.add_runtime_dependency(%q<dsl>, ["~> 0.2.2"])
|
25
|
+
else
|
26
|
+
s.add_dependency(%q<rmagick>, ["~> 2.13.1"])
|
27
|
+
s.add_dependency(%q<version>, ["~> 1.0"])
|
28
|
+
s.add_dependency(%q<dsl>, ["~> 0.2.2"])
|
29
|
+
end
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<rmagick>, ["~> 2.13.1"])
|
32
|
+
s.add_dependency(%q<version>, ["~> 1.0"])
|
33
|
+
s.add_dependency(%q<dsl>, ["~> 0.2.2"])
|
34
|
+
end
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rmagick-sprite
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ryan Scott Lewis
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rmagick
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.13.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.13.1
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: version
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: dsl
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.2.2
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.2.2
|
62
|
+
description: Encapsulates a "Sprite" in RMagick.
|
63
|
+
email: ryan@rynet.us
|
64
|
+
executables: []
|
65
|
+
extensions: []
|
66
|
+
extra_rdoc_files: []
|
67
|
+
files:
|
68
|
+
- .rvmrc
|
69
|
+
- Gemfile
|
70
|
+
- Gemfile.lock
|
71
|
+
- README.md
|
72
|
+
- Rakefile
|
73
|
+
- VERSION
|
74
|
+
- lib/sprite.rb
|
75
|
+
- lib/sprite/action.rb
|
76
|
+
- lib/sprite/frame.rb
|
77
|
+
- rmagick-sprite.gemspec
|
78
|
+
homepage: http://github.com/c00lryguy/rmagick-sprite
|
79
|
+
licenses: []
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
hash: -1641621572133305106
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.8.24
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: Slice up spritesheets into Objects and export as images/animations or use
|
105
|
+
with your favorite gaming library.
|
106
|
+
test_files: []
|