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,34 @@
1
+ module Metro
2
+ module Views
3
+
4
+ class NoView
5
+
6
+ #
7
+ # A NoView is a last resort view which means this is will always will exist.
8
+ #
9
+ # @param [String] view_path the name of the view to find
10
+ # @return a true all the time as this is the last resort format.
11
+ #
12
+ def self.exists?(view_path)
13
+ true
14
+ end
15
+
16
+ #
17
+ # A NoView will return an empty Hash to provide compatibility with other view
18
+ # types.
19
+ #
20
+ def self.parse(view_path)
21
+ {}
22
+ end
23
+
24
+ #
25
+ # @return the file type format of this view.
26
+ #
27
+ def self.format
28
+ :none
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,42 @@
1
+ require_relative 'yaml_view'
2
+ require_relative 'json_view'
3
+ require_relative 'no_view'
4
+
5
+ module Metro
6
+ module Views
7
+
8
+ module Parsers
9
+ extend self
10
+
11
+ #
12
+ # Register a view parser.
13
+ #
14
+ # A parser is any class or instance that responds to #exists?(view_path),
15
+ # #parse(view_path) and #format.
16
+ #
17
+ # @param [Parser] parser the parser to add to the list of available parsers.
18
+ #
19
+ def register(parser)
20
+ parsers.push parser
21
+ end
22
+
23
+ #
24
+ # @return [Array<Parsers>] an array of all the registered view parsers. The
25
+ # last parser is the NoView parser.
26
+ #
27
+ def parsers
28
+ @parsers ||= []
29
+ end
30
+
31
+ def parsers_with_no_view_fallback
32
+ parsers + [ NoView ]
33
+ end
34
+
35
+ end
36
+
37
+ Parsers.register YAMLView
38
+ Parsers.register JSONView
39
+
40
+ end
41
+ end
42
+
@@ -0,0 +1,107 @@
1
+ require_relative 'view'
2
+
3
+ module Metro
4
+
5
+ #
6
+ # SceneView provides support for a Scene to have a view as well as giving
7
+ # additional tools to also help draw that view.
8
+ #
9
+ module SceneView
10
+
11
+ #
12
+ # A Scene by default uses the name of the Scene to find it's associated
13
+ # view.
14
+ #
15
+ # @example Standard View Name
16
+ #
17
+ # class OpeningScene < Metro::Scene
18
+ #
19
+ # def show
20
+ # puts "View Brought To You By: #{view_name} # => View Brought To You By opening
21
+ # end
22
+ # end
23
+ #
24
+ # @example Custom View Name
25
+ #
26
+ # class ClosingScene < Metro::Scene
27
+ # view_name 'alternative'
28
+ #
29
+ # def show
30
+ # puts "View Brought To You By: #{view_name} # => View Brought To You By alternative
31
+ # end
32
+ # end
33
+ #
34
+ def view_name
35
+ self.class.view_name
36
+ end
37
+
38
+ #
39
+ # @return the view for this scene.
40
+ #
41
+ def view
42
+ self.class.view
43
+ end
44
+
45
+ #
46
+ # Loads and caches the view content based on the avilable view parsers and
47
+ # the view files defined.
48
+ #
49
+ # @return the content contained within the view
50
+ #
51
+ def view_content
52
+ view.content
53
+ end
54
+
55
+ #
56
+ # Saves the current content of the view back through the view's writer
57
+ #
58
+ def save_view
59
+ view.content = self.to_hash
60
+ view.save
61
+ end
62
+
63
+ #
64
+ # When the module is included insure that all the class helper methods are added
65
+ # at the same time.
66
+ #
67
+ def self.included(base)
68
+ base.extend ClassMethods
69
+ end
70
+
71
+ module ClassMethods
72
+
73
+ #
74
+ # A Scene by default uses the name of the Scene to find it's associated
75
+ # view.
76
+ #
77
+ # @example Custom View Name
78
+ #
79
+ # class ClosingScene < Metro::Scene
80
+ # view_name 'alternative'
81
+ # end
82
+ #
83
+ # ClosingScene.view_name # => views/alternative
84
+ #
85
+ def view_name(name = nil)
86
+ name ? view.name = name : view.name
87
+ view.name
88
+ end
89
+
90
+ #
91
+ # Loads and caches the view content based on the avilable view parsers and
92
+ # the view files defined.
93
+ #
94
+ # @return a view object
95
+ #
96
+ def view
97
+ @view ||=begin
98
+ view = View.new
99
+ view.name = scene_name
100
+ view
101
+ end
102
+ end
103
+
104
+ end
105
+
106
+ end
107
+ end
@@ -0,0 +1,133 @@
1
+ require_relative 'parsers'
2
+ require_relative 'writers'
3
+
4
+ module Metro
5
+
6
+ #
7
+ # A view represents the representation of the content found within
8
+ # the view file. A view has the ability to save/load the content
9
+ # as well.
10
+ #
11
+ class View
12
+
13
+ #
14
+ # The name of the view, which is used to influence the file path.
15
+ #
16
+ attr_accessor :name
17
+
18
+ #
19
+ # The content contained within the view.
20
+ #
21
+ def content
22
+ @content ||= begin
23
+ parsed_content = parse
24
+ parsed_content.default = {}
25
+ parsed_content
26
+ end
27
+ end
28
+
29
+ #
30
+ # Set the content of the view.
31
+ #
32
+ # @param [Hash] value the hash content that will represent this view
33
+ #
34
+ def content=(value)
35
+ value.default = {}
36
+ @content = value
37
+ end
38
+
39
+ #
40
+ # A Scene view path is based on the view name.
41
+ #
42
+ # @example Standard View Path
43
+ #
44
+ # class OpeningScene < Metro::Scene
45
+ # end
46
+ #
47
+ # OpeniningScene.view_path # => views/opening
48
+ #
49
+ # @example Custom View Path
50
+ #
51
+ # class ClosingScene < Metro::Scene
52
+ # view_name 'alternative'
53
+ # end
54
+ #
55
+ # ClosingScene.view_path # => views/alternative
56
+ #
57
+ def view_path
58
+ File.join "views", name
59
+ end
60
+
61
+ #
62
+ # Parse the content found at the view path for the view.
63
+ #
64
+ # @return the hash of content stored within the view file.
65
+ #
66
+ def parse
67
+ parser.parse(view_path)
68
+ end
69
+
70
+ #
71
+ # The parser for this view is one of the supported parsers. A parser
72
+ # is selected if the parser is capable of finding the content to
73
+ # load.
74
+ #
75
+ def parser
76
+ @parser ||= supported_parsers.find { |parser| parser.exists? view_path }
77
+ end
78
+
79
+ #
80
+ # Supported view formats
81
+ #
82
+ def supported_parsers
83
+ Views::Parsers.parsers_with_no_view_fallback
84
+ end
85
+
86
+ #
87
+ # Ask the parser to save the current content of the view at the view path
88
+ #
89
+ def save
90
+ writer.write(view_path,content)
91
+ end
92
+
93
+ #
94
+ # Return the format of the view. By default the format of the view is dictated
95
+ # by the format of the content that is parsed.
96
+ #
97
+ def format
98
+ @format || parser.format
99
+ end
100
+
101
+ #
102
+ # Setting the format allows the view to be changed from the current format as
103
+ # dictated what is parsed by the parser.
104
+ #
105
+ # This is mostly to benefit the edit transition scene which inherits all the view
106
+ # related data from the scene that is being edited but does not inherit the
107
+ # the view (which would have the parser).
108
+ #
109
+ # @see EditTransitionScene
110
+ #
111
+ attr_writer :format
112
+
113
+ #
114
+ # The writer for this view. If the view has already been parsed then use
115
+ #
116
+ def writer
117
+ @writer ||= begin
118
+ writer_matching_existing_parser = supported_writers.find { |writer| writer.format == format }
119
+ writer_matching_existing_parser || default_writer
120
+ end
121
+ end
122
+
123
+ def supported_writers
124
+ Views::Writers.writers
125
+ end
126
+
127
+ def default_writer
128
+ Views::Writers.default_writer
129
+ end
130
+
131
+ end
132
+
133
+ end
@@ -0,0 +1,43 @@
1
+ require_relative 'yaml_view'
2
+ require_relative 'json_view'
3
+
4
+ module Metro
5
+ module Views
6
+
7
+ module Writers
8
+ extend self
9
+
10
+ #
11
+ # Register a view writer
12
+ #
13
+ # A writer is any class or instance that responds to #write(view_path,content),
14
+ # and #format.
15
+ #
16
+ # @param [Writer] writer the writer to add to the list of available writers..
17
+ #
18
+ def register(writer)
19
+ writers.push writer
20
+ end
21
+
22
+ #
23
+ # @return [Array<Writers>] an array of all the registered view writers.
24
+ #
25
+ def writers
26
+ @writers ||= []
27
+ end
28
+
29
+ #
30
+ # The default view writer, this is the one that will be used if no view
31
+ # can be found by the writers.
32
+ #
33
+ attr_accessor :default_writer
34
+
35
+ end
36
+
37
+ Writers.register YAMLView
38
+ Writers.register JSONView
39
+ Writers.default_writer = YAMLView
40
+
41
+ end
42
+ end
43
+
@@ -0,0 +1,94 @@
1
+ require 'yaml'
2
+
3
+ module Metro
4
+ module Views
5
+
6
+ class YAMLView
7
+
8
+ #
9
+ # Determine if a view exists for this specified format
10
+ #
11
+ # @param [String] view_path the name of the view to find
12
+ # @return a true if the yaml view exists and false if it does not exist.
13
+ #
14
+ def self.exists?(view_path)
15
+ yaml_view_paths(view_path).find { |view_path| File.exists? view_path }
16
+ end
17
+
18
+ #
19
+ # Parse the contents of the view given the name.
20
+ #
21
+ # @param [String] view_path the name of the view to read
22
+ # @return a Hash that contains the contents of the view.
23
+ #
24
+ def self.parse(view_path)
25
+ YAML.load(File.read(yaml_view_path(view_path))) or { }
26
+ end
27
+
28
+ #
29
+ # @return the file type format of this view.
30
+ #
31
+ def self.format
32
+ :yaml
33
+ end
34
+
35
+ #
36
+ # @param [String] view_path the file path to the view which to save the content
37
+ # @param [Hash] content the content to save within the view
38
+ #
39
+ def self.write(view_path,content)
40
+ filename = write_filepath(view_path)
41
+ yaml_content = content.to_yaml
42
+ File.write(filename,yaml_content)
43
+ end
44
+
45
+ #
46
+ # @return the default extension to use when saving yaml files.
47
+ #
48
+ def self.default_extname
49
+ @default_extname || ".yaml"
50
+ end
51
+
52
+ #
53
+ # Set the default extname
54
+ #
55
+ # @example
56
+ #
57
+ # Metro::Views::YAMLView.default_extname = ".yml"
58
+ #
59
+ def self.default_extname=(value)
60
+ @default_extname = value
61
+ end
62
+
63
+ private
64
+
65
+ #
66
+ # If a file already exists with .yaml or .yml use that extension. Otherwise, we
67
+ # will fall back to the default extension name.
68
+ #
69
+ def self.write_filepath(view_path)
70
+ if existing_file = exists?(view_path)
71
+ existing_file
72
+ else
73
+ "#{view_path}#{default_extname}"
74
+ end
75
+ end
76
+
77
+ #
78
+ # A helper method to get the view file.
79
+ #
80
+ def self.yaml_view_path(view_path)
81
+ yaml_view_paths(view_path).find { |view_path| File.exists? view_path }
82
+ end
83
+
84
+ #
85
+ # A helper method to generate the name of the yaml view file. In this case
86
+ # it is the view name with the suffix `.yaml` or `.yml`.
87
+ #
88
+ def self.yaml_view_paths(view_path)
89
+ File.extname(view_path) == "" ? [ "#{view_path}.yaml", "#{view_path}.yml" ] : [ view_path ]
90
+ end
91
+ end
92
+
93
+ end
94
+ end