metro 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|