metro 0.1.2 → 0.1.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.
- data/README.md +29 -13
- data/changelog.md +10 -0
- data/lib/core_ext/numeric.rb +59 -0
- data/lib/gosu_ext/gosu_constants.rb +53 -0
- data/lib/locale/en.yml +16 -0
- data/lib/locale/locale.rb +1 -0
- data/lib/metro.rb +30 -16
- data/lib/metro/animation/after_interval_factory.rb +12 -0
- data/lib/metro/animation/animation_factory.rb +3 -2
- data/lib/metro/animation/has_animations.rb +3 -3
- data/lib/metro/animation/implicit_animation.rb +33 -19
- data/lib/metro/animation/{animation.rb → on_update_operation.rb} +6 -4
- data/lib/metro/animation/scene_animation.rb +16 -0
- data/lib/metro/events/control_definition.rb +11 -0
- data/lib/metro/events/controls.rb +42 -0
- data/lib/metro/events/event_relay.rb +49 -11
- data/lib/metro/events/has_events.rb +6 -5
- data/lib/metro/game.rb +17 -11
- data/lib/metro/game/dsl.rb +8 -0
- data/lib/metro/models/image.rb +3 -1
- data/lib/metro/models/key_value_coding.rb +38 -0
- data/lib/metro/models/label.rb +18 -3
- data/lib/metro/models/menu.rb +6 -5
- data/lib/metro/models/model.rb +11 -4
- data/lib/metro/models/rectangle.rb +28 -0
- data/lib/metro/scene.rb +76 -15
- data/lib/metro/scene_view/yaml_view.rb +11 -4
- data/lib/metro/scenes.rb +27 -3
- data/lib/metro/template_message.rb +33 -4
- data/lib/metro/transitions/fade_transition_scene.rb +59 -0
- data/lib/metro/transitions/scene_transitions.rb +30 -0
- data/lib/metro/transitions/transition_scene.rb +18 -0
- data/lib/metro/version.rb +1 -1
- data/lib/metro/window.rb +0 -2
- data/lib/templates/game/metro.tt +13 -0
- data/lib/templates/game/scenes/brand_scene.rb +10 -4
- data/lib/templates/game/scenes/brand_to_title_scene.rb +3 -3
- data/lib/templates/game/scenes/title_scene.rb +1 -1
- data/lib/templates/game/views/brand_to_title.yaml +2 -4
- data/lib/templates/game/views/title.yaml +2 -4
- data/lib/templates/message.erb +1 -1
- data/lib/templates/model.rb.erb +2 -2
- data/lib/templates/scene.rb.erb +3 -3
- data/metro.gemspec +1 -0
- data/spec/core_ext/numeric_spec.rb +78 -0
- data/spec/metro/models/key_value_coding_spec.rb +61 -0
- data/spec/metro/scene_views/yaml_view_spec.rb +38 -0
- metadata +44 -6
- 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,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,
|
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,
|
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,
|
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,
|
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
|
178
|
+
# event :on_hold KbLeft, GpLeft do
|
144
179
|
# player.turn_left
|
145
180
|
# end
|
146
181
|
#
|
147
|
-
# event :on_hold,
|
182
|
+
# event :on_hold, KbRight, GpRight do
|
148
183
|
# player.turn_right
|
149
184
|
# end
|
150
185
|
#
|
151
|
-
# event :on_hold,
|
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
|
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
|
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
|
28
|
+
# event :on_hold KbLeft, Gosu::GpLeft do
|
28
29
|
# player.turn_left
|
29
30
|
# end
|
30
31
|
#
|
31
|
-
# event :on_hold,
|
32
|
+
# event :on_hold, KbRight, Gosu::GpRight do
|
32
33
|
# player.turn_right
|
33
34
|
# end
|
34
35
|
#
|
35
|
-
# event :on_hold,
|
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,
|
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,
|
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
|
-
|
14
|
+
fetch(:first_scene)
|
15
15
|
end
|
16
16
|
|
17
17
|
def width
|
18
|
-
|
18
|
+
fetch(:width,640)
|
19
19
|
end
|
20
20
|
|
21
21
|
def height
|
22
|
-
|
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
|
-
!!
|
34
|
+
!!fetch(:fullscreen)
|
35
35
|
end
|
36
36
|
|
37
37
|
def debug?
|
38
|
-
!!
|
38
|
+
!!fetch(:debug)
|
39
39
|
end
|
40
40
|
|
41
41
|
def name
|
42
|
-
|
42
|
+
fetch(:name)
|
43
43
|
end
|
44
44
|
|
45
45
|
def authors
|
46
|
-
|
46
|
+
fetch(:authors)
|
47
47
|
end
|
48
48
|
|
49
49
|
def website
|
50
|
-
|
50
|
+
fetch(:website,Metro::WEBSITE)
|
51
51
|
end
|
52
52
|
|
53
53
|
def contact
|
54
|
-
|
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
|
data/lib/metro/game/dsl.rb
CHANGED
@@ -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
|
data/lib/metro/models/image.rb
CHANGED
@@ -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
|
data/lib/metro/models/label.rb
CHANGED
@@ -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,
|
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 =
|
41
|
+
label_text = text
|
27
42
|
font.draw label_text, x, y, z_order, x_factor, y_factor, color
|
28
43
|
end
|
29
44
|
|