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,154 @@
1
+ module Metro
2
+
3
+ #
4
+ # @example Finding a scene based on the scene name
5
+ #
6
+ # class IntroScene < Metro::Scene
7
+ # # ... scene content ...
8
+ # end
9
+ #
10
+ # Scenes.find("intro") # => IntroScene
11
+ # Scenes.find(:intro) # => IntroScene
12
+ #
13
+ # @example Creating a scene instance based on the scene name
14
+ #
15
+ # class IntroScene < Metro::Scene
16
+ # # ... scene content ...
17
+ # end
18
+ #
19
+ # Scenes.generate("intro") # => [SCENE: title]
20
+ # Scenes.generate(:intro) # => [SCENE: title]
21
+ #
22
+ # @example Finding a scene that does not exist
23
+ #
24
+ # scene = Scenes.find(:unknown)
25
+ # scene.missing_scene # => :unknown
26
+ #
27
+ module Scenes
28
+ extend self
29
+
30
+ #
31
+ # Add a scene to the hash of scenes with the scene name of the scene as the key
32
+ # to retrieving this scene.
33
+ #
34
+ # @param [Scene] scene the scene to be added to the hash of Scenes.
35
+ #
36
+ def add(scene)
37
+ all_scenes_for(scene).each { |scene| scenes_hash[scene.scene_name] = scene.to_s }
38
+ end
39
+
40
+ #
41
+ # Finds the scene based on the specified scene name.
42
+ #
43
+ # @param [String,Symbol] scene_name the name of the scene to locate.
44
+ # @return the Scene class that is found matching the specified scene name.
45
+ #
46
+ def find(scene_name)
47
+ scenes_hash[scene_name].constantize
48
+ end
49
+
50
+ #
51
+ # @return [Array<String>] all the names supported by the scenes hash.
52
+ #
53
+ def list
54
+ scenes_hash.keys
55
+ end
56
+
57
+ #
58
+ # Finds the scene with the specified name and then creates an instance of that
59
+ # scene.
60
+ #
61
+ # @param [String,Symbol,Object] scene_name the name of the scene to locate.
62
+ # @return an instance of Scene that is found matching the specified scene name
63
+ #
64
+ def generate(scene_or_scene_name,options = {})
65
+ new_scene = generate_scene_from(scene_or_scene_name)
66
+ apply_post_filters(new_scene,options)
67
+ end
68
+
69
+ #
70
+ # If we have been given a scene, then we simply want to use it otherwise
71
+ # we need to find and generate our scene from the scene name.
72
+ #
73
+ # @param [String,Sybmol,Class] scene_or_scene_name the name of the scene or an instance
74
+ # of Scene.
75
+ #
76
+ def generate_scene_from(scene_or_scene_name)
77
+ if scene_or_scene_name.is_a? Scene
78
+ scene_or_scene_name
79
+ else
80
+ find(scene_or_scene_name).new
81
+ end
82
+ end
83
+
84
+ #
85
+ # Post filters are applied to the scene after it has been found. These are
86
+ # all objects that can respond to the #filter method.
87
+ #
88
+ def post_filters
89
+ @post_filters ||= []
90
+ end
91
+
92
+ #
93
+ # Register a filter that will be executed after a scene is found and generated. This
94
+ # allows for the scene to be modified or changed based on the provided options.
95
+ #
96
+ # A filter is any object that responds to #filter and accepts two parameters: the
97
+ # scene and a hash of options.
98
+ #
99
+ # @param [#filter] post_filter a filter is an object that can act as a filter.
100
+ #
101
+ def register_post_filter(post_filter)
102
+ post_filters.push(post_filter)
103
+ end
104
+
105
+ private
106
+
107
+ #
108
+ # Apply all the post filtering to the specified scene with the given options
109
+ #
110
+ # @return a Scene object that has been filtered.
111
+ #
112
+ def apply_post_filters(new_scene,options)
113
+ post_filters.inject(new_scene) {|scene,post| post.filter(scene,options) }
114
+ end
115
+
116
+ #
117
+ # @return a Hash that allows for accessing symbol names of the scenes
118
+ # as well as the class name constants to allow for the scenes to be found.
119
+ #
120
+ def scenes_hash
121
+ @scenes_hash ||= hash_with_missing_scene_default
122
+ end
123
+
124
+ #
125
+ # Create a hash that will return a setup missing scene by default.
126
+ #
127
+ def hash_with_missing_scene_default
128
+ hash = HashWithIndifferentAccess.new do |hash,key|
129
+ missing_scene = hash[:missing_scene].constantize
130
+ missing_scene.missing_scene = key.to_sym
131
+ missing_scene
132
+ end
133
+ hash[:missing_scene] = "Metro::MissingScene"
134
+ hash
135
+ end
136
+
137
+ #
138
+ # Returns all subclassed scenes of the scene or scenes provided. This method is
139
+ # meant to be called recursively to generate the entire list of all the scenes.
140
+ #
141
+ # @param [Scene,Array<Scene>] scenes a scene or scene subclass or an array of
142
+ # scene subclasses.
143
+ #
144
+ def all_scenes_for(scenes)
145
+ Array(scenes).map do |scene_class_name|
146
+ scene = scene_class_name.constantize
147
+ [ scene ] + all_scenes_for(scene.scenes)
148
+ end.flatten.compact
149
+ end
150
+
151
+ end
152
+ end
153
+
154
+ require_relative 'transitions/scene_transitions'
@@ -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
@@ -0,0 +1,60 @@
1
+ class TemplateMessage
2
+
3
+ def initialize(details = {})
4
+ @messages = Array(details[:message]) + Array(details[:messages])
5
+ @details = details[:details]
6
+ @website = details[:website]
7
+ @email = details[:contact]
8
+ end
9
+
10
+ class Message
11
+
12
+ attr_reader :name, :details
13
+
14
+ def initialize(name,details)
15
+ @name = name
16
+ @details = details
17
+ end
18
+
19
+ def field_locale(field)
20
+ I18n.t("#{name}.#{field}",details)
21
+ end
22
+
23
+ def title
24
+ field_locale 'title'
25
+ end
26
+
27
+ def message
28
+ field_locale 'message'
29
+ end
30
+
31
+ def actions
32
+ Array( field_locale('actions') ).map {|action| "* #{action}" }.join("\n")
33
+ end
34
+ end
35
+
36
+ def messages
37
+ @messages.map {|m| Message.new m, @details }
38
+ end
39
+
40
+ def website
41
+ Array(@website).map {|website| "* #{website}" }.join("\n")
42
+ end
43
+
44
+ def email
45
+ Array(@email).map {|email| "* #{email}" }.join("\n")
46
+ end
47
+
48
+ def message_filename
49
+ File.join(File.dirname(__FILE__),"..","templates","message.erb")
50
+ end
51
+
52
+ def message_template
53
+ File.read(message_filename)
54
+ end
55
+
56
+ def to_s
57
+ ERB.new(message_template).result(binding)
58
+ end
59
+
60
+ end
@@ -0,0 +1,100 @@
1
+ require_relative '../events/hit_list'
2
+
3
+ module Metro
4
+
5
+ #
6
+ # The Edit Transition Scene is place where scenes go to be edited. Any scene
7
+ # can transition into edit mode. This scene will copy all the actors and
8
+ # gain access to the view.
9
+ #
10
+ # This scene grants new keyboard commands that will enable, disable, and
11
+ # toggle feature of edit mode:
12
+ #
13
+ # * `e` will end edit mode
14
+ # * `g` will toggle the display of the grid
15
+ # * `l` will toggle the display of the model labels
16
+ # * `b` will toggle the bounding boxes around the models.
17
+ #
18
+ class EditTransitionScene < Metro::TransitionScene
19
+
20
+ def initialize
21
+ #
22
+ # The EditTransitionScene needs to have all the drawers
23
+ # cleared from the class because it may still have
24
+ # drawers from other things that this was executed.
25
+ #
26
+ # This is a product of using the classes to store the definitions
27
+ # of scene. This means we need to change this so that it is much
28
+ # easier to dup scenes.
29
+ #
30
+ self.class.drawings.clear
31
+ self.class.draw :overlay, model: "metro::ui::grid_drawer"
32
+ self.class.draw :labeler, model: "metro::ui::model_labeler"
33
+ add_actors_to_scene
34
+ after_initialize
35
+ end
36
+
37
+ def prepare_transition_from(old_scene)
38
+ next_scene.prepare_transition_from(old_scene)
39
+ @previous_scene = old_scene
40
+
41
+ # Set the view name to the previous scene's view name
42
+ self.class.view_name old_scene.view_name
43
+ self.class.view.format = old_scene.class.view.format
44
+
45
+ # import all the actors from the previous scene into the current scene.
46
+ old_scene.class.actors.each do |scene_actor|
47
+ self.class.draw scene_actor.name, scene_actor.options
48
+ end
49
+
50
+ add_actors_to_scene
51
+ end
52
+
53
+ def show
54
+ window.show_cursor
55
+ end
56
+
57
+ event :on_up, KbE do
58
+ transition_to next_scene.scene_name
59
+ end
60
+
61
+ event :on_up, KbG do
62
+ overlay.enabled = !overlay.enabled
63
+ end
64
+
65
+ event :on_up, KbL do
66
+ labeler.should_draw_labels = !labeler.should_draw_labels
67
+ end
68
+
69
+ event :on_up, KbB do
70
+ labeler.should_draw_bounding_boxes = !labeler.should_draw_bounding_boxes
71
+ end
72
+
73
+ #
74
+ # Generate a hitlist which manages the click start, hold, and release
75
+ # of the mouse button.
76
+ #
77
+ def hitlist
78
+ @hitlist ||= HitList.new(drawers)
79
+ end
80
+
81
+ event :on_down, MsLeft do |event|
82
+ hitlist.hit(event)
83
+ end
84
+
85
+ event :on_hold, MsLeft do |event|
86
+ hitlist.update(event)
87
+ end
88
+
89
+ event :on_up, MsLeft do |event|
90
+ hitlist.release(event)
91
+ end
92
+
93
+ event :on_up, KbS do
94
+ log.info "Saving changes to Scene #{previous_scene} View - #{view_name}"
95
+ save_view
96
+ end
97
+
98
+ end
99
+
100
+ end
@@ -0,0 +1,66 @@
1
+ module Metro
2
+ class FadeTransitionScene < TransitionScene
3
+
4
+ draw :rectangle, model: "metro::ui::rectangle"
5
+
6
+ #
7
+ # When the scene is shown set up the starting color for the rectangle
8
+ # and queue the animation to transition the color to the final color.
9
+ #
10
+ def show
11
+ rectangle.color = starting_color
12
+
13
+ color = final_color
14
+
15
+ animate :rectangle, to: { red: color.red,
16
+ green: color.green,
17
+ blue: color.blue,
18
+ alpha: color.alpha },
19
+ interval: interval do
20
+
21
+ transition_to next_scene
22
+ end
23
+ end
24
+
25
+ def interval
26
+ options[:interval] || default_interval
27
+ end
28
+
29
+ def default_interval
30
+ 60
31
+ end
32
+
33
+ def starting_color
34
+ options_starting_color || default_starting_color
35
+ end
36
+
37
+ def options_starting_color
38
+ color_from_options(:from)
39
+ end
40
+
41
+ def default_starting_color
42
+ Gosu::Color.new "rgb(255,255,255)"
43
+ end
44
+
45
+ def final_color
46
+ options_final_color || default_final_color
47
+ end
48
+
49
+ def options_final_color
50
+ color_from_options(:to)
51
+ end
52
+
53
+ def default_final_color
54
+ Gosu::Color.new "rgb(0,0,0)"
55
+ end
56
+
57
+ def color_from_options(position)
58
+ if options[position]
59
+ if options[position][:color]
60
+ Gosu::Color.new options[position][:color]
61
+ end
62
+ end
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,44 @@
1
+ require_relative 'transition_scene'
2
+
3
+ module Metro
4
+ module SceneTransitions
5
+ extend self
6
+
7
+ def insert_transition(scene,options)
8
+ return scene unless options.key?(:with)
9
+ name = options[:with]
10
+ generate_transition(name,scene,options)
11
+ end
12
+
13
+ alias_method :filter, :insert_transition
14
+
15
+ def generate_transition(name,next_scene,options)
16
+ transition = find_transition(name).new
17
+ transition.next_scene = next_scene
18
+ transition.options = options
19
+ transition
20
+ end
21
+
22
+ def find_transition(name)
23
+ transition_name = supported_transitions[name]
24
+ transition_name.constantize
25
+ end
26
+
27
+ def supported_transitions
28
+ @supported_transitions ||= begin
29
+ hash = HashWithIndifferentAccess.new("Metro::FadeTransitionScene")
30
+ hash[:edit] = "Metro::EditTransitionScene"
31
+ hash
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ #
38
+ # The Scene Transition should act as a filter and allow for
39
+ # common or custom scenes to be inserted between the scene
40
+ # that was about to be displayed.
41
+ #
42
+ Scenes.register_post_filter SceneTransitions
43
+
44
+ end