metro-ld25 0.3.3

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.
Files changed (177) hide show
  1. data/.gitignore +17 -0
  2. data/.rspec +2 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +12 -0
  6. data/Guardfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +189 -0
  9. data/Rakefile +18 -0
  10. data/bin/metro +16 -0
  11. data/changelog.md +157 -0
  12. data/lib/assets/menu-movement.wav +0 -0
  13. data/lib/assets/menu-selection.wav +0 -0
  14. data/lib/assets/missing.ogg +0 -0
  15. data/lib/assets/missing.png +0 -0
  16. data/lib/assets/missing.wav +0 -0
  17. data/lib/assets/missing_animation.png +0 -0
  18. data/lib/commands/generate_game.rb +13 -0
  19. data/lib/commands/generate_model.rb +25 -0
  20. data/lib/commands/generate_scene.rb +36 -0
  21. data/lib/commands/generate_view.rb +21 -0
  22. data/lib/commands/thor.rb +83 -0
  23. data/lib/core_ext/class.rb +14 -0
  24. data/lib/core_ext/numeric.rb +59 -0
  25. data/lib/gosu_ext/color.rb +62 -0
  26. data/lib/gosu_ext/gosu_constants.rb +53 -0
  27. data/lib/locale/en.yml +35 -0
  28. data/lib/locale/locale.rb +1 -0
  29. data/lib/metro.rb +140 -0
  30. data/lib/metro/animation.rb +135 -0
  31. data/lib/metro/animation/after_interval_factory.rb +12 -0
  32. data/lib/metro/animation/animation_factory.rb +15 -0
  33. data/lib/metro/animation/easing/ease_in.rb +15 -0
  34. data/lib/metro/animation/easing/easing.rb +51 -0
  35. data/lib/metro/animation/easing/linear.rb +15 -0
  36. data/lib/metro/animation/has_animations.rb +70 -0
  37. data/lib/metro/animation/implicit_animation.rb +100 -0
  38. data/lib/metro/animation/on_update_operation.rb +96 -0
  39. data/lib/metro/animation/scene_animation.rb +16 -0
  40. data/lib/metro/asset_path.rb +97 -0
  41. data/lib/metro/events/control_definition.rb +11 -0
  42. data/lib/metro/events/controls.rb +42 -0
  43. data/lib/metro/events/event_data.rb +60 -0
  44. data/lib/metro/events/event_dictionary.rb +52 -0
  45. data/lib/metro/events/event_factory.rb +17 -0
  46. data/lib/metro/events/event_relay.rb +300 -0
  47. data/lib/metro/events/event_state_manager.rb +63 -0
  48. data/lib/metro/events/events.rb +3 -0
  49. data/lib/metro/events/has_events.rb +108 -0
  50. data/lib/metro/events/hit_list.rb +75 -0
  51. data/lib/metro/events/unknown_sender.rb +5 -0
  52. data/lib/metro/font.rb +69 -0
  53. data/lib/metro/game.rb +102 -0
  54. data/lib/metro/game/dsl.rb +68 -0
  55. data/lib/metro/image.rb +68 -0
  56. data/lib/metro/logging.rb +33 -0
  57. data/lib/metro/missing_scene.rb +21 -0
  58. data/lib/metro/models/audio/song.rb +33 -0
  59. data/lib/metro/models/draws.rb +86 -0
  60. data/lib/metro/models/key_value_coding.rb +38 -0
  61. data/lib/metro/models/model.rb +236 -0
  62. data/lib/metro/models/model_factory.rb +32 -0
  63. data/lib/metro/models/models.rb +62 -0
  64. data/lib/metro/models/properties/animation_property.rb +115 -0
  65. data/lib/metro/models/properties/array_property.rb +24 -0
  66. data/lib/metro/models/properties/boolean_property.rb +27 -0
  67. data/lib/metro/models/properties/color_property.rb +116 -0
  68. data/lib/metro/models/properties/dimensions_property.rb +84 -0
  69. data/lib/metro/models/properties/font_property.rb +130 -0
  70. data/lib/metro/models/properties/image_property.rb +96 -0
  71. data/lib/metro/models/properties/model_property.rb +84 -0
  72. data/lib/metro/models/properties/numeric_property.rb +29 -0
  73. data/lib/metro/models/properties/options_property/no_option.rb +29 -0
  74. data/lib/metro/models/properties/options_property/options.rb +94 -0
  75. data/lib/metro/models/properties/options_property/options_property.rb +125 -0
  76. data/lib/metro/models/properties/position_property.rb +90 -0
  77. data/lib/metro/models/properties/property.rb +221 -0
  78. data/lib/metro/models/properties/property_owner.rb +137 -0
  79. data/lib/metro/models/properties/sample_property.rb +84 -0
  80. data/lib/metro/models/properties/scale_property.rb +80 -0
  81. data/lib/metro/models/properties/song_property.rb +89 -0
  82. data/lib/metro/models/properties/text_property.rb +75 -0
  83. data/lib/metro/models/ui/animated_sprite.rb +85 -0
  84. data/lib/metro/models/ui/border.rb +95 -0
  85. data/lib/metro/models/ui/fps.rb +54 -0
  86. data/lib/metro/models/ui/generic.rb +66 -0
  87. data/lib/metro/models/ui/grid_drawer.rb +74 -0
  88. data/lib/metro/models/ui/image.rb +87 -0
  89. data/lib/metro/models/ui/label.rb +175 -0
  90. data/lib/metro/models/ui/menu.rb +214 -0
  91. data/lib/metro/models/ui/model_label.rb +65 -0
  92. data/lib/metro/models/ui/model_labeler.rb +79 -0
  93. data/lib/metro/models/ui/rectangle.rb +59 -0
  94. data/lib/metro/models/ui/sprite.rb +79 -0
  95. data/lib/metro/models/ui/tile_map.rb +162 -0
  96. data/lib/metro/models/ui/ui.rb +13 -0
  97. data/lib/metro/parameters/command_line_args_parser.rb +68 -0
  98. data/lib/metro/parameters/options.rb +25 -0
  99. data/lib/metro/parameters/parameters.rb +2 -0
  100. data/lib/metro/sample.rb +40 -0
  101. data/lib/metro/scene.rb +477 -0
  102. data/lib/metro/scenes.rb +154 -0
  103. data/lib/metro/song.rb +56 -0
  104. data/lib/metro/template_message.rb +60 -0
  105. data/lib/metro/transitions/edit_transition_scene.rb +100 -0
  106. data/lib/metro/transitions/fade_transition_scene.rb +66 -0
  107. data/lib/metro/transitions/scene_transitions.rb +44 -0
  108. data/lib/metro/transitions/transition_scene.rb +19 -0
  109. data/lib/metro/units/bounds.rb +8 -0
  110. data/lib/metro/units/calculation_validations.rb +74 -0
  111. data/lib/metro/units/dimensions.rb +60 -0
  112. data/lib/metro/units/point.rb +51 -0
  113. data/lib/metro/units/rectangle_bounds.rb +85 -0
  114. data/lib/metro/units/scale.rb +46 -0
  115. data/lib/metro/units/units.rb +6 -0
  116. data/lib/metro/version.rb +32 -0
  117. data/lib/metro/views/json_view.rb +60 -0
  118. data/lib/metro/views/no_view.rb +34 -0
  119. data/lib/metro/views/parsers.rb +42 -0
  120. data/lib/metro/views/scene_view.rb +107 -0
  121. data/lib/metro/views/view.rb +133 -0
  122. data/lib/metro/views/writers.rb +43 -0
  123. data/lib/metro/views/yaml_view.rb +94 -0
  124. data/lib/metro/window.rb +94 -0
  125. data/lib/setup_handlers/exit_if_dry_run.rb +26 -0
  126. data/lib/setup_handlers/game_execution.rb +65 -0
  127. data/lib/setup_handlers/load_game_configuration.rb +65 -0
  128. data/lib/setup_handlers/load_game_files.rb +101 -0
  129. data/lib/setup_handlers/move_to_game_directory.rb +25 -0
  130. data/lib/setup_handlers/reload_game_on_game_file_changes.rb +79 -0
  131. data/lib/templates/game/README.md.tt +52 -0
  132. data/lib/templates/game/assets/brand.jpg +0 -0
  133. data/lib/templates/game/assets/hero.png +0 -0
  134. data/lib/templates/game/lib/custom_easing.rb +32 -0
  135. data/lib/templates/game/metro.tt +63 -0
  136. data/lib/templates/game/models/hero.rb +62 -0
  137. data/lib/templates/game/scenes/brand_scene.rb +19 -0
  138. data/lib/templates/game/scenes/brand_to_title_scene.rb +13 -0
  139. data/lib/templates/game/scenes/first_scene.rb +28 -0
  140. data/lib/templates/game/scenes/game_scene.rb +43 -0
  141. data/lib/templates/game/scenes/title_scene.rb +15 -0
  142. data/lib/templates/game/views/brand.yaml +4 -0
  143. data/lib/templates/game/views/brand_to_title.yaml +8 -0
  144. data/lib/templates/game/views/first.yaml +26 -0
  145. data/lib/templates/game/views/title.yaml +11 -0
  146. data/lib/templates/message.erb +23 -0
  147. data/lib/templates/model.rb.tt +111 -0
  148. data/lib/templates/scene.rb.tt +140 -0
  149. data/lib/templates/view.yaml.tt +11 -0
  150. data/lib/tmxed_ext/tile_set.rb +34 -0
  151. data/metro.gemspec +56 -0
  152. data/spec/core_ext/numeric_spec.rb +78 -0
  153. data/spec/core_ext/string_spec.rb +33 -0
  154. data/spec/gosu_ext/color_spec.rb +80 -0
  155. data/spec/metro/events/event_state_manager_spec.rb +5 -0
  156. data/spec/metro/models/key_value_coding_spec.rb +61 -0
  157. data/spec/metro/models/properties/array_property_spec.rb +60 -0
  158. data/spec/metro/models/properties/color_property_spec.rb +85 -0
  159. data/spec/metro/models/properties/dimensions_spec.rb +29 -0
  160. data/spec/metro/models/properties/font_property_spec.rb +127 -0
  161. data/spec/metro/models/properties/numeric_property_spec.rb +46 -0
  162. data/spec/metro/models/properties/options_property/no_option_spec.rb +25 -0
  163. data/spec/metro/models/properties/options_property/options_property_spec.rb +133 -0
  164. data/spec/metro/models/properties/options_property/options_spec.rb +125 -0
  165. data/spec/metro/models/properties/position_property_spec.rb +90 -0
  166. data/spec/metro/models/ui/label_spec.rb +259 -0
  167. data/spec/metro/parameters/command_line_args_parser_spec.rb +42 -0
  168. data/spec/metro/scene_spec.rb +15 -0
  169. data/spec/metro/scene_views/json_view_spec.rb +27 -0
  170. data/spec/metro/scene_views/yaml_view_spec.rb +38 -0
  171. data/spec/metro/scenes_spec.rb +77 -0
  172. data/spec/metro/units/point_spec.rb +132 -0
  173. data/spec/metro/views/view_spec.rb +53 -0
  174. data/spec/setup_handlers/exit_if_dry_run_spec.rb +27 -0
  175. data/spec/setup_handlers/reload_game_on_game_file_changes_spec.rb +68 -0
  176. data/spec/spec_helper.rb +20 -0
  177. metadata +374 -0
@@ -0,0 +1,214 @@
1
+ module Metro
2
+ module UI
3
+
4
+ #
5
+ # Draws a a menu of options. A menu model inserts itself into the scene as an event
6
+ # target as it needs to maintain the state of the menu. When an option is selected
7
+ # an event is fired based on the name of the option.
8
+ #
9
+ # @note Only one 'menu' can be defined for a given scene
10
+ #
11
+ # @example Creating a menu with basic options
12
+ #
13
+ # menu:
14
+ # model: metro::ui::menu
15
+ # position: "472.0,353.0,5.0"
16
+ # alpha: 0
17
+ # unselected_color: "rgba(119,119,119,1.0)"
18
+ # selected_color: "rgba(255,255,255,1.0)"
19
+ # options: [ 'Start Game', 'Exit' ]
20
+ #
21
+ # @example Creating a menu with a selected item
22
+ #
23
+ # menu:
24
+ # model: metro::ui::menu
25
+ # position: "472.0,353.0,5.0"
26
+ # alpha: 0
27
+ # unselected_color: "rgba(119,119,119,1.0)"
28
+ # selected_color: "rgba(255,255,255,1.0)"
29
+ # options:
30
+ # selected: 0
31
+ # items: [ 'Start Game', 'Exit' ]
32
+ #
33
+ #
34
+ # @example Creating a menu with complex options
35
+ #
36
+ # menu:
37
+ # model: metro::ui::menu
38
+ # position: "472.0,353.0,5.0"
39
+ # alpha: 0
40
+ # layout: vertical
41
+ # # layout: horizontal
42
+ # unselected_color: "rgba(119,119,119,1.0)"
43
+ # selected_color: "rgba(255,255,255,1.0)"
44
+ # options:
45
+ # selected: 1
46
+ # items:
47
+ # -
48
+ # model: "metro::ui::label"
49
+ # text: "Start Game"
50
+ # action: start_game
51
+ # -
52
+ # model: metro::ui::label
53
+ # text: Exit
54
+ # action: exit_game
55
+ #
56
+ #
57
+ class Menu < Model
58
+
59
+ # @attribute
60
+ # The position of the menu
61
+ property :position, default: Game.center
62
+
63
+ # @attribute
64
+ # The alpha level of the menu from 0 to 255.
65
+ property :alpha, default: 255
66
+
67
+ # @attribute
68
+ # The scale at which the menu should be drawn.
69
+ property :scale, default: Scale.one
70
+
71
+ # @attribute
72
+ # The distance between each of the menu items
73
+ property :padding, default: 20
74
+
75
+ # @attribute
76
+ # The dimensions of the menu. This is based on the items within the
77
+ # menu.
78
+ property :dimensions do
79
+ Dimensions.of (right_x - left_x), (bottom_y - top_y)
80
+ end
81
+
82
+ # @attribute
83
+ # The options that are displayed in the menu. These are by default
84
+ # 'metro::ui::labels' But can be defined more dynamically as neeeded.
85
+ #
86
+ # @see Metro::Model::Property::OptionsProperty
87
+ property :options
88
+
89
+ # @attribute
90
+ # The color for all the currently unselected items.
91
+ property :unselected_color, type: :color, default: "rgba(119,119,119,1.0)"
92
+
93
+ # @attribute
94
+ # The color of the item that currently has focus.
95
+ property :selected_color, type: :color, default: "rgba(255,255,255,1.0)"
96
+
97
+ def alpha_changed(alpha)
98
+ adjust_alpha_on_colors(alpha)
99
+ options.each { |option| option.alpha = alpha.floor }
100
+ end
101
+
102
+ def adjust_alpha_on_colors(alpha)
103
+ self.selected_color_alpha = alpha
104
+ self.unselected_color_alpha = alpha
105
+ end
106
+
107
+ # @attribute
108
+ # The sample sound that plays when a selection has been made.
109
+ property :selection_sample, type: :sample, path: "menu-selection.wav"
110
+
111
+ # @attribute
112
+ # The sample sound when moving between the different options in the menu.
113
+ property :movement_sample, type: :sample, path: "menu-movement.wav"
114
+
115
+ # @attribute
116
+ # Determines whether the menu is currently enabled or disabled.
117
+ property :enabled, type: :boolean, default: true
118
+
119
+ # @attribute
120
+ # Allows the menu to be layouted out in a 'horizontal' or 'vertical'
121
+ # fashion. By default this is 'vertical'
122
+ property :layout, type: :text, default: "vertical"
123
+
124
+ def bounds
125
+ Bounds.new left: left_x, right: right_x, top: top_y, bottom: bottom_y
126
+ end
127
+
128
+ #
129
+ # When the position has changed on every other time beside the first time
130
+ # we want to update the position of all the options defined in the menu.
131
+ #
132
+ def position_changed(new_position)
133
+ return unless properties[:position]
134
+ difference = Point.parse(new_position) - Point.parse(properties[:position])
135
+ options.each { |option| option.position += difference }
136
+ end
137
+
138
+ def left_x
139
+ options.map {|option| option.bounds.left }.min
140
+ end
141
+
142
+ def right_x
143
+ options.map {|option| option.bounds.right }.max
144
+ end
145
+
146
+ def top_y
147
+ options.map {|option| option.bounds.top }.min
148
+ end
149
+
150
+ def bottom_y
151
+ options.map {|option| option.bounds.bottom }.max
152
+ end
153
+
154
+ # @TODO: enable the user to define the events for this interaction
155
+ #################################################################
156
+
157
+ event :on_up, KbLeft, GpLeft, KbUp, GpUp do
158
+ if enabled
159
+ movement_sample.play
160
+ options.previous!
161
+ update_options
162
+ end
163
+ end
164
+
165
+ event :on_up, KbRight, GpRight, KbDown, GpDown do
166
+ if enabled
167
+ movement_sample.play
168
+ options.next!
169
+ update_options
170
+ end
171
+ end
172
+
173
+ event :on_up, KbEnter, KbReturn, GpButton0 do
174
+ if enabled
175
+ selection_sample.play
176
+ scene.send options.selected_action
177
+ end
178
+ end
179
+
180
+ #################################################################
181
+
182
+ def show
183
+ adjust_alpha_on_colors(alpha)
184
+
185
+ previous_width = 0
186
+
187
+ options.each_with_index do |option,index|
188
+ option.color = unselected_color
189
+ option.scale = scale
190
+
191
+ option_x = x + (layout == "horizontal" ? (previous_width + padding) * index : 0)
192
+ previous_width = option.width
193
+ option_y = y + (layout == "vertical" ? (option.height + padding) * index : 0)
194
+ option_z = z
195
+
196
+ option.position = option.position + Point.at(option_x,option_y,option_z)
197
+
198
+ end
199
+
200
+ options.selected.color = selected_color
201
+ end
202
+
203
+ def update_options
204
+ options.unselected.each { |option| option.color = unselected_color }
205
+ options.selected.color = selected_color
206
+ end
207
+
208
+ def draw
209
+ options.each { |label| label.draw }
210
+ end
211
+
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,65 @@
1
+ module Metro
2
+ module UI
3
+
4
+ #
5
+ # The model label will draw a bounding box and label around another model
6
+ #
7
+ # The model label is used by the model labeler which is a facet of the
8
+ # edit scene
9
+ #
10
+ class ModelLabel < Model
11
+
12
+ # Stores the model that is currently being labeled.
13
+ attr_accessor :target
14
+
15
+ def bounds=(bounds)
16
+ bounding_box.position = bounds.top_left
17
+ label.position = bounds.top_left + Point.at(4,2,label_z_order)
18
+ label_background.position = label.position - Point.at(2,0,1)
19
+ end
20
+
21
+ property :bounding_box_color, type: :color, default: "rgba(255,0,0,0.5)"
22
+ property :font, default: { size: 16 }
23
+ property :label_color, type: :color, default: "rgba(255,255,255,1.0)"
24
+ property :label_background_color, type: :color, default: "rgba(255,0,0,0.5)"
25
+
26
+ property :should_draw_bounding_box, type: :boolean, default: true
27
+ property :should_draw_label, type: :boolean, default: true
28
+
29
+ property :bounding_box, type: :model do
30
+ create "metro::ui::border", color: bounding_box_color,
31
+ dimensions: target.bounds.dimensions
32
+ end
33
+
34
+ property :label, type: :model do
35
+ create "metro::ui::label", text: target.name, font: font,
36
+ position: target.bounds.top_left + Point.at(4,2,label_z_order)
37
+ end
38
+
39
+ def label_z_order
40
+ target.respond_to?(:z_order) ? target.z_order + 2 : 0
41
+ end
42
+
43
+ property :label_background, type: :model do
44
+ create "metro::ui::rectangle", color: label_background_color,
45
+ position: label.position - Point.at(2,0,1),
46
+ dimensions: label.dimensions + Dimensions.of(6,4)
47
+ end
48
+
49
+ def draw
50
+ draw_bounding_box if should_draw_bounding_box
51
+ draw_label if should_draw_label
52
+ end
53
+
54
+ def draw_bounding_box
55
+ bounding_box.draw
56
+ end
57
+
58
+ def draw_label
59
+ label_background.draw
60
+ label.draw
61
+ end
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,79 @@
1
+ module Metro
2
+ module UI
3
+
4
+ #
5
+ # The model labeler will draw a bounding box and label around all the
6
+ # scene's drawers.
7
+ #
8
+ # The model labeler is used in the edit transition scene to generate
9
+ # the bounding boxes and labeles around all the actors within the scene
10
+ # being edited.
11
+ #
12
+ class ModelLabeler < Model
13
+
14
+ # @attribute
15
+ # The color use for the border surrounding each actor and the background
16
+ # behind the model's name.
17
+ property :color, default: "rgba(255,0,0,0.5)"
18
+
19
+ # @attribute
20
+ # Sets whether to draw the bounding boxes around the actors.
21
+ property :should_draw_bounding_boxes, type: :boolean, default: true
22
+
23
+ # @attribute
24
+ # The color of the model name text.
25
+ property :label_color, default: "rgba(255,255,255,1.0)"
26
+
27
+ # @attribute
28
+ # The font of the model name label.
29
+ property :font, default: { name: 'Arial', size: 16 }
30
+
31
+ # @attribute
32
+ # Sets whether to draw the model name labels
33
+ property :should_draw_labels, type: :boolean, default: true
34
+
35
+ # @attribute
36
+ # For actors that have no bounds, like sound or custom models without
37
+ # a position, they are normally hidden but can be shown. Currently they
38
+ # appear all overlapped in the upper-left corner of the screen.
39
+ #
40
+ # @todo when enabled the boundless actors should be presented in a cleaner
41
+ # way to allow for easier viewing of them.
42
+ property :should_hide_boundless_actors, type: :boolean, default: true
43
+
44
+ # Store the labels that are being drawn in the scene. This hash of labels
45
+ # acts as a cache around the items that are being labeled based on the
46
+ # name of the objects that are being labeled.
47
+ def labels
48
+ @labels ||= {}
49
+ end
50
+
51
+ def show
52
+ self.saveable_to_view = false
53
+ end
54
+
55
+ def update
56
+ scene.drawers.each do |drawer|
57
+ next if (drawer.bounds == Bounds.none and should_hide_boundless_actors)
58
+ label = labels[drawer.name]
59
+
60
+ unless label
61
+ label = create "metro::ui::model_label", target: drawer
62
+ labels[drawer.name] = label
63
+ end
64
+
65
+ label.should_draw_label = should_draw_labels
66
+ label.should_draw_bounding_box = should_draw_bounding_boxes
67
+ label.bounds = drawer.bounds
68
+ end
69
+
70
+ end
71
+
72
+ def draw
73
+ labels.values.each { |label| label.draw }
74
+ end
75
+
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,59 @@
1
+ module Metro
2
+ module UI
3
+
4
+ #
5
+ # The rectangle will draw a rectangle from the specified position out to the specified
6
+ # dimensions in the specified color.
7
+ #
8
+ # @example Drawing a red rectangle that starts at (20,20) and is 200 by 200
9
+ #
10
+ # class IntroScene < GameScene
11
+ # draw :backdrop, model: "metro::ui::rectangle", position: "20,20",
12
+ # color: "rgba(255,0,0,1.0)", dimensions: "200,200"
13
+ # end
14
+ #
15
+ class Rectangle < Model
16
+
17
+ # @attribute
18
+ # The position of the upper-left corner of the rectangle
19
+ property :position
20
+
21
+ # @attribute
22
+ # The color to rectangle
23
+ property :color
24
+
25
+ # @attribute
26
+ # The dimensions of the rectangle
27
+ property :dimensions do
28
+ window.dimensions
29
+ end
30
+
31
+ def draw
32
+ window.draw_quad(left_x,top_y,color,
33
+ right_x,top_y,color,
34
+ right_x,bottom_y,color,
35
+ left_x,bottom_y,color,
36
+ z_order)
37
+ end
38
+
39
+ private
40
+
41
+ def left_x
42
+ x
43
+ end
44
+
45
+ def right_x
46
+ x + width
47
+ end
48
+
49
+ def top_y
50
+ y
51
+ end
52
+
53
+ def bottom_y
54
+ y + height
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,79 @@
1
+ module Metro
2
+ module UI
3
+
4
+ #
5
+ # A sprite is a Metro model that is specially designed to draw and manage
6
+ # an image. A sprite maintains an image, location information, and rotation.
7
+ #
8
+ class Sprite < Model
9
+
10
+ # @attribute
11
+ # The image that will be drawn for the sprite
12
+ property :image
13
+
14
+ # @attribute
15
+ # The point at which the sprite should be drawn
16
+ property :position
17
+
18
+ # @attribute
19
+ # This is the color of the spirte. The color usually remains white, and
20
+ # the color property is implemented by the `alpha` value is the one thing
21
+ # that is altered to fade in and fade out the sprite.
22
+ property :color
23
+
24
+ # @attribute
25
+ # The scale at which to draw the sprite. This is default scale of 1.
26
+ property :scale
27
+
28
+ # @attribute
29
+ # The center, horizontal position, as expressed in a ratio, of the image.
30
+ property :center_x, type: :numeric, default: 0.5
31
+
32
+ # @attribute
33
+ # The center, vertical position, as expressed in a ratio, of the image.
34
+ property :center_y, type: :numeric, default: 0.5
35
+
36
+ # @attribute
37
+ # The angle at which the sprite should be drawn. This is by default 0.
38
+ property :angle
39
+
40
+ # @attribute
41
+ # The height and width of the sprite is based on the image of the sprite.
42
+ property :dimensions do
43
+ image.dimensions
44
+ end
45
+
46
+ # @return [RectangleBounds] the bounds of the sprite.
47
+ def bounds
48
+ Bounds.new left: left, right: right, top: top, bottom: bottom
49
+ end
50
+
51
+ # @return [Float] the left-most x position of the sprite
52
+ def left
53
+ x - width * center_x
54
+ end
55
+
56
+ # @return [Float] the right-most x position of the sprite
57
+ def right
58
+ left + width * x_factor
59
+ end
60
+
61
+ # @return [Float] the top-most y position of the sprite
62
+ def top
63
+ y - height * center_y
64
+ end
65
+
66
+ # @return [Float] the bottom-most y position of the sprite
67
+ def bottom
68
+ top + height * y_factor
69
+ end
70
+
71
+ #
72
+ # By default the sprite will draw the image defined for it.
73
+ #
74
+ def draw
75
+ image.draw_rot x, y, z_order, angle, center_x, center_y, x_factor, y_factor, color
76
+ end
77
+ end
78
+ end
79
+ end