metro 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
data/changelog.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Metro
2
2
 
3
+ ## 0.2.4 / 2012-11-15
4
+
5
+ * All retrieved models from properties are now cached for better performance
6
+ * Animations were re-vamped to accept more parameters
7
+ * Metro models names in code are now refered to as "metro::models::*" to "metro::ui::*"
8
+
3
9
  ## 0.2.3 / 2012-11-11
4
10
 
5
11
  * FIX metro generators and templates generating out-of-date formats
data/lib/metro.rb CHANGED
@@ -11,10 +11,6 @@ require 'active_support/core_ext/hash'
11
11
  require 'active_support/hash_with_indifferent_access'
12
12
 
13
13
  require 'gosu_ext/color'
14
- require 'gosu_ext/image'
15
- require 'gosu_ext/animation'
16
- require 'gosu_ext/song'
17
- require 'gosu_ext/sample'
18
14
  require 'gosu_ext/gosu_constants'
19
15
  require 'core_ext/numeric'
20
16
 
@@ -24,6 +20,10 @@ require 'metro/asset_path'
24
20
  require 'metro/units/units'
25
21
  require 'metro/logging'
26
22
  require 'metro/version'
23
+ require 'metro/animation'
24
+ require 'metro/image'
25
+ require 'metro/sample'
26
+ require 'metro/song'
27
27
  require 'metro/template_message'
28
28
  require 'metro/window'
29
29
  require 'metro/game'
@@ -0,0 +1,135 @@
1
+ module Metro
2
+
3
+ #
4
+ # The animation is an wrapper object for an array of Gosu::Images that also contains
5
+ # the additional information on the path, height, width, and tileability.
6
+ #
7
+ class Animation
8
+
9
+ attr_accessor :images, :path, :height, :width, :tileable, :time_per_image
10
+
11
+ def initialize(params = {})
12
+ @images = Array(params[:images])
13
+ @path = params[:path]
14
+ @height = params[:height]
15
+ @width = params[:width]
16
+ @tileable = params[:tileable]
17
+ @time_per_image = params[:time_per_image]
18
+ end
19
+
20
+ #
21
+ # @return a hash representation of the Animation
22
+ #
23
+ def to_hash
24
+ { path: path,
25
+ width: width.to_i, height: height.to_i,
26
+ tileable: !!tileable,
27
+ time_per_image: time_per_image }
28
+ end
29
+
30
+ #
31
+ # @return [Fixnum] the game time when the animation started to display.
32
+ #
33
+ def start_time
34
+ @start_time ||= current_time
35
+ end
36
+
37
+ #
38
+ # @return [Fixnum] the current time in the game.
39
+ #
40
+ def current_time
41
+ Gosu::milliseconds
42
+ end
43
+
44
+ #
45
+ # @return [Fixnum] the age of the animation.
46
+ #
47
+ def age
48
+ current_time - start_time
49
+ end
50
+
51
+ #
52
+ # @return the current animation image count.
53
+ #
54
+ def current_index
55
+ age / time_per_image
56
+ end
57
+
58
+ #
59
+ # @return the current animation image to display.
60
+ #
61
+ def current_image_index
62
+ current_index % images.size
63
+ end
64
+
65
+ #
66
+ # @return the animation is complete if it the current index exceeds the
67
+ # number of images.
68
+ #
69
+ def complete?
70
+ current_index > (images.size - 1)
71
+ end
72
+
73
+ #
74
+ # @return a Gosu::Image to be displayed in a animation sequence.
75
+ #
76
+ def image
77
+ images[current_image_index]
78
+ end
79
+
80
+ #
81
+ # Finds an existing image or creates a new image given the window, path,
82
+ # width, height and tileablilty.
83
+ #
84
+ # @example Finding or creating an Animation image
85
+ #
86
+ # Metro::Animation.find_or_create window: model.window,
87
+ # path: "asset_path", tileable: tileable, width: 64, height: 64,
88
+ # time_per_image: 50
89
+ #
90
+ def self.find_or_create(options)
91
+ new options.merge(images: find_or_create_gosu_images(options))
92
+ end
93
+
94
+ #
95
+ # Create an animation image given the window, path, width, height,
96
+ # and tileability.
97
+ #
98
+ # @example Creating an Animation Image
99
+ #
100
+ # Metro::Animation.create window: model.window,
101
+ # path: "asset_path", tileable: tileable, width: 64, height: 64,
102
+ # time_per_image: 50
103
+ #
104
+ def self.create(options)
105
+ new options.merge(images: create_gosu_images(options))
106
+ end
107
+
108
+ private
109
+
110
+ def self.create_gosu_images(options)
111
+ path = AssetPath.with(options[:path]).to_s
112
+ images[path] = Gosu::Image.load_tiles(*create_params(options))
113
+ end
114
+
115
+ def self.find_or_create_gosu_images(options)
116
+ path = AssetPath.with(options[:path]).to_s
117
+ images[path] or create_gosu_images(options)
118
+ end
119
+
120
+ def self.create_params(options)
121
+ options.symbolize_keys!
122
+ window = options[:window]
123
+ asset_path = AssetPath.with(options[:path]).filepath
124
+ width = options[:width].to_i
125
+ height = options[:height].to_i
126
+ tileable = !!options[:tileable]
127
+ [ window, asset_path, width, height, tileable ]
128
+ end
129
+
130
+ def self.images
131
+ @images ||= {}
132
+ end
133
+
134
+ end
135
+ end
@@ -2,12 +2,12 @@
2
2
  # The asset_path is a helper which will generate a filepath based on the current working
3
3
  # directory of the game. This allows for game author's to specify a path relative within
4
4
  # the assets directory of their game.
5
- #
5
+ #
6
6
  # @note Paths that are defined within views use this helper and are assumed to be paths
7
7
  # relative within the assets directory of the game.
8
- #
8
+ #
9
9
  # @example Loading the branding image for the player model.
10
- #
10
+ #
11
11
  # class Player < Metro::Model
12
12
  # def image
13
13
  # @image ||= Gosu::Image.new( window, asset_path("player.png"), false )
@@ -16,7 +16,7 @@
16
16
  # image.draw_rot(x,y,2,angle)
17
17
  # end
18
18
  # end
19
- #
19
+ #
20
20
  def asset_path(name)
21
21
  File.join Dir.pwd, "assets", name
22
22
  end
@@ -25,7 +25,55 @@ end
25
25
  #
26
26
  # The metro_asset_path is a helper which will generate a filepath based on the directory
27
27
  # of the metro library. This is used to retrieve assets internally for missing images.
28
- #
28
+ #
29
29
  def metro_asset_path(name)
30
30
  File.join Metro.asset_dir, name
31
+ end
32
+
33
+ module Metro
34
+
35
+ #
36
+ # An AssetPath searches through the various paths based on the path provided.
37
+ #
38
+ # First it assumes the path is absolute, second it assuemts that path is within
39
+ # the game, and third it assumes it is within metro itself.
40
+ #
41
+ class AssetPath
42
+
43
+ def self.with(path)
44
+ path.is_a?(AssetPath) ? path : new(path.to_s)
45
+ end
46
+
47
+ def initialize(path)
48
+ @path = path
49
+ end
50
+
51
+ attr_reader :path
52
+
53
+ def filepath
54
+ @filepath ||= begin
55
+ absolute_asset?(path) or game_asset?(path) or metro_asset?(path)
56
+ end
57
+ end
58
+
59
+ def absolute_asset?(path)
60
+ asset_at_path? path
61
+ end
62
+
63
+ def game_asset?(path)
64
+ asset_at_path? asset_path(path)
65
+ end
66
+
67
+ def metro_asset?(path)
68
+ asset_at_path? metro_asset_path(path)
69
+ end
70
+
71
+ alias_method :to_s, :filepath
72
+
73
+ private
74
+
75
+ def asset_at_path?(asset_path)
76
+ asset_path if File.exists?(asset_path) and File.file?(asset_path)
77
+ end
78
+ end
31
79
  end
@@ -0,0 +1,67 @@
1
+ module Metro
2
+
3
+ #
4
+ # Image is a wrapper class for a Gosu Image. This allows for additional data to be stored
5
+ # without relying on monkey-patching on functionality.
6
+ #
7
+ class Image < SimpleDelegator
8
+
9
+ def initialize(gosu_image,path,tileable)
10
+ super(gosu_image)
11
+ @path = path
12
+ @tileable = tileable
13
+ end
14
+
15
+ # The relative path of the image
16
+ attr_reader :path
17
+
18
+ # The tileability of the image
19
+ attr_reader :tileable
20
+
21
+ def dimensions
22
+ Metro::Units::Dimensions.of width, height
23
+ end
24
+
25
+ #
26
+ # Finds an existing image or creates a new image given the window, path, and tileablilty.
27
+ #
28
+ # @example Finding or creating an Image
29
+ #
30
+ # Metro::Image.find_or_create window: model.window,
31
+ # path: "asset_path", tileable: tileable
32
+ #
33
+ def self.find_or_create(options)
34
+ path = AssetPath.with(options[:path])
35
+ images[path.to_s] or (images[path.to_s] = create(options))
36
+ end
37
+
38
+ #
39
+ # Create an image given the window, path, and tileability.
40
+ #
41
+ # @example Creating an Image
42
+ #
43
+ # Metro::Image.create window: model.window,
44
+ # path: "asset_path", tileable: tileable
45
+ #
46
+ def self.create(options)
47
+ window, asset_path, tileable = create_params(options)
48
+ gosu_image = Gosu::Image.new(window,asset_path.filepath,tileable)
49
+ new gosu_image, asset_path.path, tileable
50
+ end
51
+
52
+ private
53
+
54
+ def self.create_params(options)
55
+ options.symbolize_keys!
56
+ asset_path = AssetPath.with(options[:path])
57
+ window = options[:window]
58
+ tileable = !!options[:tileable]
59
+ [ window, asset_path, tileable ]
60
+ end
61
+
62
+ def self.images
63
+ @images ||= {}
64
+ end
65
+
66
+ end
67
+ end
@@ -1,5 +1,5 @@
1
1
  module Metro
2
- module Models
2
+ module Audio
3
3
 
4
4
  #
5
5
  # A song represents an audio representation.
@@ -68,7 +68,6 @@ module Metro
68
68
  def draw ; end
69
69
 
70
70
 
71
-
72
71
  #
73
72
  # Define a property for the model. A property has a name and then can optionally specify
74
73
  # a property type which will receive additional options.
@@ -103,10 +102,17 @@ module Metro
103
102
 
104
103
  define_method name do
105
104
  raw_value = properties[name]
106
- property_class.new(self,options,&block).get raw_value
105
+
106
+ unless parsed_value = instance_variable_get("@_property_parsed_#{name}")
107
+ parsed_value = property_class.new(self,options,&block).get(raw_value)
108
+ instance_variable_set("@_property_parsed_#{name}",parsed_value)
109
+ end
110
+
111
+ parsed_value
107
112
  end
108
113
 
109
114
  define_method "#{name}=" do |value|
115
+ instance_variable_set("@_property_parsed_#{name}",nil)
110
116
  prepared_value = property_class.new(self,options).set(value)
111
117
  properties[name] = prepared_value
112
118
  end
@@ -218,6 +224,18 @@ module Metro
218
224
  #
219
225
  include HasEvents
220
226
 
227
+ #
228
+ # @param [String] model_name the name of the model to be created.
229
+ # @return [Metro::Model] the metro model instance
230
+ #
231
+ def create(model_name)
232
+ model_class = Metro::Model.model(model_name).constantize
233
+ mc = model_class.new
234
+ mc.scene = scene
235
+ mc.window = window
236
+ mc
237
+ end
238
+
221
239
  def saveable?
222
240
  true
223
241
  end
@@ -319,10 +337,10 @@ module Metro
319
337
  end
320
338
  end
321
339
 
322
- require_relative 'models/generic'
323
- require_relative 'models/label'
324
- require_relative 'models/menu'
325
- require_relative 'models/image'
326
- require_relative 'models/rectangle'
327
- require_relative 'models/grid_drawer'
328
- require_relative 'models/song'
340
+ require_relative 'ui/generic'
341
+ require_relative 'ui/label'
342
+ require_relative 'ui/menu'
343
+ require_relative 'ui/image'
344
+ require_relative 'ui/rectangle'
345
+ require_relative 'ui/grid_drawer'
346
+ require_relative 'audio/song'
@@ -37,7 +37,7 @@ module Metro
37
37
  # @example Using an animation property with a different property name
38
38
  #
39
39
  # class Hero < Metro::Model
40
- # property :walking, type: :animation, path: "star.png",
40
+ # property :walking, type: :animation, path: "star.png",
41
41
  # dimensions: Metro::Dimensions.of(25,25)
42
42
  #
43
43
  # def draw
@@ -50,18 +50,18 @@ module Metro
50
50
  # By default return the default animation when getting a nil or
51
51
  # other unsupported value.
52
52
  get do
53
- default_animation
53
+ create_animation default_properties
54
54
  end
55
55
 
56
56
  # When getting a hash, create the animation with the properties.
57
- get Hash do |value|
58
- self.class.animation_for value.merge(window: model.window)
57
+ get Hash do |loaded|
58
+ create_animation default_properties.merge(loaded)
59
59
  end
60
60
 
61
61
  # Setting the animation with a nil or other unsupported value
62
62
  # will default to the default animation.
63
63
  set do
64
- default_animation.to_hash
64
+ defaults.except(:window)
65
65
  end
66
66
 
67
67
  # Setting with an animation will convert it to it's hash representation.
@@ -71,60 +71,38 @@ module Metro
71
71
 
72
72
  # Setting with a hash will assume the hash defines an animation.
73
73
  set Hash do |value|
74
- value
74
+ value.except(:window)
75
75
  end
76
76
 
77
- def default_animation
78
- self.class.animation_for window: model.window,
79
- path: default_image_path,
77
+ private
78
+
79
+ def create_animation(properties)
80
+ self.class.animation_for properties
81
+ end
82
+
83
+ def default_properties
84
+ { window: model.window,
85
+ path: default_image_filename,
80
86
  width: default_dimensions.width,
81
87
  height: default_dimensions.height,
82
- tileable: false
88
+ time_per_image: default_time_per_image,
89
+ tileable: false }
83
90
  end
84
91
 
85
- def default_image_path
86
- options[:path] ? options[:path] : metro_asset_path("missing_animation.png")
92
+ def default_image_filename
93
+ options[:path] or "missing_animation.png"
87
94
  end
88
95
 
89
96
  def default_dimensions
90
- options[:dimensions] ? options[:dimensions] : Dimensions.of(16.0,16.0)
97
+ options[:dimensions] or Dimensions.of(16.0,16.0)
91
98
  end
92
99
 
93
- #
94
- # Return an animation for the specified path. On first request it will be loaded from
95
- # the file-system. On subsequent requests it will be pulled from the cache.
96
- #
97
- # @param [Hash] options the relative `path` to the image and the window for which it
98
- # will be displayed.
99
- #
100
- def self.animation_for(options)
101
- options.symbolize_keys!
102
- window = options[:window]
103
-
104
- absolute_path = path = options[:path]
105
- absolute_path = asset_path(absolute_path) unless absolute_path.start_with? "/"
106
-
107
- width = options[:width].to_i
108
- height = options[:height].to_i
109
- tileable = options[:tileable]
110
-
111
- animation_images = images[path]
112
- unless animation_images
113
- animation_images = create_images(window,absolute_path,width,height,tileable)
114
- images[path] = animation_images
115
- end
116
-
117
- Animation.new options.merge(images: animation_images)
118
- end
119
-
120
- def self.images
121
- @images ||= {}
100
+ def default_time_per_image
101
+ options[:time_per_image] or 50
122
102
  end
123
103
 
124
- private
125
-
126
- def self.create_images(window,path,width,height,tileable)
127
- Gosu::Image.load_tiles(window,path,width,height,tileable)
104
+ def self.animation_for(options)
105
+ Metro::Animation.find_or_create(options)
128
106
  end
129
107
 
130
108
  end
@@ -9,9 +9,6 @@ module Metro
9
9
  # Property will attempt to use a image at that path that already meets that criteria if it has been
10
10
  # loaded.
11
11
  #
12
- # The images are cached within the image property to help performance by reducing the unncessary
13
- # creation of similar images.
14
- #
15
12
  # @example Defining a image property
16
13
  #
17
14
  # class Player < Metro::Model
@@ -41,22 +38,22 @@ module Metro
41
38
  #
42
39
  class ImageProperty < Property
43
40
 
41
+ # By default, getting will use the the default image.
44
42
  get do
45
43
  default_image
46
44
  end
47
45
 
48
46
  # Return the image at the specified path.
49
- # @note The path should be the relative path within the game.
50
47
  get String do |path|
51
48
  self.class.image_for path: path, window: model.window
52
49
  end
53
50
 
51
+ # By default, setting will use the path of the default image.
54
52
  set do
55
53
  default_image.path
56
54
  end
57
55
 
58
56
  # Set the image with the specified path.
59
- # @note The path should be the relative path within the game.
60
57
  set String do |path|
61
58
  path
62
59
  end
@@ -67,15 +64,21 @@ module Metro
67
64
  image.path
68
65
  end
69
66
 
67
+ #
68
+ # @return the default image based on the default image path specified.
69
+ #
70
70
  def default_image
71
71
  self.class.image_for path: default_image_path, window: model.window
72
72
  end
73
73
 
74
+ #
75
+ # @return the path provided as the default or if one has not been specified
76
+ # the default "missing.png"
77
+ #
74
78
  def default_image_path
75
- options[:path] || metro_asset_path("missing.png")
79
+ options[:path] or "missing.png"
76
80
  end
77
81
 
78
-
79
82
  #
80
83
  # Return an image for the specified path. On first request it will be loaded from
81
84
  # the file-system. On subsequent requests it will be pulled from the cache.
@@ -84,31 +87,7 @@ module Metro
84
87
  # will be displayed.
85
88
  #
86
89
  def self.image_for(options)
87
- options.symbolize_keys!
88
-
89
- absolute_path = path = options[:path]
90
- absolute_path = asset_path(absolute_path) unless absolute_path.start_with? "/"
91
-
92
- tileable = !!options[:tileable]
93
- window = options[:window]
94
-
95
- gosu_image = images[path]
96
- unless gosu_image
97
- gosu_image = create_image(window,absolute_path,tileable)
98
- images[path] = gosu_image
99
- end
100
-
101
- Metro::Image.new gosu_image, path, tileable
102
- end
103
-
104
- def self.images
105
- @images ||= {}
106
- end
107
-
108
- private
109
-
110
- def self.create_image(window,path,tileable)
111
- Gosu::Image.new(window,path,tileable)
90
+ Metro::Image.find_or_create(options)
112
91
  end
113
92
 
114
93
  end
@@ -25,14 +25,14 @@ module Metro
25
25
  # class Hero < Metro::Model
26
26
  # property :pickup_sample, type: :sample, path: 'pickup.wav'
27
27
  # end
28
- #
28
+ #
29
29
  class SampleProperty < Metro::Model::Property
30
30
 
31
31
  # By default, getting an unsupported value will return the default sample
32
32
  get do |value|
33
33
  default_sample
34
34
  end
35
-
35
+
36
36
  # Bu default, setting sn unsupported value will save the default sample filename
37
37
  set do |value|
38
38
  default_sample_filename
@@ -52,7 +52,7 @@ module Metro
52
52
  set Metro::Sample do |sample|
53
53
  sample.path
54
54
  end
55
-
55
+
56
56
  #
57
57
  # @return the default sample for the sample property. This is based on the default
58
58
  # sample name.
@@ -60,15 +60,15 @@ module Metro
60
60
  def default_sample
61
61
  self.class.sample_for path: default_sample_filename, window: model.window
62
62
  end
63
-
63
+
64
64
  #
65
65
  # @return a string sample name that is default. If the property was not created with
66
66
  # a default value the the default sample is the missing sample found in Metro.
67
67
  #
68
68
  def default_sample_filename
69
- options[:path] || metro_asset_path("missing.wav")
69
+ options[:path] or "missing.wav"
70
70
  end
71
-
71
+
72
72
  #
73
73
  # Returns a Metro::Sample. This is composed of the metadata provided and a Gosu::Sample.
74
74
  #
@@ -76,20 +76,7 @@ module Metro
76
76
  # a sample.
77
77
  #
78
78
  def self.sample_for(options)
79
- options.symbolize_keys!
80
- relative_path = options[:path]
81
- window = options[:window]
82
-
83
- absolute_path = path = options[:path]
84
- absolute_path = asset_path(absolute_path) unless absolute_path.start_with? "/"
85
-
86
- gosu_sample = create_sample(window,absolute_path)
87
-
88
- Metro::Sample.new gosu_sample, relative_path
89
- end
90
-
91
- def self.create_sample(window,filename)
92
- Gosu::Sample.new(window, filename)
79
+ Metro::Sample.create(options)
93
80
  end
94
81
 
95
82
  end
@@ -69,7 +69,7 @@ module Metro
69
69
  # a default value the the default song is the missing song found in Metro.
70
70
  #
71
71
  def default_song_name
72
- options[:path] || metro_asset_path('missing.ogg')
72
+ options[:path] or 'missing.ogg'
73
73
  end
74
74
 
75
75
  #
@@ -81,31 +81,7 @@ module Metro
81
81
  # a song.
82
82
  #
83
83
  def self.song_for(options)
84
- options.symbolize_keys!
85
- relative_path = options[:path]
86
- window = options[:window]
87
-
88
- absolute_path = path = options[:path]
89
- absolute_path = asset_path(absolute_path) unless absolute_path.start_with? "/"
90
-
91
- gosu_song = songs[relative_path]
92
-
93
- unless gosu_song
94
- gosu_song = create_song(window,absolute_path)
95
- songs[relative_path] = gosu_song
96
- end
97
-
98
- Metro::Song.new gosu_song, relative_path
99
- end
100
-
101
- def self.songs
102
- @songs ||= {}
103
- end
104
-
105
- private
106
-
107
- def self.create_song(window,filename)
108
- Gosu::Song.new(window, filename)
84
+ Song.find_or_create(options)
109
85
  end
110
86
 
111
87
  end
@@ -1,5 +1,5 @@
1
1
  module Metro
2
- module Models
2
+ module UI
3
3
 
4
4
  #
5
5
  # Generic model is used when no model is cannot not be found
@@ -1,5 +1,5 @@
1
1
  module Metro
2
- module Models
2
+ module UI
3
3
 
4
4
  class GridDrawer < Model
5
5
 
@@ -1,5 +1,5 @@
1
1
  module Metro
2
- module Models
2
+ module UI
3
3
 
4
4
  #
5
5
  # Draws an Image
@@ -1,5 +1,5 @@
1
1
  module Metro
2
- module Models
2
+ module UI
3
3
 
4
4
  #
5
5
  # Draws a string of text
@@ -1,5 +1,5 @@
1
1
  module Metro
2
- module Models
2
+ module UI
3
3
 
4
4
  #
5
5
  # Draws a a menu of options. A menu model inserts itself into the scene as an event
@@ -1,5 +1,5 @@
1
1
  module Metro
2
- module Models
2
+ module UI
3
3
 
4
4
  class Rectangle < ::Metro::Model
5
5
 
@@ -0,0 +1,40 @@
1
+ module Metro
2
+
3
+ #
4
+ # Sample is a wrapper class for a Gosu Sample. This allows for additional data to be stored
5
+ # without relying on monkey-patching on functionality.
6
+ #
7
+ class Sample < SimpleDelegator
8
+
9
+ attr_accessor :sample, :path
10
+
11
+ def initialize(sample,path)
12
+ super(sample)
13
+ @sample = sample
14
+ @path = path
15
+ end
16
+
17
+ #
18
+ # Create a sample given the window and path.
19
+ #
20
+ # @example Creating a Sample
21
+ #
22
+ # Metro::Sample.create window: model.window, path: "sample_path.wav"
23
+ #
24
+ def self.create(options)
25
+ window, asset_path = create_params(options)
26
+ gosu_sample = Gosu::Sample.new(window,asset_path.filepath)
27
+ new gosu_sample, asset_path.path
28
+ end
29
+
30
+ private
31
+
32
+ def self.create_params(options)
33
+ options.symbolize_keys!
34
+ asset_path = AssetPath.with(options[:path])
35
+ window = options[:window]
36
+ [ window, asset_path ]
37
+ end
38
+
39
+ end
40
+ end
data/lib/metro/song.rb ADDED
@@ -0,0 +1,56 @@
1
+ module Metro
2
+
3
+ #
4
+ # Song is a wrapper class for a Gosu Song. This allows for additional data to be stored
5
+ # without relying on monkey-patching on functionality.
6
+ #
7
+ class Song < SimpleDelegator
8
+
9
+ attr_accessor :song, :path
10
+
11
+ def initialize(song,path)
12
+ super(song)
13
+ @song = song
14
+ @path = path
15
+ end
16
+
17
+ #
18
+ # Finds an existing song or creates a new song given the window and path.
19
+ #
20
+ # @example Finding or creating an Song
21
+ #
22
+ # Metro::Image.find_or_create window: model.window, path: "asset_path"
23
+ #
24
+ def self.find_or_create(options)
25
+ path = AssetPath.with(options[:path])
26
+ songs[path.to_s] or (songs[path.to_s] = create(options))
27
+ end
28
+
29
+ #
30
+ # Create an Song given the window and path.
31
+ #
32
+ # @example Creating an Song
33
+ #
34
+ # Metro::Song.create window: model.window, path: "asset_path"
35
+ #
36
+ def self.create(options)
37
+ window, asset_path = create_params(options)
38
+ gosu_song = Gosu::Song.new(window,asset_path.filepath)
39
+ new gosu_song, asset_path.path
40
+ end
41
+
42
+ private
43
+
44
+ def self.create_params(options)
45
+ options.symbolize_keys!
46
+ asset_path = AssetPath.with(options[:path])
47
+ window = options[:window]
48
+ [ window, asset_path ]
49
+ end
50
+
51
+ def self.songs
52
+ @songs ||= {}
53
+ end
54
+
55
+ end
56
+ end
data/lib/metro/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Metro
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.4"
3
3
  WEBSITE = "https://github.com/burtlo/metro"
4
4
  CONTACT_EMAILS = ["franklin.webber@gmail.com"]
5
5
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-11 00:00:00.000000000 Z
12
+ date: 2012-11-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gosu
@@ -120,15 +120,12 @@ files:
120
120
  - lib/commands/generate_view.rb
121
121
  - lib/commands/thor.rb
122
122
  - lib/core_ext/numeric.rb
123
- - lib/gosu_ext/animation.rb
124
123
  - lib/gosu_ext/color.rb
125
124
  - lib/gosu_ext/gosu_constants.rb
126
- - lib/gosu_ext/image.rb
127
- - lib/gosu_ext/sample.rb
128
- - lib/gosu_ext/song.rb
129
125
  - lib/locale/en.yml
130
126
  - lib/locale/locale.rb
131
127
  - lib/metro.rb
128
+ - lib/metro/animation.rb
132
129
  - lib/metro/animation/after_interval_factory.rb
133
130
  - lib/metro/animation/animation_factory.rb
134
131
  - lib/metro/animation/easing/ease_in.rb
@@ -150,19 +147,14 @@ files:
150
147
  - lib/metro/events/unknown_sender.rb
151
148
  - lib/metro/game.rb
152
149
  - lib/metro/game/dsl.rb
150
+ - lib/metro/image.rb
153
151
  - lib/metro/logging.rb
154
152
  - lib/metro/missing_scene.rb
153
+ - lib/metro/models/audio/song.rb
155
154
  - lib/metro/models/draws.rb
156
155
  - lib/metro/models/key_value_coding.rb
157
156
  - lib/metro/models/model.rb
158
157
  - lib/metro/models/model_factory.rb
159
- - lib/metro/models/models/generic.rb
160
- - lib/metro/models/models/grid_drawer.rb
161
- - lib/metro/models/models/image.rb
162
- - lib/metro/models/models/label.rb
163
- - lib/metro/models/models/menu.rb
164
- - lib/metro/models/models/rectangle.rb
165
- - lib/metro/models/models/song.rb
166
158
  - lib/metro/models/properties/animation_property.rb
167
159
  - lib/metro/models/properties/color_property.rb
168
160
  - lib/metro/models/properties/dimensions_property.rb
@@ -175,8 +167,16 @@ files:
175
167
  - lib/metro/models/properties/scale_property.rb
176
168
  - lib/metro/models/properties/song_property.rb
177
169
  - lib/metro/models/properties/text_property.rb
170
+ - lib/metro/models/ui/generic.rb
171
+ - lib/metro/models/ui/grid_drawer.rb
172
+ - lib/metro/models/ui/image.rb
173
+ - lib/metro/models/ui/label.rb
174
+ - lib/metro/models/ui/menu.rb
175
+ - lib/metro/models/ui/rectangle.rb
176
+ - lib/metro/sample.rb
178
177
  - lib/metro/scene.rb
179
178
  - lib/metro/scenes.rb
179
+ - lib/metro/song.rb
180
180
  - lib/metro/template_message.rb
181
181
  - lib/metro/transitions/edit_transition_scene.rb
182
182
  - lib/metro/transitions/fade_transition_scene.rb
@@ -237,12 +237,11 @@ licenses: []
237
237
  post_install_message: ! " ______ ___ _____\n ___ |/ /_____ __ /_______________\n
238
238
  \ __ /|_/ / _ _ \\_ __/__ ___/_ __ \\\n _ / / / / __// /_ _ / /
239
239
  /_/ /\n /_/ /_/ \\___/ \\__/ /_/ \\____/\n\n Thank you for installing
240
- metro 0.2.3 / 2012-11-11.\n ---------------------------------------------------------------------\n
241
- \ Changes:\n \n * FIX metro generators and templates generating out-of-date
242
- formats\n * FIX YAML views wil now return an empty hash instead of false on empty
243
- files\n * Added first scene and model to template.\n * FIX better error message
244
- when a directory is specified\n * Added the `g` generator shortcut: `metro g scene
245
- NAME`\n \n\n ---------------------------------------------------------------------\n"
240
+ metro 0.2.4 / 2012-11-15.\n ---------------------------------------------------------------------\n
241
+ \ Changes:\n \n * All retrieved models from properties are now cached for better
242
+ performance\n * Animations were re-vamped to accept more parameters\n * Metro
243
+ models names in code are now refered to as \"metro::models::*\" to \"metro::ui::*\"\n
244
+ \ \n\n ---------------------------------------------------------------------\n"
246
245
  rdoc_options: []
247
246
  require_paths:
248
247
  - lib
@@ -283,3 +282,4 @@ test_files:
283
282
  - spec/metro/scenes_spec.rb
284
283
  - spec/metro/views/view_spec.rb
285
284
  - spec/spec_helper.rb
285
+ has_rdoc:
@@ -1,31 +0,0 @@
1
- module Metro
2
-
3
- #
4
- # The animation is an wrapper object for an array of Gosu::Images that also contains
5
- # the additional information on the path, height, width, and tileability.
6
- #
7
- class Animation
8
-
9
- attr_accessor :images, :path, :height, :width, :tileable
10
-
11
- def initialize(params = {})
12
- @images = Array(params[:images])
13
- @path = params[:path]
14
- @height = params[:height]
15
- @width = params[:width]
16
- @tileable = params[:tileable]
17
- end
18
-
19
- def to_hash
20
- { path: path, width: width.to_i, height: height.to_i, tileable: !!tileable }
21
- end
22
-
23
- #
24
- # @return a Gosu::Image to be displayed in a animation sequence.
25
- #
26
- def image
27
- images[Gosu::milliseconds / 100 % images.size]
28
- end
29
-
30
- end
31
- end
@@ -1,42 +0,0 @@
1
- module Metro
2
-
3
- #
4
- # Image is a wrapper class for a Gosu Image. This allows for additional data to be stored
5
- # without relying on monkey-patching on functionality.
6
- #
7
- class Image < SimpleDelegator
8
-
9
- #
10
- # Generate an image given the Gosu window and path. Consider using a model and an image
11
- # property instead of using this method.
12
- #
13
- # @note this goes through the image property because that current performs the caching.
14
- #
15
- # @example Creating an Image
16
- #
17
- # Metro::Image.create path: "relative_imagepath.png", window: window
18
- #
19
- # @see Metro::Model::ImageProperty
20
- #
21
- def self.create(params = {})
22
- Model::ImageProperty.image_for params
23
- end
24
-
25
- def initialize(gosu_image,path,tileable)
26
- super(gosu_image)
27
- @path = path
28
- @tileable = tileable
29
- end
30
-
31
- # The relative path of the image
32
- attr_reader :path
33
-
34
- # The tileability of the image
35
- attr_reader :tileable
36
-
37
- def dimensions
38
- Metro::Units::Dimensions.of width, height
39
- end
40
-
41
- end
42
- end
@@ -1,18 +0,0 @@
1
- module Metro
2
-
3
- #
4
- # Sample is a wrapper class for a Gosu Sample. This allows for additional data to be stored
5
- # without relying on monkey-patching on functionality.
6
- #
7
- class Sample < SimpleDelegator
8
-
9
- attr_accessor :sample, :path
10
-
11
- def initialize(sample,path)
12
- super(sample)
13
- @sample = sample
14
- @path = path
15
- end
16
-
17
- end
18
- end
data/lib/gosu_ext/song.rb DELETED
@@ -1,18 +0,0 @@
1
- module Metro
2
-
3
- #
4
- # Song is a wrapper class for a Gosu Song. This allows for additional data to be stored
5
- # without relying on monkey-patching on functionality.
6
- #
7
- class Song < SimpleDelegator
8
-
9
- attr_accessor :song, :path
10
-
11
- def initialize(song,path)
12
- super(song)
13
- @song = song
14
- @path = path
15
- end
16
-
17
- end
18
- end