metro 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/changelog.md +11 -0
  2. data/lib/assets/menu-movement.wav +0 -0
  3. data/lib/assets/menu-selection.wav +0 -0
  4. data/lib/metro.rb +1 -0
  5. data/lib/metro/asset_path.rb +27 -9
  6. data/lib/metro/events/event_dictionary.rb +1 -2
  7. data/lib/metro/font.rb +66 -0
  8. data/lib/metro/image.rb +4 -3
  9. data/lib/metro/models/draws.rb +8 -7
  10. data/lib/metro/models/model.rb +8 -5
  11. data/lib/metro/models/model_factory.rb +4 -6
  12. data/lib/metro/models/properties/animation_property.rb +1 -1
  13. data/lib/metro/models/properties/array_property.rb +24 -0
  14. data/lib/metro/models/properties/boolean_property.rb +27 -0
  15. data/lib/metro/models/properties/font_property.rb +5 -29
  16. data/lib/metro/models/properties/options_property/no_option.rb +29 -0
  17. data/lib/metro/models/properties/options_property/options.rb +94 -0
  18. data/lib/metro/models/properties/options_property/options_property.rb +125 -0
  19. data/lib/metro/models/properties/property.rb +14 -5
  20. data/lib/metro/models/properties/property_owner.rb +1 -0
  21. data/lib/metro/models/ui/generic.rb +22 -5
  22. data/lib/metro/models/ui/grid_drawer.rb +25 -15
  23. data/lib/metro/models/ui/image.rb +7 -3
  24. data/lib/metro/models/ui/label.rb +25 -15
  25. data/lib/metro/models/ui/menu.rb +106 -95
  26. data/lib/metro/models/ui/rectangle.rb +21 -8
  27. data/lib/metro/version.rb +1 -1
  28. data/spec/metro/models/properties/array_property_spec.rb +60 -0
  29. data/spec/metro/models/properties/{color_spec.rb → color_property_spec.rb} +0 -0
  30. data/spec/metro/models/properties/{font_spec.rb → font_property_spec.rb} +16 -18
  31. data/spec/metro/models/properties/options_property/no_option_spec.rb +25 -0
  32. data/spec/metro/models/properties/options_property/options_property_spec.rb +133 -0
  33. data/spec/metro/models/properties/options_property/options_spec.rb +125 -0
  34. data/spec/metro/models/ui/label_spec.rb +56 -15
  35. metadata +29 -11
data/changelog.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Metro
2
2
 
3
+ ## 0.2.6 / 2012/11-20
4
+
5
+ * Menus now support vertical and horizontal layout
6
+ * Menus now support movement and selection noises
7
+ * Menus can now have a default selection
8
+ * Menus can be enabled/disabled
9
+ * Added Array Property, Boolean Property, and Menu Options Property
10
+ * FIX label horizontal center and right alignments
11
+ * Generic Models will now show a warning instead of raising an exception
12
+ * Removed event chain debug messaging
13
+
3
14
  ## 0.2.5 / 2012-11-18
4
15
 
5
16
  * FIX metro::ui::rectangle calculation
Binary file
Binary file
data/lib/metro.rb CHANGED
@@ -21,6 +21,7 @@ require 'metro/units/units'
21
21
  require 'metro/logging'
22
22
  require 'metro/version'
23
23
  require 'metro/animation'
24
+ require 'metro/font'
24
25
  require 'metro/image'
25
26
  require 'metro/sample'
26
27
  require 'metro/song'
@@ -1,12 +1,28 @@
1
+
2
+ #
3
+ # The asset_path is a helper which will generate a filepath based on the current
4
+ # working directory of the game. This allows for game author's to specify a path
5
+ # relative within the assets directory of their game.
6
+ #
7
+ # @note Paths that are defined within views use this helper and are assumed to
8
+ # be paths relative within the assets directory of the game. For images,
9
+ # samples, and songs in a model consider using a property.
1
10
  #
2
- # The asset_path is a helper which will generate a filepath based on the current working
3
- # directory of the game. This allows for game author's to specify a path relative within
4
- # the assets directory of their game.
11
+ # @see Metro::Model::ImageProperty
12
+ # @see Metro::Model::AnimationProperty
13
+ # @see Metro::Model::SongProperty
14
+ # @see Metro::Model::SampleProperty
5
15
  #
6
- # @note Paths that are defined within views use this helper and are assumed to be paths
7
- # relative within the assets directory of the game.
16
+ # @note Also consider the model classes Image, Animation, Song, and Sample for
17
+ # creating the assets found within the assets folder. Each of those will
18
+ # assist with using the asset_path internally to find the asset.
8
19
  #
9
- # @example Loading the branding image for the player model.
20
+ # @see Metro::Image
21
+ # @see Metro::Animation
22
+ # @see Metro::Song
23
+ # @see Metro::Sample
24
+ #
25
+ # @example Loading a raw Gosu::Image with an `asset_path`
10
26
  #
11
27
  # class Player < Metro::Model
12
28
  # def image
@@ -21,10 +37,12 @@ def asset_path(name)
21
37
  File.join Dir.pwd, "assets", name
22
38
  end
23
39
 
24
-
25
40
  #
26
- # The metro_asset_path is a helper which will generate a filepath based on the directory
27
- # of the metro library. This is used to retrieve assets internally for missing images.
41
+ # The metro_asset_path is a helper which will generate a filepath based on the
42
+ # directory of the metro library. This is used to retrieve internal assets which
43
+ # can be used to serve up missing images, animations, samples, or songs or
44
+ # defaults that may come with the metro game library.
45
+ #
28
46
  #
29
47
  def metro_asset_path(name)
30
48
  File.join Metro.asset_dir, name
@@ -28,7 +28,6 @@ module Metro
28
28
  #
29
29
  def events_for_targets(*list)
30
30
  found_events = Array(list).flatten.compact.map {|s| events_for_target(s) }.flatten.compact
31
- log.debug "Retrieved (#{found_events.count}) events for [#{list.join(",")}]"
32
31
  found_events
33
32
  end
34
33
 
@@ -50,4 +49,4 @@ module Metro
50
49
 
51
50
  end
52
51
 
53
- end
52
+ end
data/lib/metro/font.rb ADDED
@@ -0,0 +1,66 @@
1
+ module Metro
2
+
3
+ #
4
+ # Font is a wrapper class for a Gosu::Font. This allows for additional data
5
+ # to be stored without relying on monkey-patching on functionality.
6
+ #
7
+ class Font < SimpleDelegator
8
+
9
+ def initialize(gosu_font)
10
+ super(gosu_font)
11
+ end
12
+
13
+ #
14
+ # Return a font that matches the specified criteria. Using the name, size,
15
+ # and window a font will be generated or retrieved from the cache.
16
+ #
17
+ # @example Finding or creating a Font
18
+ #
19
+ # Metro::Font.find_or_create window: model.window,
20
+ # name: "Times New Roman", size: 24
21
+ #
22
+ # @param [Hash] value the hash that contains the `name`, `size` and `window`
23
+ # that describe the font.
24
+ #
25
+ def self.find_or_create(options)
26
+ window, name, size = create_params(options)
27
+ gosu_font = fonts["#{name}:#{size}:#{window}"]
28
+ gosu_font ? new(gosu_font) : create(options)
29
+ end
30
+
31
+ #
32
+ # Return a font that matches the specified criteria. Using the name, size,
33
+ # and window a font will be generated and stored in the cache.
34
+ #
35
+ # @example Creating a Font
36
+ #
37
+ # Metro::Font.create window: model.window,
38
+ # name: "Comic Sans", size: 48
39
+ #
40
+ # @param [Hash] value the hash that contains the `name`, `size` and `window`
41
+ # that describe the font.
42
+ #
43
+ def self.create(options)
44
+ window, name, size = create_params(options)
45
+ gosu_font = create_gosu_font(window,name,size)
46
+ fonts["#{name}:#{size}:#{window}"] = gosu_font
47
+ new(gosu_font)
48
+ end
49
+
50
+ private
51
+
52
+ def self.create_params(options)
53
+ options.symbolize_keys!
54
+ [ options[:window], options[:name], options[:size] ]
55
+ end
56
+
57
+ def self.create_gosu_font(window, name, size)
58
+ Gosu::Font.new window, name, size
59
+ end
60
+
61
+ def self.fonts
62
+ @fonts ||= {}
63
+ end
64
+
65
+ end
66
+ end
data/lib/metro/image.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Metro
2
2
 
3
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.
4
+ # Image is a wrapper class for a Gosu Image. This allows for additional data
5
+ # to be stored without relying on monkey-patching on functionality.
6
6
  #
7
7
  class Image < SimpleDelegator
8
8
 
@@ -23,7 +23,8 @@ module Metro
23
23
  end
24
24
 
25
25
  #
26
- # Finds an existing image or creates a new image given the window, path, and tileablilty.
26
+ # Finds an existing image or creates a new image given the window, path,
27
+ # and tileablilty.
27
28
  #
28
29
  # @example Finding or creating an Image
29
30
  #
@@ -18,11 +18,11 @@ module Metro
18
18
  # @example Defining a title label within a scene
19
19
  #
20
20
  # class ExampleScene
21
- # draw :title, 'text' => 'Title Screen',
22
- # 'x' => 20, 'y' => 20, 'z-order' => 0,
23
- # 'x-factor' => 3, 'y-factor' => 3,
24
- # 'color' => 0xffffffff,
21
+ # draw :title, text: Title Screen',
25
22
  # 'model' => 'metro::ui::label'
23
+ # position: "20,20,0",
24
+ # scale: "3,3",
25
+ # color: "rgba(255,255,255,1.0)"
26
26
  #
27
27
  # def show
28
28
  # puts "Where is my title? #{title.x},#{title.y}"
@@ -32,6 +32,7 @@ module Metro
32
32
  def draw(actor_name,options = {})
33
33
 
34
34
  view_content_for_actor = view.content[actor_name.to_s]
35
+
35
36
  actor_data = view_content_for_actor.merge(options)
36
37
  actor_data[:name] = actor_name
37
38
 
@@ -50,9 +51,9 @@ module Metro
50
51
 
51
52
  #
52
53
  # Define a sound actor with the given anem and options.
53
- #
54
+ #
54
55
  # @see #draw
55
- #
56
+ #
56
57
  def play(song_name,options={})
57
58
  draw song_name, options.merge(model: "metro::audio::song")
58
59
  end
@@ -82,4 +83,4 @@ module Metro
82
83
  end
83
84
 
84
85
  end
85
- end
86
+ end
@@ -113,13 +113,18 @@ module Metro
113
113
  #
114
114
  include HasEvents
115
115
 
116
+ #
117
+ # A helper method that allows the current model to generate another model. This
118
+ # is useful as it allows for the current model to pass window and scene state
119
+ # to the created model.
116
120
  #
117
121
  # @param [String] model_name the name of the model to be created.
118
122
  # @return [Metro::Model] the metro model instance
119
123
  #
120
- def create(model_name)
124
+ def create(model_name,options={})
125
+ # @TODO: this is another path that parallels the ModelFactory
121
126
  model_class = Metro::Model.model(model_name).constantize
122
- mc = model_class.new
127
+ mc = model_class.new options
123
128
  mc.scene = scene
124
129
  mc.window = window
125
130
  mc
@@ -159,8 +164,7 @@ module Metro
159
164
  # with the contents of the view.
160
165
  #
161
166
  def _load(options = {})
162
-
163
- # Clean up and symbolize all the keys then merge that with the existing properties
167
+ # Clean up and symbolize all the keys then merge that with the existing properties
164
168
  options.keys.each do |key|
165
169
  property_name = key.to_s.underscore.to_sym
166
170
  if respond_to? "#{property_name}="
@@ -168,7 +172,6 @@ module Metro
168
172
  else
169
173
  options[property_name] = options.delete(key)
170
174
  end
171
-
172
175
  end
173
176
 
174
177
  properties.merge! options
@@ -5,26 +5,24 @@ module Metro
5
5
 
6
6
  def initialize(name,options)
7
7
  @name = name.to_s.downcase
8
- @options = options
8
+ @options = options.symbolize_keys
9
9
  end
10
10
 
11
11
  def create
12
12
  actor_class = class_for_actor(model_name)
13
- instance = actor_class.new
14
- instance._load options
15
- instance
13
+ actor_class.new options
16
14
  end
17
15
 
18
16
  def load_from_previous_scene?
19
17
  @options[:from] == :previous_scene
20
18
  end
21
-
19
+
22
20
  def options
23
21
  @options.except(:from)
24
22
  end
25
23
 
26
24
  def model_name
27
- options['model'] || options[:model] || name
25
+ options[:model] || name
28
26
  end
29
27
 
30
28
  def class_for_actor(model_name)
@@ -70,7 +70,7 @@ module Metro
70
70
  end
71
71
 
72
72
  # Setting with a hash will assume the hash defines an animation.
73
- set Hash do |value|
73
+ set Hash, HashWithIndifferentAccess do |value|
74
74
  value.except(:window)
75
75
  end
76
76
 
@@ -0,0 +1,24 @@
1
+ module Metro
2
+ class Model
3
+
4
+ #
5
+ # The array property will simply store or retrieve an array.
6
+ #
7
+ class ArrayProperty < Property
8
+
9
+ get do |value|
10
+ value.is_a?(NilClass) ? default_value : Array(value)
11
+ end
12
+
13
+ set do |value|
14
+ Array(value).map {|item| item }
15
+ end
16
+
17
+ def default_value
18
+ options[:default] or []
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ module Metro
2
+ class Model
3
+
4
+ #
5
+ # The boolean property will simply convert any input into a true or
6
+ # false value.
7
+ #
8
+ class BooleanProperty < Property
9
+
10
+ # For all cases the value is converted to floating point when it can
11
+ # otherwise the default number is used.
12
+ get_or_set do |value|
13
+ if value.is_a?(NilClass)
14
+ default_value
15
+ else
16
+ !!value
17
+ end
18
+ end
19
+
20
+ def default_value
21
+ !!options[:default]
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+ end
@@ -81,13 +81,13 @@ module Metro
81
81
  end
82
82
 
83
83
  # Save a hash representation of the font when given a font
84
- set Gosu::Font do |font|
84
+ set Metro::Font do |font|
85
85
  { name: font.name, size: font.height }
86
86
  end
87
87
 
88
88
  # Save the hash provided. It is assumed to contain the correct font data.
89
- set Hash do |hash|
90
- hash.symbolize_keys!
89
+ set Hash, HashWithIndifferentAccess do |hash|
90
+ hash.to_hash
91
91
  end
92
92
 
93
93
  #
@@ -120,34 +120,10 @@ module Metro
120
120
  # @param [Hash] value the hash that contains the `name`, `size` and `window` that describe the font.
121
121
  #
122
122
  def self.font_for(value)
123
- value.symbolize_keys!
124
- name = value[:name]
125
- size = value[:size]
126
- window = value[:window]
127
-
128
- font = fonts["#{name}:#{size}:#{window}"]
129
- unless font
130
- font = create_font(window,name,size)
131
- fonts["#{name}:#{size}:#{window}"] = font
132
- end
133
-
134
- font
135
- end
136
-
137
- #
138
- # @return the fonts currently cached by the FontProperty.
139
- #
140
- def self.fonts
141
- @fonts ||= {}
142
- end
143
-
144
- private
145
-
146
- def self.create_font(window,name,size)
147
- Gosu::Font.new window, name, size
123
+ Font.find_or_create(value)
148
124
  end
149
125
 
150
126
  end
151
127
 
152
128
  end
153
- end
129
+ end
@@ -0,0 +1,29 @@
1
+ module Metro
2
+ class Model
3
+ class OptionsProperty
4
+
5
+ #
6
+ # When the options cannot find a selected menu option then this no option
7
+ # is returned instead of a nil value. This allows for a warning to be generated
8
+ # if any methods target this item.
9
+ #
10
+ # Also if the option will send a 'missing_menu_action' if the options were to
11
+ # ask for the selected action.
12
+ #
13
+ class NoOption
14
+ def method_missing(name,*args,&block)
15
+ log.warn warning_message
16
+ end
17
+
18
+ def warning_message
19
+ "No valid options were found in the menu"
20
+ end
21
+
22
+ def properties
23
+ { action: :missing_menu_action }
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+ end