metro 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/README.md +29 -13
  2. data/changelog.md +10 -0
  3. data/lib/core_ext/numeric.rb +59 -0
  4. data/lib/gosu_ext/gosu_constants.rb +53 -0
  5. data/lib/locale/en.yml +16 -0
  6. data/lib/locale/locale.rb +1 -0
  7. data/lib/metro.rb +30 -16
  8. data/lib/metro/animation/after_interval_factory.rb +12 -0
  9. data/lib/metro/animation/animation_factory.rb +3 -2
  10. data/lib/metro/animation/has_animations.rb +3 -3
  11. data/lib/metro/animation/implicit_animation.rb +33 -19
  12. data/lib/metro/animation/{animation.rb → on_update_operation.rb} +6 -4
  13. data/lib/metro/animation/scene_animation.rb +16 -0
  14. data/lib/metro/events/control_definition.rb +11 -0
  15. data/lib/metro/events/controls.rb +42 -0
  16. data/lib/metro/events/event_relay.rb +49 -11
  17. data/lib/metro/events/has_events.rb +6 -5
  18. data/lib/metro/game.rb +17 -11
  19. data/lib/metro/game/dsl.rb +8 -0
  20. data/lib/metro/models/image.rb +3 -1
  21. data/lib/metro/models/key_value_coding.rb +38 -0
  22. data/lib/metro/models/label.rb +18 -3
  23. data/lib/metro/models/menu.rb +6 -5
  24. data/lib/metro/models/model.rb +11 -4
  25. data/lib/metro/models/rectangle.rb +28 -0
  26. data/lib/metro/scene.rb +76 -15
  27. data/lib/metro/scene_view/yaml_view.rb +11 -4
  28. data/lib/metro/scenes.rb +27 -3
  29. data/lib/metro/template_message.rb +33 -4
  30. data/lib/metro/transitions/fade_transition_scene.rb +59 -0
  31. data/lib/metro/transitions/scene_transitions.rb +30 -0
  32. data/lib/metro/transitions/transition_scene.rb +18 -0
  33. data/lib/metro/version.rb +1 -1
  34. data/lib/metro/window.rb +0 -2
  35. data/lib/templates/game/metro.tt +13 -0
  36. data/lib/templates/game/scenes/brand_scene.rb +10 -4
  37. data/lib/templates/game/scenes/brand_to_title_scene.rb +3 -3
  38. data/lib/templates/game/scenes/title_scene.rb +1 -1
  39. data/lib/templates/game/views/brand_to_title.yaml +2 -4
  40. data/lib/templates/game/views/title.yaml +2 -4
  41. data/lib/templates/message.erb +1 -1
  42. data/lib/templates/model.rb.erb +2 -2
  43. data/lib/templates/scene.rb.erb +3 -3
  44. data/metro.gemspec +1 -0
  45. data/spec/core_ext/numeric_spec.rb +78 -0
  46. data/spec/metro/models/key_value_coding_spec.rb +61 -0
  47. data/spec/metro/scene_views/yaml_view_spec.rb +38 -0
  48. metadata +44 -6
  49. data/lib/metro/error.rb +0 -21
@@ -0,0 +1,16 @@
1
+ require_relative 'on_update_operation'
2
+
3
+ module Metro
4
+
5
+ module SceneAnimation
6
+ extend self
7
+
8
+ def build(options,&block)
9
+ animation = Metro::ImplicitAnimation.new options
10
+ animation.on_complete(&block) if block
11
+ animation
12
+ end
13
+
14
+ end
15
+
16
+ end
@@ -0,0 +1,11 @@
1
+ module Metro
2
+ class ControlDefinition
3
+ attr_accessor :name, :event, :args
4
+
5
+ def initialize(name,event,args)
6
+ @name = name
7
+ @event = event
8
+ @args = args
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,42 @@
1
+ require_relative 'control_definition'
2
+
3
+ module Metro
4
+ #
5
+ # Assists in creating and the storing of ControlDefinitions.
6
+ #
7
+ # @see DSL
8
+ #
9
+ class Controls
10
+
11
+ #
12
+ # Creation through controls is usually done with an instance_eval
13
+ # of a block and this allows for a flexible interface.
14
+ #
15
+ # @param [String,Symbol] name the name or the alias of the control
16
+ # as it will be used within the course of the game.
17
+ #
18
+ def method_missing(name,*params,&block)
19
+ options = params.find {|param| param.is_a? Hash }
20
+ define_control(name,options)
21
+ end
22
+
23
+ def define_control(name,options)
24
+ event = _event_type(options)
25
+ args = _event_args(options)
26
+
27
+ defined_controls.push ControlDefinition.new name, event, args
28
+ end
29
+
30
+ def _event_type(options)
31
+ options[:is]
32
+ end
33
+
34
+ def _event_args(options)
35
+ options[:with]
36
+ end
37
+
38
+ def defined_controls
39
+ @defined_controls ||= []
40
+ end
41
+ end
42
+ end
@@ -41,6 +41,37 @@ module Metro
41
41
  #
42
42
  class EventRelay
43
43
 
44
+ #
45
+ # Defines the provided controls for every EventRelay that is created.
46
+ #
47
+ # @see #define_control
48
+ #
49
+ # @param [Array<ControlDefinition>] controls the definitions of controls
50
+ # that should be added to all EventRelays.
51
+ #
52
+ def self.define_controls(controls)
53
+ controls.each { |control| define_control control }
54
+ end
55
+
56
+ #
57
+ # Defines a control from a ControlDefinition for all EventRelays. A
58
+ # control is a way of defining a shortcut for a common event. This
59
+ # could be the use of a common set of keys for confirmation or canceling.
60
+ #
61
+ def self.define_control(control)
62
+ check_for_already_defined_control!(control)
63
+
64
+ define_method control.name do |&block|
65
+ send(control.event,*control.args,&block)
66
+ end
67
+ end
68
+
69
+ def self.check_for_already_defined_control!(control)
70
+ if instance_methods.include? control.name
71
+ error "error.reserved_control_name", name: control.name
72
+ end
73
+ end
74
+
44
75
  #
45
76
  # An event relay is created a with a target and optionally a window.
46
77
  #
@@ -69,7 +100,7 @@ module Metro
69
100
  # @example Registering for a button down event to call a method named 'previous_option'
70
101
  #
71
102
  # class ExampleScene
72
- # event :on_down, Gosu::GpLeft, Gosu::GpUp, do: :previous_option
103
+ # event :on_down, GpLeft, GpUp, do: :previous_option
73
104
  #
74
105
  # def previous_option
75
106
  # @selected_index = @selected_index - 1
@@ -84,7 +115,7 @@ module Metro
84
115
  # @example Registering for a button down event with a block of code to execute
85
116
  #
86
117
  # class ExampleScene
87
- # event :on_down, Gosu::GpLeft, Gosu::GpUp do
118
+ # event :on_down, GpLeft, GpUp do
88
119
  # @selected_index = @selected_index - 1
89
120
  # @selected_index = options.length - 1 if @selected_index <= -1
90
121
  # end
@@ -97,6 +128,8 @@ module Metro
97
128
  _on(@down_actions,args,block)
98
129
  end
99
130
 
131
+ alias_method :button_down, :on_down
132
+
100
133
  #
101
134
  # Register for a button_up event. These events are fired when
102
135
  # the button is released (from being pressed down). This event only fires
@@ -105,7 +138,7 @@ module Metro
105
138
  # @example Registering for a button down event to call a method named 'next_option'
106
139
  #
107
140
  # class ExampleScene
108
- # event :on_up, Gosu::KbEscape, do: :leave_scene
141
+ # event :on_up, KbEscape, do: :leave_scene
109
142
  #
110
143
  # def leave_scene
111
144
  # transition_to :title
@@ -118,7 +151,7 @@ module Metro
118
151
  # @example Registering for a button up event with a block of code to execute
119
152
  #
120
153
  # class ExampleScene
121
- # event :on_up, Gosu::KbEscape do
154
+ # event :on_up, KbEscape do
122
155
  # transition_to :title
123
156
  # end
124
157
  # end
@@ -130,6 +163,8 @@ module Metro
130
163
  _on(@up_actions,args,block)
131
164
  end
132
165
 
166
+ alias_method :button_up, :on_up
167
+
133
168
  #
134
169
  # Register for a button_held event. These events are fired when
135
170
  # the button is currently in the downstate. This event continues to fire at the
@@ -140,15 +175,15 @@ module Metro
140
175
  # @example Registering for button held events
141
176
  #
142
177
  # class ExampleScene
143
- # event :on_hold Gosu::KbLeft, Gosu::GpLeft do
178
+ # event :on_hold KbLeft, GpLeft do
144
179
  # player.turn_left
145
180
  # end
146
181
  #
147
- # event :on_hold, Gosu::KbRight, Gosu::GpRight do
182
+ # event :on_hold, KbRight, GpRight do
148
183
  # player.turn_right
149
184
  # end
150
185
  #
151
- # event :on_hold, Gosu::KbUp, Gosu::GpButton0, do: :calculate_accleration
186
+ # event :on_hold, KbUp, Gosu::GpButton0, do: :calculate_accleration
152
187
  #
153
188
  # def calculate_acceleration
154
189
  # long_complicated_calculated_result = 0
@@ -162,6 +197,9 @@ module Metro
162
197
  _on(@held_actions,args,block)
163
198
  end
164
199
 
200
+ alias_method :button_hold, :on_hold
201
+ alias_method :button_held, :on_hold
202
+
165
203
  #
166
204
  # Register for a custom notification event. These events are fired when
167
205
  # another object within the game posts a notification with matching criteria.
@@ -214,7 +252,7 @@ module Metro
214
252
  # This is called by external or parent source of events, usually a Scene, when a button up event
215
253
  # has been triggered.
216
254
  #
217
- def button_up(id)
255
+ def fire_button_up(id)
218
256
  target.instance_eval( &up_action(id) )
219
257
  end
220
258
 
@@ -222,7 +260,7 @@ module Metro
222
260
  # This is called by external or parent source of events, usually a Scene, when a button down
223
261
  # event has been triggered.
224
262
  #
225
- def button_down(id)
263
+ def fire_button_down(id)
226
264
  target.instance_eval( &down_action(id) )
227
265
  end
228
266
 
@@ -265,10 +303,10 @@ module Metro
265
303
  # An action without any parameters is assumed to be executed within the contexxt
266
304
  # of the target. If there are two parameters we will simply execute the action and
267
305
  # pass it both the target and the sender.
268
- #
306
+ #
269
307
  # @TODO: Allow for the blocks to be specified with one parameter: source (and executed
270
308
  # within the context of the target)
271
- #
309
+ #
272
310
  # @TODO: Allow for the blocks to be specified with three parameters: source, target, event
273
311
  #
274
312
  def _fire_event_for_notification(event,sender,action)
@@ -6,6 +6,7 @@ module Metro
6
6
 
7
7
  def self.included(base)
8
8
  base.extend ClassMethods
9
+ base.extend GosuConstants
9
10
  end
10
11
 
11
12
  module ClassMethods
@@ -24,15 +25,15 @@ module Metro
24
25
  # @example Registering for button held events
25
26
  #
26
27
  # class ExampleScene
27
- # event :on_hold Gosu::KbLeft, Gosu::GpLeft do
28
+ # event :on_hold KbLeft, Gosu::GpLeft do
28
29
  # player.turn_left
29
30
  # end
30
31
  #
31
- # event :on_hold, Gosu::KbRight, Gosu::GpRight do
32
+ # event :on_hold, KbRight, Gosu::GpRight do
32
33
  # player.turn_right
33
34
  # end
34
35
  #
35
- # event :on_hold, Gosu::KbUp, Gosu::GpButton0, do: :calculate_accleration
36
+ # event :on_hold, KbUp, Gosu::GpButton0, do: :calculate_accleration
36
37
  #
37
38
  # def calculate_acceleration
38
39
  # long_complicated_calculated_result = 0
@@ -44,7 +45,7 @@ module Metro
44
45
  # @example Registering for a button down event to call a method named 'next_option'
45
46
  #
46
47
  # class ExampleScene
47
- # event :on_up, Gosu::KbEscape, do: :leave_scene
48
+ # event :on_up, KbEscape, do: :leave_scene
48
49
  #
49
50
  # def leave_scene
50
51
  # transition_to :title
@@ -57,7 +58,7 @@ module Metro
57
58
  # @example Registering for a button up event with a block of code to execute
58
59
  #
59
60
  # class ExampleScene
60
- # event :on_up, Gosu::KbEscape do
61
+ # event :on_up, KbEscape do
61
62
  # transition_to :title
62
63
  # end
63
64
  # end
data/lib/metro/game.rb CHANGED
@@ -11,15 +11,15 @@ module Metro
11
11
  attr_reader :config
12
12
 
13
13
  def first_scene
14
- config.first_scene
14
+ fetch(:first_scene)
15
15
  end
16
16
 
17
17
  def width
18
- config.width || 640
18
+ fetch(:width,640)
19
19
  end
20
20
 
21
21
  def height
22
- config.height || 480
22
+ fetch(:height,480)
23
23
  end
24
24
 
25
25
  def dimensions
@@ -31,31 +31,37 @@ module Metro
31
31
  end
32
32
 
33
33
  def fullscreen?
34
- !!config.fullscreen
34
+ !!fetch(:fullscreen)
35
35
  end
36
36
 
37
37
  def debug?
38
- !!config.debug
38
+ !!fetch(:debug)
39
39
  end
40
40
 
41
41
  def name
42
- config.name
42
+ fetch(:name)
43
43
  end
44
44
 
45
45
  def authors
46
- config.authors
46
+ fetch(:authors)
47
47
  end
48
48
 
49
49
  def website
50
- config.website
50
+ fetch(:website,Metro::WEBSITE)
51
51
  end
52
52
 
53
53
  def contact
54
- config.contact
54
+ fetch(:contact)
55
+ end
56
+
57
+ def controls
58
+ config.controls.defined_controls
59
+ end
60
+
61
+ def fetch(name,fallback = nil)
62
+ config.send(name) rescue fallback
55
63
  end
56
64
 
57
- # TODO: ZOrder related constants that belong to Starry Knight
58
- Background, Stars, Players, UI = *0..3
59
65
 
60
66
  end
61
67
  end
@@ -1,3 +1,5 @@
1
+ require_relative '../events/controls'
2
+
1
3
  module Metro
2
4
  module Game
3
5
  class DSL
@@ -55,6 +57,12 @@ module Metro
55
57
  game_contact ? @contact = game_contact : @contact
56
58
  end
57
59
 
60
+ def controls(&block)
61
+ @controls ||= Controls.new
62
+ @controls.instance_eval(&block) if block
63
+ @controls
64
+ end
65
+
58
66
  end
59
67
  end
60
68
  end
@@ -9,7 +9,7 @@ module Metro
9
9
  #
10
10
  class Image < Model
11
11
 
12
- attr_accessor :angle, :center_x, :center_y, :x_factor, :y_factor, :z_order
12
+ attr_accessor :x, :y, :angle, :center_x, :center_y, :x_factor, :y_factor, :z_order
13
13
 
14
14
  def after_initialize
15
15
  @angle = 0
@@ -17,6 +17,8 @@ module Metro
17
17
  @x_factor = @y_factor = 1
18
18
  @z_order = 0
19
19
  @color = Gosu::Color.new "rgba(255,255,255,1.0)"
20
+ @x = Game.width / 2
21
+ @y = Game.height / 2
20
22
  end
21
23
 
22
24
  def image
@@ -0,0 +1,38 @@
1
+ module Metro
2
+
3
+ #
4
+ # Key-Value coding emulates the functionality found in Objective-C, which allows
5
+ # for an object to be sent a message which contains the method to return. This is
6
+ # the same as Ruby. However, Objective-C also supports the use of the dot notation
7
+ # within the keys to acces the sub-values.
8
+ #
9
+ # @example Setting the red value of the color on a Model.
10
+ #
11
+ # class Elf
12
+ # include KeyValueCoding
13
+ #
14
+ # attr_accessor :color
15
+ # end
16
+ #
17
+ # elf = Elf.new
18
+ # elf.color = Gosu::Color.new "rgb(0,0,0)"
19
+ #
20
+ # elf.get("color.red") # => 0
21
+ # elf.set("color.red",255)
22
+ # elf.get("color.red") # => 255
23
+ #
24
+ module KeyValueCoding
25
+
26
+ def set(name,value)
27
+ keys = name.to_s.split('.')
28
+ key_to_set = keys[0..-2].inject(self) {|target,method| target.send(method) }
29
+ key_to_set.send("#{keys.last}=",value)
30
+ end
31
+
32
+ def get(name)
33
+ keys = name.to_s.split('.')
34
+ keys.inject(self) {|target,method| target.send(method) }
35
+ end
36
+ end
37
+
38
+ end
@@ -10,20 +10,35 @@ module Metro
10
10
  class Label < Model
11
11
 
12
12
  attr_accessor :x, :y, :x_factor, :y_factor, :z_order
13
+ attr_accessor :size, :size, :font_family
13
14
 
14
15
  def after_initialize
15
16
  @text = ""
16
17
  @x_factor = @y_factor = 1.0
17
18
  @z_order = 0
18
19
  @color = Gosu::Color.new "rgba(255,255,255,1.0)"
20
+ @size = 20
21
+ @font_family = Gosu::default_font_name
19
22
  end
20
-
23
+
21
24
  def font
22
- @font ||= Gosu::Font.new(window, Gosu::default_font_name, 20)
25
+ @font ||= Gosu::Font.new(window, font_family, size)
26
+ end
27
+
28
+ def x
29
+ @x || (Game.width/2 - font.text_width(text)/2)
30
+ end
31
+
32
+ def y
33
+ @y || (Game.height/2 - font.height/2)
34
+ end
35
+
36
+ def text
37
+ scene.instance_eval( "\"#{@text}\"" )
23
38
  end
24
39
 
25
40
  def draw
26
- label_text = scene.instance_eval( "\"#{text}\"" )
41
+ label_text = text
27
42
  font.draw label_text, x, y, z_order, x_factor, y_factor, color
28
43
  end
29
44