metro-ld26 0.3.4

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 (185) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +14 -0
  6. data/Guardfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +177 -0
  9. data/Rakefile +18 -0
  10. data/bin/metro +16 -0
  11. data/changelog.md +153 -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 +144 -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 +342 -0
  47. data/lib/metro/events/event_state_manager.rb +70 -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 +75 -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 +246 -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 +98 -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 +132 -0
  96. data/lib/metro/models/ui/tmx/isometric_position.rb +43 -0
  97. data/lib/metro/models/ui/tmx/orthogonal_position.rb +15 -0
  98. data/lib/metro/models/ui/tmx/tile_layer.rb +78 -0
  99. data/lib/metro/models/ui/ui.rb +13 -0
  100. data/lib/metro/parameters/command_line_args_parser.rb +68 -0
  101. data/lib/metro/parameters/options.rb +25 -0
  102. data/lib/metro/parameters/parameters.rb +2 -0
  103. data/lib/metro/sample.rb +40 -0
  104. data/lib/metro/scene.rb +478 -0
  105. data/lib/metro/scenes.rb +154 -0
  106. data/lib/metro/song.rb +56 -0
  107. data/lib/metro/template_message.rb +60 -0
  108. data/lib/metro/transitions/edit_transition_scene.rb +100 -0
  109. data/lib/metro/transitions/fade_transition_scene.rb +66 -0
  110. data/lib/metro/transitions/scene_transitions.rb +44 -0
  111. data/lib/metro/transitions/transition_scene.rb +19 -0
  112. data/lib/metro/units/bounds.rb +8 -0
  113. data/lib/metro/units/calculation_validations.rb +74 -0
  114. data/lib/metro/units/dimensions.rb +60 -0
  115. data/lib/metro/units/point.rb +51 -0
  116. data/lib/metro/units/rectangle_bounds.rb +148 -0
  117. data/lib/metro/units/scale.rb +46 -0
  118. data/lib/metro/units/units.rb +6 -0
  119. data/lib/metro/version.rb +32 -0
  120. data/lib/metro/views/json_view.rb +60 -0
  121. data/lib/metro/views/no_view.rb +34 -0
  122. data/lib/metro/views/parsers.rb +42 -0
  123. data/lib/metro/views/scene_view.rb +107 -0
  124. data/lib/metro/views/view.rb +133 -0
  125. data/lib/metro/views/writers.rb +43 -0
  126. data/lib/metro/views/yaml_view.rb +94 -0
  127. data/lib/metro/window.rb +95 -0
  128. data/lib/setup_handlers/exit_if_dry_run.rb +26 -0
  129. data/lib/setup_handlers/game_execution.rb +65 -0
  130. data/lib/setup_handlers/load_game_configuration.rb +65 -0
  131. data/lib/setup_handlers/load_game_files.rb +101 -0
  132. data/lib/setup_handlers/move_to_game_directory.rb +25 -0
  133. data/lib/setup_handlers/reload_game_on_game_file_changes.rb +79 -0
  134. data/lib/templates/game/README.md.tt +43 -0
  135. data/lib/templates/game/assets/brand.jpg +0 -0
  136. data/lib/templates/game/assets/hero.png +0 -0
  137. data/lib/templates/game/lib/custom_easing.rb +32 -0
  138. data/lib/templates/game/metro.tt +63 -0
  139. data/lib/templates/game/models/hero.rb +62 -0
  140. data/lib/templates/game/scenes/brand_scene.rb +19 -0
  141. data/lib/templates/game/scenes/brand_to_title_scene.rb +13 -0
  142. data/lib/templates/game/scenes/first_scene.rb +28 -0
  143. data/lib/templates/game/scenes/game_scene.rb +43 -0
  144. data/lib/templates/game/scenes/title_scene.rb +15 -0
  145. data/lib/templates/game/views/brand.yaml +4 -0
  146. data/lib/templates/game/views/brand_to_title.yaml +8 -0
  147. data/lib/templates/game/views/first.yaml +26 -0
  148. data/lib/templates/game/views/title.yaml +11 -0
  149. data/lib/templates/message.erb +23 -0
  150. data/lib/templates/model.rb.tt +111 -0
  151. data/lib/templates/scene.rb.tt +140 -0
  152. data/lib/templates/view.yaml.tt +11 -0
  153. data/lib/tmx_ext/object.rb +26 -0
  154. data/lib/tmx_ext/tile_set.rb +41 -0
  155. data/metro.gemspec +57 -0
  156. data/metro.png +0 -0
  157. data/spec/core_ext/numeric_spec.rb +78 -0
  158. data/spec/core_ext/string_spec.rb +33 -0
  159. data/spec/gosu_ext/color_spec.rb +80 -0
  160. data/spec/metro/image_spec.rb +33 -0
  161. data/spec/metro/models/key_value_coding_spec.rb +61 -0
  162. data/spec/metro/models/properties/array_property_spec.rb +60 -0
  163. data/spec/metro/models/properties/color_property_spec.rb +85 -0
  164. data/spec/metro/models/properties/dimensions_spec.rb +29 -0
  165. data/spec/metro/models/properties/font_property_spec.rb +127 -0
  166. data/spec/metro/models/properties/numeric_property_spec.rb +46 -0
  167. data/spec/metro/models/properties/options_property/no_option_spec.rb +25 -0
  168. data/spec/metro/models/properties/options_property/options_property_spec.rb +133 -0
  169. data/spec/metro/models/properties/options_property/options_spec.rb +125 -0
  170. data/spec/metro/models/properties/position_property_spec.rb +90 -0
  171. data/spec/metro/models/ui/label_spec.rb +259 -0
  172. data/spec/metro/parameters/command_line_args_parser_spec.rb +42 -0
  173. data/spec/metro/scene_spec.rb +15 -0
  174. data/spec/metro/scene_views/json_view_spec.rb +27 -0
  175. data/spec/metro/scene_views/yaml_view_spec.rb +38 -0
  176. data/spec/metro/scenes_spec.rb +77 -0
  177. data/spec/metro/units/point_spec.rb +132 -0
  178. data/spec/metro/units/rectangle_bounds_spec.rb +56 -0
  179. data/spec/metro/views/view_spec.rb +53 -0
  180. data/spec/setup_handlers/exit_if_dry_run_spec.rb +27 -0
  181. data/spec/setup_handlers/reload_game_on_game_file_changes_spec.rb +68 -0
  182. data/spec/spec_helper.rb +20 -0
  183. data/spec/tmx_ext/object_spec.rb +96 -0
  184. data/spec/tmx_ext/tile_set_spec.rb +24 -0
  185. metadata +379 -0
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,13 @@
1
+ module Metro
2
+
3
+ class GenerateGame < Generator
4
+
5
+ argument :name
6
+
7
+ def create_metro_file
8
+ directory "game", name
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,25 @@
1
+ module Metro
2
+
3
+ class GenerateModel < Generator
4
+
5
+ no_tasks do
6
+
7
+ def model_filename
8
+ name.underscore
9
+ end
10
+
11
+ def model_name
12
+ name.camelize
13
+ end
14
+
15
+ end
16
+
17
+ argument :name
18
+
19
+ def create_model_file
20
+ template "model.rb.tt", "models/#{model_filename}.rb"
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,36 @@
1
+ module Metro
2
+
3
+ class GenerateScene < Generator
4
+
5
+ no_tasks do
6
+
7
+ def scene_filename
8
+ scene_name = name.gsub(/_?Scene$/i,'')
9
+ "#{scene_name.underscore}_scene"
10
+ end
11
+
12
+ def scene_class_name
13
+ scene_name = name.gsub(/_?Scene$/i,'')
14
+ "#{scene_name.camelize}Scene"
15
+ end
16
+
17
+ def view_filename
18
+ view_name = name.to_s.gsub(/_?Scene$/i,'')
19
+ view_name.underscore
20
+ end
21
+
22
+ end
23
+
24
+ argument :name
25
+
26
+ def create_scene_file
27
+ template "scene.rb.tt", "scenes/#{scene_filename}.rb"
28
+ end
29
+
30
+ def create_view_file
31
+ template "view.yaml.tt", "views/#{view_filename}.yaml"
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,21 @@
1
+ module Metro
2
+
3
+ class GenerateView < Generator
4
+
5
+ no_tasks do
6
+
7
+ def view_filename
8
+ view_name = name.to_s.gsub(/_?Scene$/i,'')
9
+ view_name.underscore
10
+ end
11
+
12
+ end
13
+
14
+ argument :name
15
+
16
+ def create_view_file
17
+ template "view.yaml.tt", "views/#{view_filename}.yaml"
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,83 @@
1
+ require 'thor'
2
+ require 'thor/group'
3
+
4
+ module Metro
5
+
6
+ class Generator < ::Thor::Group
7
+ include Thor::Actions
8
+
9
+ def self.source_root
10
+ File.join File.dirname(__FILE__), "..", "templates"
11
+ end
12
+ end
13
+
14
+ class UnknownGenerator
15
+
16
+ def self.start(commands)
17
+ raise "There is no command: [ #{commands.join(', ')} ]"
18
+ end
19
+
20
+ end
21
+
22
+
23
+ class Thor < Thor
24
+
25
+ no_tasks do
26
+
27
+ def banner
28
+ """
29
+ ********************************************************************************
30
+ ______ ___ _____
31
+ ___ |/ /_____ __ /_______________
32
+ __ /|_/ / _ _ \\_ __/__ ___/_ __ \\
33
+ _ / / / / __// /_ _ / / /_/ /
34
+ /_/ /_/ \\___/ \\__/ /_/ \\____/
35
+
36
+ -------------------------------------------------------------------------------"""
37
+ end
38
+
39
+ def generators
40
+ Hash.new(UnknownGenerator).merge model: Metro::GenerateModel,
41
+ scene: Metro::GenerateScene,
42
+ view: Metro::GenerateView
43
+ end
44
+
45
+ def generator(name)
46
+ generators[name.to_sym]
47
+ end
48
+
49
+ end
50
+
51
+ desc "new GAMENAME",
52
+ "Create a new game within the directory using with the GAMENAME given."
53
+ def new(game_name)
54
+ Metro::GenerateGame.start [ game_name ]
55
+ end
56
+
57
+ desc "generate TYPE NAME",
58
+ "Create a new type: model, view, or scene."
59
+ def generate(type,name)
60
+ gen = generator(type)
61
+ gen.start [ name ]
62
+ end
63
+
64
+ desc "g TYPE NAME",
65
+ "Create a new type: model, view, or scene."
66
+ def g(type,name)
67
+ generate(type,name)
68
+ end
69
+
70
+ desc "help", "This commoand"
71
+ def help
72
+ say banner
73
+ print_table self.class.printable_tasks, indent: 4
74
+ end
75
+
76
+ end
77
+ end
78
+
79
+
80
+ require_relative 'generate_game'
81
+ require_relative 'generate_model'
82
+ require_relative 'generate_scene'
83
+ require_relative 'generate_view'
@@ -0,0 +1,14 @@
1
+
2
+ class Class
3
+
4
+ #
5
+ # Within Metro often times a Class or the name of the class is being used.
6
+ # ActiveSupport provides the constantize on Strings and Symbols but does
7
+ # not provide it on Class. So instead of providing redundant checks in
8
+ # places this monkeypatch simply makes Classes adhere to the same interface.
9
+ #
10
+ # @return [Class] itself.
11
+ def constantize
12
+ self
13
+ end
14
+ end
@@ -0,0 +1,59 @@
1
+ class Numeric
2
+
3
+ #
4
+ # Set the tick interval which is used in conversion of seconds to
5
+ # ticks.
6
+ #
7
+ def self.tick_interval=(value)
8
+ @tick_interval = value.to_f
9
+ end
10
+
11
+ #
12
+ # @return the game tick interval. By default the tick interval is 16.66666
13
+ #
14
+ def self.tick_interval
15
+ @tick_interval.to_f == 0 ? 16.666666 : @tick_interval.to_f
16
+ end
17
+
18
+
19
+
20
+ #
21
+ # Provides the suffix 'second' which will translate seconds to
22
+ # game ticks. This is to allow for a number of seconds to be expressed
23
+ # in situations where game ticks are used (e.g. animations).
24
+ #
25
+ # @example Expressing an animation that takes place over 3 seconds (~180 ticks)
26
+ #
27
+ # class ExampleScene < Metro::Scene
28
+ # draws :title
29
+ #
30
+ # animate :title, to: { x: 320, y: 444 }, interval: 3.seconds
31
+ # end
32
+ #
33
+ def second
34
+ (self * 1000 / Numeric.tick_interval).floor
35
+ end
36
+
37
+ alias_method :seconds, :second
38
+ alias_method :secs, :second
39
+ alias_method :sec, :second
40
+
41
+ #
42
+ # Provides the suffix 'tick' which will simply express the number
43
+ # with a vanity suffix.
44
+ #
45
+ # @example Expressing an animation that takes place over 60 game ticks
46
+ #
47
+ # class ExampleScene < Metro::Scene
48
+ # draws :title
49
+ #
50
+ # animate :title, to: { x: 320, y: 444 }, interval: 60.ticks
51
+ # end
52
+ #
53
+ def tick
54
+ self
55
+ end
56
+
57
+ alias_method :ticks, :tick
58
+
59
+ end
@@ -0,0 +1,62 @@
1
+ class Gosu::Color
2
+
3
+ alias_method :gosu_initialize, :initialize
4
+
5
+ #
6
+ # Monkey-patching the initialize to allow for another Gosu::Color
7
+ # and Strings.
8
+ #
9
+ def initialize(*args)
10
+ if args.length == 1
11
+ value = args.first
12
+ if value.is_a? Gosu::Color
13
+ gosu_initialize value.alpha, value.red, value.green, value.blue
14
+ elsif value.is_a? String
15
+ gosu_initialize *Array(self.class.parse_string(value))
16
+ else
17
+ gosu_initialize value
18
+ end
19
+ else
20
+ gosu_initialize *args
21
+ end
22
+ end
23
+
24
+ def self.parse_string(value)
25
+ parse_hex(value) || parse_rgb(value) || parse_rgba(value) || parse_gosu_color_string(value) || [ 255, 255, 255, 255 ]
26
+ end
27
+
28
+ def self.parse_rgba(rgba)
29
+ if rgba =~ /rgba\(([\d]{1,3}(?:\.\d*)?),([\d]{1,3}(?:\.\d*)?),([\d]{1,3}(?:\.\d*)?),(\d(?:\.\d*)?)\)/
30
+ [ (255 * $4.to_f).floor.to_i, $1.to_i, $2.to_i, $3.to_i ]
31
+ end
32
+ end
33
+
34
+ def self.parse_rgb(rgb)
35
+ if rgb =~ /rgb\(([\d]{1,3}),([\d]{1,3}),([\d]{1,3})\)/
36
+ [ 255, $1.to_i, $2.to_i, $3.to_i ]
37
+ end
38
+ end
39
+
40
+ def self.parse_hex(hex)
41
+ if hex =~ /0x([A-Fa-f0-9]{8})/
42
+ hex.to_i(16)
43
+ elsif hex =~ /#([A-Fa-f0-9]{6})/
44
+ "0xFF#{$1}".to_i(16)
45
+ end
46
+ end
47
+
48
+ def self.parse_gosu_color_string(string)
49
+ if string =~ /\(ARGB: ([\d]{1,3})\/([\d]{1,3})\/([\d]{1,3})\/([\d]{1,3})\)/
50
+ [ $1.to_i, $2.to_i, $3.to_i, $4.to_i ]
51
+ end
52
+ end
53
+
54
+ def to_s
55
+ "rgba(#{red},#{green},#{blue},#{alpha / 255.to_f})"
56
+ end
57
+
58
+ def to_json(*params)
59
+ to_s.to_json
60
+ end
61
+
62
+ end
@@ -0,0 +1,53 @@
1
+ module Metro
2
+
3
+ #
4
+ # The GosuEvents module creates aliases for the Keyboard and the Gamepad events
5
+ # within the Gosu Namespace. This is so Metro can use the events without requiring
6
+ # the namespace.
7
+ #
8
+ # This makes the interface of these events more portable.
9
+ #
10
+ module GosuConstants
11
+
12
+ def self.extended(base)
13
+ add constants: keyboard_events, to: base
14
+ add constants: gamepad_events, to: base
15
+ add constants: mouse_events, to: base
16
+ end
17
+
18
+ #
19
+ # @return the constant from which to search for all the other constants.
20
+ # This helper method is to to save sprinkling the constant value
21
+ # throughout the rest of the module.
22
+ def self.gosu
23
+ Gosu
24
+ end
25
+
26
+ def self.keyboard_events
27
+ find_all_constants_with_prefix "Kb"
28
+ end
29
+
30
+ def self.gamepad_events
31
+ find_all_constants_with_prefix "Gp"
32
+ end
33
+
34
+ def self.mouse_events
35
+ find_all_constants_with_prefix "Ms"
36
+ end
37
+
38
+ def self.find_all_constants_with_prefix(prefix)
39
+ gosu.constants.find_all { |c| c.to_s.start_with? prefix }
40
+ end
41
+
42
+ #
43
+ # Alias the list of given constants within the given class.
44
+ #
45
+ def self.add(options={})
46
+ events = options[:constants]
47
+ target = options[:to]
48
+
49
+ events.each {|event| target.const_set event, gosu.const_get(event) }
50
+ end
51
+
52
+ end
53
+ end
data/lib/locale/en.yml ADDED
@@ -0,0 +1,35 @@
1
+ ---
2
+ en:
3
+ website: "%{website}"
4
+ error:
5
+ unloadable_source:
6
+ title: "Metro CANNOT load your game code!"
7
+ message: "There is an error within your game code that needs to be fixed before Metro\nis able to replace the current running game code:\n\n%{output}"
8
+ actions: []
9
+ missing_metro_file:
10
+ title: "Unable to find Metro game file"
11
+ message: "The specified file `%{file}` which is required to run the game could not be found."
12
+ actions:
13
+ - "Ensure you have specified the correct file"
14
+ - "Ensure that the file exists at that location"
15
+ - "Did you mean to generate a new game, scene, or model? Try: `metro help`"
16
+ specified_directory:
17
+ title: "Path specified is a directory"
18
+ message: "The specified path is a `%{directory}` and not a valid Metro game file."
19
+ actions:
20
+ - "Ensure you have specified the correct file"
21
+ - "Specify the path to the metro game file with the directory included."
22
+ - "Did you mean to generate a new game, scene, or model? Try: `metro help`"
23
+ reserved_control_name:
24
+ title: "Unable to define control: %{name}"
25
+ message: "The specified control name `%{name}` is RESERVED or ALREADY DEFINED."
26
+ actions:
27
+ - "Ensure that the control name is not already defined."
28
+ - "Replace the use of this control name with name"
29
+ dry_run:
30
+ success:
31
+ title: "Metro Game Dependencies Have Been Met!"
32
+ message: "Your game should be able to be run."
33
+ actions:
34
+ - "Metro dependencies have successfully been loaded"
35
+ - "Game dependencies have successfully been loaded"
@@ -0,0 +1 @@
1
+ I18n.load_path.push "#{File.dirname(__FILE__)}/en.yml"
data/lib/metro.rb ADDED
@@ -0,0 +1,144 @@
1
+ require 'delegate'
2
+ require 'logger'
3
+ require 'erb'
4
+ require 'open3'
5
+
6
+ require 'gosu'
7
+ require 'chipmunk'
8
+ require 'texplay'
9
+ require 'tmx'
10
+ require 'i18n'
11
+ require 'listen'
12
+ require 'active_support'
13
+ require 'active_support/dependencies'
14
+ require 'active_support/inflector'
15
+ require 'active_support/core_ext/hash'
16
+ require 'active_support/hash_with_indifferent_access'
17
+
18
+ require 'core_ext/numeric'
19
+ require 'core_ext/class'
20
+ require 'gosu_ext/color'
21
+ require 'gosu_ext/gosu_constants'
22
+ require 'tmx_ext/tile_set'
23
+ require 'tmx_ext/object'
24
+ require 'tmx_ext/object_shape'
25
+
26
+ require 'locale/locale'
27
+
28
+ require 'metro/parameters/parameters'
29
+ require 'metro/asset_path'
30
+ require 'metro/units/units'
31
+ require 'metro/logging'
32
+ require 'metro/version'
33
+ require 'metro/animation'
34
+ require 'metro/font'
35
+ require 'metro/image'
36
+ require 'metro/sample'
37
+ require 'metro/song'
38
+ require 'metro/template_message'
39
+ require 'metro/window'
40
+ require 'metro/game'
41
+ require 'metro/scene'
42
+ require 'metro/scenes'
43
+ require 'metro/models/model'
44
+ require 'metro/missing_scene'
45
+
46
+ #
47
+ # To allow an author an easier time accessing the Game object from within their game.
48
+ # They do not have to use the `Metro::Game` an instead use the `Game` constant.
49
+ #
50
+ Game = Metro::Game
51
+
52
+ module Metro
53
+ extend self
54
+ extend GosuConstants
55
+
56
+ #
57
+ # @return [String] the filepath to the Metro executable
58
+ #
59
+ def executable_path
60
+ File.absolute_path File.join(File.dirname(__FILE__), "..", "bin", "metro")
61
+ end
62
+
63
+ #
64
+ # @return [String] the filepath to the Metro assets
65
+ #
66
+ def asset_dir
67
+ File.join File.dirname(__FILE__), "assets"
68
+ end
69
+
70
+ #
71
+ # @return [Array] an array of all the handlers that will be executed prior
72
+ # to the game being launched.
73
+ #
74
+ def setup_handlers
75
+ @setup_handlers ||= []
76
+ end
77
+
78
+ #
79
+ # Register a setup handler. While this method is present, it is far
80
+ # too late for game code to be executed as these pregame handlers will already
81
+ # have started executing. This allows for modularity within the Metro library
82
+ # with the possibility that this functionality could become available to
83
+ # individual games if the load process were to be updated.
84
+ #
85
+ def register_setup_handler(handler)
86
+ setup_handlers.push handler
87
+ end
88
+
89
+ #
90
+ # Run will load the contents of the game contents and game files
91
+ # within the current working directory and start the game.
92
+ #
93
+ # @param [Array<String>] parameters an array of parameters that contains
94
+ # the commands in the format that would normally be parsed into the
95
+ # ARGV array.
96
+ #
97
+ def run(*parameters)
98
+ options = Parameters::CommandLineArgsParser.parse(parameters)
99
+ setup_handlers.each { |handler| handler.setup(options) }
100
+ start_game
101
+ end
102
+
103
+ #
104
+ # Start the game by lanunching a window with the game configuration and data
105
+ # that has been loaded.
106
+ #
107
+ def start_game
108
+ Game.start!
109
+ end
110
+
111
+ #
112
+ # When called all the game-related code will be unloaded and reloaded.
113
+ # Providding an opportunity for a game author to tweak the code without having
114
+ # to restart the game.
115
+ #
116
+ def reload!
117
+ SetupHandlers::LoadGameFiles.new.load_game_files!
118
+ end
119
+
120
+ #
121
+ # When called the game-related code will be loaded in a sub-process to see
122
+ # if the code is valid. This is used in tandem with {#reload} and should be
123
+ # called prior to ensure that the code that is replacing the current code
124
+ # is valid.
125
+ #
126
+ # @return [TrueClass,FalseClass] true if the game code that was loaded was
127
+ # loaded successfully. false if the game code was not able to be loaded.
128
+ #
129
+ def game_has_valid_code?
130
+ execution = SetupHandlers::LoadGameFiles.new.launch_game_in_dry_run_mode
131
+
132
+ if execution.invalid?
133
+ error! 'error.unloadable_source', output: execution.output, exit: false
134
+ end
135
+
136
+ execution.valid?
137
+ end
138
+ end
139
+
140
+ require 'setup_handlers/move_to_game_directory'
141
+ require 'setup_handlers/load_game_configuration'
142
+ require 'setup_handlers/load_game_files'
143
+ require 'setup_handlers/exit_if_dry_run'
144
+ require 'setup_handlers/reload_game_on_game_file_changes'