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,19 @@
1
+ module Metro
2
+ class TransitionScene < Scene
3
+
4
+ attr_accessor :next_scene, :previous_scene, :options
5
+
6
+ def prepare_transition_from(old_scene)
7
+ next_scene.prepare_transition_from(old_scene)
8
+ @previous_scene = old_scene
9
+ end
10
+
11
+ def prepare_transition_to(new_scene)
12
+ previous_scene.prepare_transition_to(new_scene)
13
+ end
14
+
15
+ end
16
+ end
17
+
18
+ require_relative 'fade_transition_scene'
19
+ require_relative 'edit_transition_scene'
@@ -0,0 +1,8 @@
1
+ module Metro
2
+ module Units
3
+
4
+ # Rectangle Bounds are common enough to be considered simply Bounds.
5
+ Bounds = RectangleBounds
6
+
7
+ end
8
+ end
@@ -0,0 +1,74 @@
1
+ module Metro
2
+ module Units
3
+ module CalculationValidations
4
+
5
+ #
6
+ # @param [Object] value the other object that needs to be validated.
7
+ #
8
+ def check_calculation_requirements(value)
9
+ if calculation_requirements.find { |method| ! value.respond_to?(method) }
10
+ raise "Unable to perform operation with #{value} #{value.class} It is missing a property #{calculation_requirements.join(",")}"
11
+ end
12
+ end
13
+
14
+ #
15
+ # @return [Array] an array of methods that are required to be on the
16
+ # object for it to be correctly calculated.
17
+ #
18
+ # @note this method is intended to be defined in the including class. This
19
+ # method is included here when one has not been provided.
20
+ def calculation_requirements
21
+ []
22
+ end
23
+
24
+ #
25
+ # Add this object to another object.
26
+ #
27
+ # @return a new object that is the sum of the two objects
28
+ #
29
+ def +(value)
30
+ self.class.new *calculate(value,:+)
31
+ end
32
+
33
+ #
34
+ # Subtract the other object from this object.
35
+ #
36
+ # @return a new object that is the difference of the original object
37
+ # and the value specified.
38
+ #
39
+ def -(value)
40
+ self.class.new *calculate(value,:-)
41
+ end
42
+
43
+ #
44
+ # Multiply this object and another object.
45
+ #
46
+ # @return a new object that is the product of the two objects.
47
+ #
48
+ def *(value)
49
+ self.class.new *calculate(value,:*)
50
+ end
51
+
52
+ #
53
+ # This generic method will perform the calculation defined by the
54
+ # operation for all the calculation requirements defined.
55
+ #
56
+ # @param [value] value this is the other value that is being added,
57
+ # subtracted, etc. to the current object.
58
+ # @param [Symbol] operation this is the mathematical operation that
59
+ # is being performed between all the calc requirements of the current
60
+ # object and other value.
61
+ #
62
+ # @return [Array] an array of reults from the calculations of all the
63
+ # requirements.
64
+ #
65
+ def calculate(value,operation)
66
+ check_calculation_requirements(value)
67
+ calculation_requirements.map do |requirement|
68
+ send(requirement).send(operation,value.send(requirement))
69
+ end
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,60 @@
1
+ module Metro
2
+ module Units
3
+
4
+ #
5
+ # Represents an object that contains both the width and height.
6
+ #
7
+ class Dimensions < Struct.new(:width,:height)
8
+ include CalculationValidations
9
+
10
+ #
11
+ # Create a dimensions objects with zero width and zero height.
12
+ #
13
+ def self.none
14
+ of 0.0, 0.0
15
+ end
16
+
17
+ #
18
+ # Parse a string representation of a dimensions object. The
19
+ # supported formated is a comma-delimited string that contains
20
+ # two attributes width and height.
21
+ #
22
+ def self.parse(string)
23
+ of *string.to_s.split(",",2).map(&:to_f)
24
+ end
25
+
26
+
27
+ #
28
+ # An alternate way of creating a dimensions object which
29
+ # will enforce that the values added are converted to floating
30
+ # point numbers.
31
+ #
32
+ def self.of(width=0.0,height=0.0)
33
+ new width.to_f, height.to_f
34
+ end
35
+
36
+ def to_s
37
+ "#{width},#{height}"
38
+ end
39
+
40
+ #
41
+ # Compare the dimension to another dimensions-like structure.
42
+ #
43
+ # @return [Fixnum] -1 if the dimensions is smaller than the other dimension,
44
+ # 0 if the dimensions are exactly the same, 1 if the dimensions are bigger
45
+ # then the other dimensions.
46
+ #
47
+ def <=>(value)
48
+ check_calculation_requirements(value)
49
+ (width * height) <=> (value.width * value.height)
50
+ end
51
+
52
+ private
53
+
54
+ def calculation_requirements
55
+ [ :width, :height ]
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,51 @@
1
+ module Metro
2
+ module Units
3
+
4
+ #
5
+ # Represents and object that contains the x, y, and z position.
6
+ #
7
+ class Point < Struct.new(:x,:y,:z)
8
+ include CalculationValidations
9
+
10
+ #
11
+ # Generate a point at 0,0,0.
12
+ #
13
+ def self.zero
14
+ new 0.0, 0.0, 0.0
15
+ end
16
+
17
+ #
18
+ # An alternate way of creating a point. Creation here converts
19
+ # all inputs to floating point and assumes that the z-value is
20
+ # zero (as this is a 2D universe).
21
+ #
22
+ def self.at(x=0.0,y=0.0,z=0.0)
23
+ new x.to_f, y.to_f, z.to_f
24
+ end
25
+
26
+ #
27
+ # Parse a string representation of a point object. The
28
+ # supported formated is a comma-delimited string that contains
29
+ # either "x,y" or "x,y,z".
30
+ #
31
+ def self.parse(string)
32
+ at *string.to_s.split(",",3).map(&:to_f)
33
+ end
34
+
35
+ # As this is a 2D world, the Z is often refered to as a the z-ordering
36
+ alias_method :z_order, :z
37
+ alias_method :z_order=, :z=
38
+
39
+ def to_s
40
+ "#{x},#{y},#{z}"
41
+ end
42
+
43
+ private
44
+
45
+ def calculation_requirements
46
+ [ :x, :y, :z ]
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,85 @@
1
+ module Metro
2
+ module Units
3
+
4
+ #
5
+ # An object that represents a rectanglar bounds.
6
+ #
7
+ class RectangleBounds
8
+ include CalculationValidations
9
+
10
+ attr_accessor :left, :right, :top, :bottom
11
+
12
+ def self.none
13
+ new left: 0, right: 0, top: 0, bottom: 0
14
+ end
15
+
16
+ #
17
+ # Create a bounds with bounds.
18
+ #
19
+ def initialize(params = {})
20
+ @left = params[:left].to_f
21
+ @top = params[:top].to_f
22
+ @right = params[:right].to_f
23
+ @bottom = params[:bottom].to_f
24
+ end
25
+
26
+ def shift(point)
27
+ self.left = self.left + point.x
28
+ self.right = self.right + point.x
29
+ self.top = self.top + point.y
30
+ self.bottom = self.bottom + point.y
31
+ end
32
+
33
+ def top_left
34
+ Point.at(left,top)
35
+ end
36
+
37
+ def top_right
38
+ Point.at(right,top)
39
+ end
40
+
41
+ def bottom_right
42
+ Point.at(right,bottom)
43
+ end
44
+
45
+ def bottom_left
46
+ Point.at(left,bottom)
47
+ end
48
+
49
+ def dimensions
50
+ Dimensions.of (right - left), (bottom - top)
51
+ end
52
+
53
+ def ==(value)
54
+ check_calculation_requirements(value)
55
+ left == value.left and right == value.right and top == value.top and bottom == value.bottom
56
+ end
57
+
58
+ #
59
+ # Does this bounds contain the following point?
60
+ #
61
+ def contains?(point)
62
+ point.x > left and point.x < right and point.y > top and point.y < bottom
63
+ end
64
+
65
+ #
66
+ # Does this rectanglular bounds intersect with another rectanglular bounds?
67
+ #
68
+ def intersect?(b)
69
+ not(b.left > right or b.right < left or b.top > bottom or b.bottom < top)
70
+ end
71
+
72
+ def to_s
73
+ "(#{left},#{top}) to (#{right},#{bottom})"
74
+ end
75
+
76
+ private
77
+
78
+ def calculation_requirements
79
+ [ :left, :right, :top, :bottom ]
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,46 @@
1
+ module Metro
2
+ module Units
3
+
4
+ #
5
+ # Represents an object that contains the x scale factor, and y scale factor.
6
+ #
7
+ class Scale < Struct.new(:x_factor,:y_factor)
8
+ include CalculationValidations
9
+
10
+ #
11
+ # Create a scale that is 1:1.
12
+ #
13
+ def self.one
14
+ new 1.0, 1.0
15
+ end
16
+
17
+ #
18
+ # An alternative way to create a scale which will automatically convert
19
+ # the inputs into floating numbers.
20
+ #
21
+ def self.to(x,y)
22
+ new x.to_f, y.to_f
23
+ end
24
+
25
+ #
26
+ # Parse a string representation of a scale object. The
27
+ # supported formated is a comma-delimited string that contains
28
+ # two attributes x-factor and y-factor.
29
+ #
30
+ def self.parse(string)
31
+ to *string.split(",",2).map(&:to_f)
32
+ end
33
+
34
+ def to_s
35
+ "#{x_factor},#{y_factor}"
36
+ end
37
+
38
+ private
39
+
40
+ def calculation_requirements
41
+ [ :x_factor, :y_factor ]
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,6 @@
1
+ require_relative 'calculation_validations'
2
+ require_relative 'point'
3
+ require_relative 'dimensions'
4
+ require_relative 'scale'
5
+ require_relative 'rectangle_bounds'
6
+ require_relative 'bounds'
@@ -0,0 +1,32 @@
1
+ module Metro
2
+ VERSION = "0.3.3"
3
+ WEBSITE = "https://github.com/burtlo/metro"
4
+ CONTACT_EMAILS = ["dev@rubymetro.com"]
5
+
6
+ def self.changes_for_version(version)
7
+
8
+ change = Struct::Changes.new(nil,[])
9
+
10
+ grab_changes = false
11
+
12
+ changelog_filename = "#{File.dirname(__FILE__)}/../../changelog.md"
13
+
14
+ File.open(changelog_filename,'r') do |file|
15
+ while (line = file.gets) do
16
+
17
+ if line =~ /^##\s*#{version.gsub('.','\.')}\s*\/\s*(.+)\s*$/
18
+ grab_changes = true
19
+ change.date = $1.strip
20
+ elsif line =~ /^##\s*.+$/
21
+ grab_changes = false
22
+ elsif grab_changes
23
+ change.changes.push line
24
+ end
25
+
26
+ end
27
+ end
28
+
29
+ change
30
+ end
31
+
32
+ end
@@ -0,0 +1,60 @@
1
+ require 'json'
2
+
3
+ module Metro
4
+ module Views
5
+
6
+ #
7
+ # Provides support for a JSON Representation of a view.
8
+ #
9
+ class JSONView
10
+
11
+ #
12
+ # Determine if a view exists for this specified format
13
+ #
14
+ # @param [String] view_path the name of the view to find
15
+ # @return a true if the json view exists and false if it does not exist.
16
+ #
17
+ def self.exists?(view_path)
18
+ File.exists? json_view_path(view_path)
19
+ end
20
+
21
+ #
22
+ # Parse the contents of the view given the name.
23
+ #
24
+ # @param [String] view_path the name of the view to read
25
+ # @return a Hash that contains the contents of the view.
26
+ #
27
+ def self.parse(view_path)
28
+ JSON.parse File.read json_view_path(view_path)
29
+ end
30
+
31
+ #
32
+ # @return the file type format of this view.
33
+ #
34
+ def self.format
35
+ :json
36
+ end
37
+
38
+ #
39
+ # Writes the content out to the spcified view path
40
+ #
41
+ def self.write(view_path,content)
42
+ filename = json_view_path(view_path)
43
+ json_content = JSON.pretty_generate(content)
44
+ File.write(filename,json_content)
45
+ end
46
+
47
+ private
48
+
49
+ #
50
+ # A helper method to generate the name of the json view file. In this case
51
+ # it is the view name with the suffix .json.
52
+ #
53
+ def self.json_view_path(view_path)
54
+ File.extname(view_path) == "" ? "#{view_path}.json" : view_path
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+ end