metro-ld25 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
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,32 @@
1
+ module Metro
2
+ class ModelFactory
3
+
4
+ attr_reader :name
5
+
6
+ def initialize(name,options)
7
+ @name = name.to_s.downcase
8
+ @options = options.symbolize_keys
9
+ end
10
+
11
+ def create
12
+ actor_class = class_for_actor(model_name)
13
+ actor_class.new options
14
+ end
15
+
16
+ def load_from_previous_scene?
17
+ @options[:from] == :previous_scene
18
+ end
19
+
20
+ def options
21
+ @options.except(:from)
22
+ end
23
+
24
+ def model_name
25
+ options[:model] || name
26
+ end
27
+
28
+ def class_for_actor(model_name)
29
+ Models.find(model_name)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,62 @@
1
+ module Metro
2
+
3
+
4
+ module Models
5
+ extend self
6
+
7
+ #
8
+ # Add a model, and all it's subclasses, to the list of available models.
9
+ #
10
+ # A model has several names added so that it accessible in many ways:
11
+ #
12
+ # * Model Class Name
13
+ # * Model Name
14
+ # * Model Name with slashes replaced with `::` separator
15
+ #
16
+ def add(model)
17
+ all_models_for(model).each do |model|
18
+ models_hash[model.to_s] = model.to_s
19
+ name_with_slashes = model.model_name
20
+ models_hash[name_with_slashes] = model.to_s
21
+ name_with_colons = name_with_slashes.gsub('/','::')
22
+ models_hash[name_with_colons] = model.to_s
23
+ end
24
+ end
25
+
26
+ #
27
+ # @param [String] name the name of the model that you want to return.
28
+ #
29
+ # @return [String] the name of the model class
30
+ #
31
+ def find(name)
32
+ models_hash[name].constantize
33
+ end
34
+
35
+ #
36
+ # @return [Array<String>] all the names supported by the models hash.
37
+ #
38
+ def list
39
+ models_hash.keys
40
+ end
41
+
42
+ #
43
+ # @return [Hash] a hash of the available models. The keys are the various
44
+ # supported names, with the values being the names of the model classes.
45
+ def models_hash
46
+ @models_hash ||= HashWithIndifferentAccess.new("Metro::UI::Generic")
47
+ end
48
+
49
+ #
50
+ # @param [Class,Array<Class>] models a model or array of models.
51
+ # @return [Array] an array that contains the model itself and all of the
52
+ # models that are sub-classes of this model on down.
53
+ #
54
+ def all_models_for(models)
55
+ Array(models).map do |model_class_name|
56
+ model = model_class_name.constantize
57
+ [ model ] + all_models_for(models.models)
58
+ end.flatten.compact
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,115 @@
1
+ module Metro
2
+ class Model
3
+
4
+ #
5
+ # An animation property manages an Animation, which is an array of
6
+ # Gosu::Images and some metadata.
7
+ #
8
+ # @see Animation
9
+ #
10
+ # A animation is stored in the properties as a hash representation and is
11
+ # converted into an Animation when it is retrieved within the system.
12
+ #
13
+ # The animate images are cached within the animation property to help
14
+ # performance by reducing the unncessary creation of similar animations.
15
+ #
16
+ # @example Defining an animation property (will default to the missing animation)
17
+ #
18
+ # class Scoreboard < Metro::Model
19
+ # property :animation
20
+ #
21
+ # def draw
22
+ # animation.image.draw text, x, y, z_order, x_factor, y_factor, color
23
+ # end
24
+ # end
25
+ #
26
+ # @example Defining an animation with a path.
27
+ #
28
+ # class Hero < Metro::Model
29
+ # property :animation, path: "star.png", dimensions: Dimensions.of(25,25)
30
+ # dimensions: Dimensions.of(25,25) }
31
+ #
32
+ # def draw
33
+ # animation.image.draw text, x, y, z_order, x_factor, y_factor, color
34
+ # end
35
+ # end
36
+ #
37
+ # @example Using an animation property with a different property name
38
+ #
39
+ # class Hero < Metro::Model
40
+ # property :walking, type: :animation, path: "star.png",
41
+ # dimensions: Dimensions.of(25,25)
42
+ #
43
+ # def draw
44
+ # walking.image.draw text, x, y, z_order, x_factor, y_factor, color
45
+ # end
46
+ # end
47
+ #
48
+ class AnimationProperty < Property
49
+
50
+ # By default return the default animation when getting a nil or
51
+ # other unsupported value.
52
+ get do
53
+ create_animation default_properties
54
+ end
55
+
56
+ # When getting a hash, create the animation with the properties.
57
+ get Hash do |loaded|
58
+ create_animation default_properties.merge(loaded)
59
+ end
60
+
61
+ # Setting the animation with a nil or other unsupported value
62
+ # will default to the default animation.
63
+ set do
64
+ defaults.except(:window)
65
+ end
66
+
67
+ # Setting with an animation will convert it to it's hash representation.
68
+ set Animation do |image|
69
+ image.to_hash
70
+ end
71
+
72
+ # Setting with a hash will assume the hash defines an animation.
73
+ set Hash, HashWithIndifferentAccess do |value|
74
+ value.except(:window)
75
+ end
76
+
77
+ private
78
+
79
+ def create_animation(properties)
80
+ self.class.animation_for properties
81
+ end
82
+
83
+ def default_properties
84
+ { window: model.window,
85
+ path: default_image_filename,
86
+ width: default_dimensions.width,
87
+ height: default_dimensions.height,
88
+ time_per_image: default_time_per_image,
89
+ tileable: false }
90
+ end
91
+
92
+ def default_image_filename
93
+ options[:path] or "missing_animation.png"
94
+ end
95
+
96
+ def default_dimensions
97
+ if options[:dimensions]
98
+ Dimensions.parse options[:dimensions]
99
+ else
100
+ Dimensions.of 16.0, 16.0
101
+ end
102
+ end
103
+
104
+ def default_time_per_image
105
+ options[:time_per_image] or 50
106
+ end
107
+
108
+ def self.animation_for(options)
109
+ Metro::Animation.find_or_create(options)
110
+ end
111
+
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,24 @@
1
+ module Metro
2
+ class Model
3
+
4
+ #
5
+ # The array property will simply store or retrieve an array.
6
+ #
7
+ class ArrayProperty < Property
8
+
9
+ get do |value|
10
+ value.is_a?(NilClass) ? default_value : Array(value)
11
+ end
12
+
13
+ set do |value|
14
+ Array(value).map {|item| item }
15
+ end
16
+
17
+ def default_value
18
+ options[:default] or []
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ module Metro
2
+ class Model
3
+
4
+ #
5
+ # The boolean property will simply convert any input into a true or
6
+ # false value.
7
+ #
8
+ class BooleanProperty < Property
9
+
10
+ # For all cases the value is converted to floating point when it can
11
+ # otherwise the default number is used.
12
+ get_or_set do |value|
13
+ if value.is_a?(NilClass)
14
+ default_value
15
+ else
16
+ !!value
17
+ end
18
+ end
19
+
20
+ def default_value
21
+ !!options[:default]
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,116 @@
1
+ module Metro
2
+ class Model
3
+
4
+ #
5
+ # A color property maintains a Gosu::Color.
6
+ #
7
+ # A color property also defines an alpha property which allows a more direct interface
8
+ # to setting the alpha property on the color. This is useful in cases for images where
9
+ # the color remains as white but the alpha value needs to be adjusted.
10
+ #
11
+ # A color is stored in the properties as a string representation and is converted into
12
+ # a Gosu::Color when it is retrieved within the system.
13
+ #
14
+ # @example Defining a color property using the color properties default
15
+ #
16
+ # class Hero < Metro::Model
17
+ # property :color
18
+ #
19
+ # def draw
20
+ # image.draw x, y, z_order, x_factor, y_factor, color, :add)
21
+ # end
22
+ #
23
+ # end
24
+ #
25
+ # @example Defining a color property providing a default
26
+ #
27
+ # class Hero < Metro::Model
28
+ # property :color, default: "rgba(255,0,0,1.0)"
29
+ # end
30
+ #
31
+ # @example Using the alpha property
32
+ #
33
+ # class Hero < Metro::Model
34
+ # property :color, default: "rgba(255,0,0,1.0)"
35
+ #
36
+ # def become_ghost!
37
+ # self.alpha = 127
38
+ # end
39
+ # end
40
+ #
41
+ # @example Using a color property with a different property name
42
+ #
43
+ # class Hero < Metro::Model
44
+ # property :color
45
+ # property :invincible_color, type: :color, default: "rgba(255,0,255,1.0)"
46
+ #
47
+ # def draw
48
+ # if invincible?
49
+ # image.draw x, y, z_order, x_factor, y_factor, invincible_color, :add)
50
+ # else
51
+ # image.draw x, y, z_order, x_factor, y_factor, color, :add)
52
+ # end
53
+ # end
54
+ # end
55
+ #
56
+ class ColorProperty < Property
57
+
58
+ define_property :alpha
59
+ define_property :red
60
+ define_property :green
61
+ define_property :blue
62
+
63
+ # By default convert the value to the default color if it
64
+ # cannot be processed by the other get filters.
65
+ get do |value|
66
+ default_color
67
+ end
68
+
69
+ # A color should remain a color.
70
+ get Gosu::Color do |value|
71
+ value
72
+ end
73
+
74
+ # A string representation of a color will be converted to a color.
75
+ # If Gosu::Color does not support the format, then it will default to white.
76
+ get String do |value|
77
+ create_color value
78
+ end
79
+
80
+ # By default save the default color string.
81
+ set do |value|
82
+ default_color_string
83
+ end
84
+
85
+ # When given a string assume that it is a string representation of color.
86
+ set String do |value|
87
+ value
88
+ end
89
+
90
+ # When given a color, convert it into the string representation.
91
+ set Gosu::Color do |value|
92
+ value.to_s
93
+ end
94
+
95
+ #
96
+ # @return the default color of the color property. This can be set during initialization
97
+ # by usign the option `default`.
98
+ #
99
+ def default_color
100
+ create_color(default_color_string)
101
+ end
102
+
103
+ private
104
+
105
+ def default_color_string
106
+ options[:default] || "rgba(255,255,255,1.0)"
107
+ end
108
+
109
+ def create_color(value)
110
+ Gosu::Color.new value
111
+ end
112
+
113
+ end
114
+
115
+ end
116
+ end
@@ -0,0 +1,84 @@
1
+ module Metro
2
+ class Model
3
+
4
+ #
5
+ # A dimensions property maintains an width and height.
6
+ #
7
+ # A dimensions property also defines a `width` property and a `height`
8
+ # property which allows a more direct interface. Changing these values
9
+ # will update the dimensions the next time that it is drawn.
10
+ #
11
+ # Dimensions is stored in the properties as a string and is converted into
12
+ # a Dimensions when it is retrieved within the system. When retrieving the dimensions.
13
+ #
14
+ # @example Defining a dimensions property
15
+ #
16
+ # class Hero < Metro::Model
17
+ # property :dimensions
18
+ # end
19
+ #
20
+ # @example Defining a dimensions providing a default
21
+ #
22
+ # class Hero < Metro::Model
23
+ # property :dimensions, default: Dimensions.of(100.0, 100.0)
24
+ # end
25
+ #
26
+ # @example Using a dimensions property with a different property name
27
+ #
28
+ # class Hero < Metro::Model
29
+ # property :box, type: dimensions, default: Dimensions.of(100.0, 100.0)
30
+ # # box_width, box_height
31
+ # end
32
+ #
33
+ # @example Using a dimensions property providing a default block (to be calculated
34
+ # when the model retrieves the value - allowing for the model's scene and window
35
+ # to be set.)
36
+ #
37
+ # class Hero < Metro::Model
38
+ # property :dimensions do
39
+ # # Return the dimensions of the current window for the hero
40
+ # model.window.dimensions
41
+ # end
42
+ # end
43
+ #
44
+ class DimensionsProperty < Property
45
+
46
+ define_property :width
47
+
48
+ define_property :height
49
+
50
+ get do |value|
51
+ default_dimensions
52
+ end
53
+
54
+ get String do |value|
55
+ Dimensions.parse(value)
56
+ end
57
+
58
+ set do |value|
59
+ default_dimensions.to_s
60
+ end
61
+
62
+ set String do |value|
63
+ value
64
+ end
65
+
66
+ set Dimensions do |value|
67
+ value.to_s
68
+ end
69
+
70
+ def default_dimensions
71
+ Dimensions.parse default_dimensions_params.to_s
72
+ end
73
+
74
+ private
75
+
76
+ def default_dimensions_params
77
+ block ? model.instance_eval(&block) : options[:default]
78
+ end
79
+
80
+
81
+ end
82
+
83
+ end
84
+ end