metro 0.1.4 → 0.1.5
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/changelog.md +9 -0
- data/lib/commands/generate_model.rb +2 -2
- data/lib/commands/generate_scene.rb +2 -2
- data/lib/commands/generate_view.rb +1 -1
- data/lib/gosu_ext/color.rb +16 -2
- data/lib/metro.rb +50 -10
- data/lib/metro/events/event_data.rb +61 -0
- data/lib/metro/events/event_relay.rb +10 -3
- data/lib/metro/events/hit_list.rb +77 -0
- data/lib/metro/models/draws.rb +6 -1
- data/lib/metro/models/grid_drawer.rb +57 -0
- data/lib/metro/models/image.rb +18 -2
- data/lib/metro/models/label.rb +22 -6
- data/lib/metro/models/menu.rb +20 -0
- data/lib/metro/models/model.rb +47 -6
- data/lib/metro/models/model_factory.rb +2 -2
- data/lib/metro/models/rectangle_bounds.rb +28 -0
- data/lib/metro/scene.rb +46 -11
- data/lib/metro/scenes.rb +10 -9
- data/lib/metro/transitions/edit_transition_scene.rb +73 -0
- data/lib/metro/transitions/scene_transitions.rb +8 -2
- data/lib/metro/transitions/transition_scene.rb +2 -1
- data/lib/metro/version.rb +1 -1
- data/lib/metro/views/json_view.rb +60 -0
- data/lib/metro/{scene_view → views}/no_view.rb +12 -4
- data/lib/metro/views/parsers.rb +26 -0
- data/lib/metro/views/scene_view.rb +107 -0
- data/lib/metro/views/view.rb +125 -0
- data/lib/metro/views/writers.rb +28 -0
- data/lib/metro/views/yaml_view.rb +94 -0
- data/lib/metro/window.rb +19 -0
- data/metro.gemspec +1 -0
- data/spec/core_ext/string_spec.rb +13 -13
- data/spec/metro/scene_spec.rb +15 -0
- data/spec/metro/scene_views/json_view_spec.rb +27 -0
- data/spec/metro/scene_views/yaml_view_spec.rb +1 -1
- data/spec/metro/views/view_spec.rb +53 -0
- metadata +41 -11
- data/lib/core_ext/string.rb +0 -15
- data/lib/metro/scene_view/json_view.rb +0 -41
- data/lib/metro/scene_view/scene_view.rb +0 -83
- data/lib/metro/scene_view/yaml_view.rb +0 -45
data/lib/metro/models/label.rb
CHANGED
@@ -3,10 +3,10 @@ module Metro
|
|
3
3
|
|
4
4
|
#
|
5
5
|
# Draws a string of text
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# @example Using the Label in a view file
|
8
8
|
# model: "metro::models::label"
|
9
|
-
#
|
9
|
+
#
|
10
10
|
class Label < Model
|
11
11
|
|
12
12
|
attr_accessor :x, :y, :x_factor, :y_factor, :z_order
|
@@ -20,19 +20,35 @@ module Metro
|
|
20
20
|
@size = 20
|
21
21
|
@font_family = Gosu::default_font_name
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def font
|
25
25
|
@font ||= Gosu::Font.new(window, font_family, size)
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def x
|
29
29
|
@x || (Game.width/2 - font.text_width(text)/2)
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def y
|
33
33
|
@y || (Game.height/2 - font.height/2)
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
|
+
def bounds
|
37
|
+
Bounds.new x, y, x + width, y + height
|
38
|
+
end
|
39
|
+
|
40
|
+
def width
|
41
|
+
font.text_width(text) * x_factor
|
42
|
+
end
|
43
|
+
|
44
|
+
def height
|
45
|
+
font.height * y_factor
|
46
|
+
end
|
47
|
+
|
48
|
+
def contains?(x,y)
|
49
|
+
bounds.contains?(x,y)
|
50
|
+
end
|
51
|
+
|
36
52
|
def text
|
37
53
|
scene.instance_eval( "\"#{@text}\"" )
|
38
54
|
end
|
data/lib/metro/models/menu.rb
CHANGED
@@ -56,6 +56,26 @@ module Metro
|
|
56
56
|
@font ||= Gosu::Font.new(window, Gosu::default_font_name, 20)
|
57
57
|
end
|
58
58
|
|
59
|
+
def contains?(x,y)
|
60
|
+
bounds.contains?(x,y)
|
61
|
+
end
|
62
|
+
|
63
|
+
def bounds
|
64
|
+
Metro::Models::Bounds.new x, y, x + width, y + height
|
65
|
+
end
|
66
|
+
|
67
|
+
def width
|
68
|
+
font.text_width(longest_option_text)# * x_factor
|
69
|
+
end
|
70
|
+
|
71
|
+
def longest_option_text
|
72
|
+
longest = options.map {|opt| opt }.inject("") {|longest,opt| opt.length > longest.length ? opt : longest }
|
73
|
+
end
|
74
|
+
|
75
|
+
def height
|
76
|
+
options.length * font.height + (options.length - 1) * padding
|
77
|
+
end
|
78
|
+
|
59
79
|
attr_reader :highlight_color
|
60
80
|
|
61
81
|
def highlight_color=(value)
|
data/lib/metro/models/model.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'key_value_coding'
|
2
|
+
require_relative 'rectangle_bounds'
|
2
3
|
|
3
4
|
module Metro
|
4
5
|
|
@@ -98,6 +99,21 @@ module Metro
|
|
98
99
|
color.alpha = value.to_i
|
99
100
|
end
|
100
101
|
|
102
|
+
def saveable?
|
103
|
+
true
|
104
|
+
end
|
105
|
+
|
106
|
+
# Belongs to positionable items only
|
107
|
+
def contains?(x,y)
|
108
|
+
false
|
109
|
+
end
|
110
|
+
|
111
|
+
# Belongs to positionable items only
|
112
|
+
def offset(x,y)
|
113
|
+
self.x += x
|
114
|
+
self.y += y
|
115
|
+
end
|
116
|
+
|
101
117
|
#
|
102
118
|
# Create an instance of a model.
|
103
119
|
#
|
@@ -121,7 +137,7 @@ module Metro
|
|
121
137
|
options.each do |raw_key,value|
|
122
138
|
|
123
139
|
key = raw_key.to_s.dup
|
124
|
-
key = key.gsub(/-/,'_').
|
140
|
+
key = key.gsub(/-/,'_').underscore
|
125
141
|
|
126
142
|
unless respond_to? key
|
127
143
|
self.class.send :define_method, key do
|
@@ -153,17 +169,38 @@ module Metro
|
|
153
169
|
# to another model.
|
154
170
|
#
|
155
171
|
def _save
|
156
|
-
data_export =
|
172
|
+
data_export = _loaded_options.map {|option| [ option, send(option) ] }.flatten
|
157
173
|
Hash[*data_export]
|
158
174
|
end
|
159
175
|
|
176
|
+
#
|
177
|
+
# Generate a hash representation of the model. Currently this is ugly
|
178
|
+
#
|
179
|
+
def to_hash
|
180
|
+
export = _loaded_options.map {|option| [ option, send(option) ] }
|
181
|
+
export_with_name = export.reject {|item| item.first == "name" }
|
182
|
+
|
183
|
+
hash = export_with_name.inject({}) {|hash,elem| hash[elem.first] = elem.last ; hash }
|
184
|
+
|
185
|
+
# TODO:: color is a class that cannot be yamlized as it is and needs to be turned into a string.
|
186
|
+
# TODO: Hack to save the Gosu::Color class as a string value (this is
|
187
|
+
# what I hoped that the properties would solve)
|
188
|
+
hash.each do |subkey,subvalue|
|
189
|
+
if subvalue.is_a? Gosu::Color
|
190
|
+
hash[subkey] = subvalue.to_s
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
{ name => hash }
|
195
|
+
end
|
196
|
+
|
160
197
|
#
|
161
198
|
# Captures all classes that subclass Model.
|
162
199
|
#
|
163
200
|
# @see #self.scenes
|
164
201
|
#
|
165
202
|
def self.inherited(base)
|
166
|
-
models << base
|
203
|
+
models << base.to_s
|
167
204
|
end
|
168
205
|
|
169
206
|
#
|
@@ -182,12 +219,15 @@ module Metro
|
|
182
219
|
def self.model(name)
|
183
220
|
@models_hash ||= begin
|
184
221
|
|
185
|
-
hash = Hash.new(Models::Generic)
|
222
|
+
hash = Hash.new("Metro::Models::Generic")
|
186
223
|
|
187
224
|
models.each do |model|
|
188
|
-
common_name = model.to_s.
|
225
|
+
common_name = model.to_s.underscore
|
226
|
+
hash[model.to_s] = model
|
227
|
+
hash[model.downcase] = model
|
189
228
|
hash[common_name] = model
|
190
229
|
end
|
230
|
+
|
191
231
|
hash
|
192
232
|
end
|
193
233
|
|
@@ -201,4 +241,5 @@ require_relative 'generic'
|
|
201
241
|
require_relative 'label'
|
202
242
|
require_relative 'menu'
|
203
243
|
require_relative 'image'
|
204
|
-
require_relative 'rectangle'
|
244
|
+
require_relative 'rectangle'
|
245
|
+
require_relative 'grid_drawer'
|
@@ -8,7 +8,7 @@ module Metro
|
|
8
8
|
@options = options
|
9
9
|
end
|
10
10
|
|
11
|
-
def create
|
11
|
+
def create
|
12
12
|
contents = {} unless contents
|
13
13
|
actor_class = class_for_actor(model_name(contents))
|
14
14
|
instance = actor_class.new
|
@@ -25,7 +25,7 @@ module Metro
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def class_for_actor(model_name)
|
28
|
-
Model.model(model_name)
|
28
|
+
Model.model(model_name).constantize
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Metro
|
2
|
+
module Models
|
3
|
+
|
4
|
+
class RectangleBounds
|
5
|
+
|
6
|
+
attr_reader :min_x, :min_y, :max_x, :max_y
|
7
|
+
|
8
|
+
def initialize(min_x,min_y,max_x,max_y)
|
9
|
+
@min_x = min_x
|
10
|
+
@min_y = min_y
|
11
|
+
@max_x = max_x
|
12
|
+
@max_y = max_y
|
13
|
+
end
|
14
|
+
|
15
|
+
def contains?(x,y)
|
16
|
+
x > min_x and x < max_x and y > min_y and y < max_y
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
"(#{min_x},#{min_y}) to (#{max_x},#{max_y})"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
Bounds = RectangleBounds
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/lib/metro/scene.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative 'views/scene_view'
|
2
2
|
|
3
3
|
require_relative 'events/has_events'
|
4
4
|
require_relative 'events/event_relay'
|
@@ -172,14 +172,16 @@ module Metro
|
|
172
172
|
# @see #after_initialize
|
173
173
|
#
|
174
174
|
def initialize
|
175
|
+
add_actors_to_scene
|
176
|
+
after_initialize
|
177
|
+
end
|
178
|
+
|
179
|
+
def add_actors_to_scene
|
175
180
|
self.class.actors.each do |scene_actor|
|
176
|
-
|
177
|
-
actor_instance = scene_actor.create(actor_data)
|
181
|
+
actor_instance = scene_actor.create
|
178
182
|
actor_instance.scene = self
|
179
183
|
send "#{scene_actor.name}=", actor_instance
|
180
184
|
end
|
181
|
-
|
182
|
-
after_initialize
|
183
185
|
end
|
184
186
|
|
185
187
|
#
|
@@ -259,12 +261,9 @@ module Metro
|
|
259
261
|
# @example Retrieving the default scene name
|
260
262
|
#
|
261
263
|
# class ExampleScene
|
262
|
-
# def show
|
263
|
-
# puts "Showing Scene: #{self.class.scene_name}"
|
264
|
-
# end
|
265
264
|
# end
|
266
265
|
#
|
267
|
-
# ExampleScene.scene_name
|
266
|
+
# ExampleScene.scene_name # => "example"
|
268
267
|
#
|
269
268
|
# @example Setting a custom name for the Scene
|
270
269
|
#
|
@@ -272,6 +271,8 @@ module Metro
|
|
272
271
|
# scene_name "credits"
|
273
272
|
# end
|
274
273
|
#
|
274
|
+
# RollingCreditsScene.scene_name # => "credits"
|
275
|
+
#
|
275
276
|
# @param [String] scene_name when specified it will set the scene name for the class
|
276
277
|
# to the value specified.
|
277
278
|
#
|
@@ -280,12 +281,30 @@ module Metro
|
|
280
281
|
#
|
281
282
|
def self.scene_name(scene_name=nil)
|
282
283
|
@scene_name ||= begin
|
283
|
-
to_s.gsub(/_?Scene$/i,'').
|
284
|
+
to_s.gsub(/_?Scene$/i,'').underscore
|
284
285
|
end
|
285
286
|
|
286
287
|
scene_name ? @scene_name = scene_name.to_s : @scene_name
|
287
288
|
end
|
288
289
|
|
290
|
+
|
291
|
+
#
|
292
|
+
# Allows you to set or retrieve the scene name for the Scene.
|
293
|
+
#
|
294
|
+
# @example Retrieving the default scene name
|
295
|
+
#
|
296
|
+
# class ExampleScene
|
297
|
+
# def show
|
298
|
+
# puts "Showing Scene: #{self.scene_name}" # => Showing Scene: example
|
299
|
+
# end
|
300
|
+
# end
|
301
|
+
#
|
302
|
+
# @return the string name of the Scene.
|
303
|
+
#
|
304
|
+
def scene_name
|
305
|
+
self.class.scene_name
|
306
|
+
end
|
307
|
+
|
289
308
|
#
|
290
309
|
# @return the string representation of a scene, this is used for debugging.
|
291
310
|
#
|
@@ -299,7 +318,7 @@ module Metro
|
|
299
318
|
# @see #self.scenes
|
300
319
|
#
|
301
320
|
def self.inherited(base)
|
302
|
-
scenes << base
|
321
|
+
scenes << base.to_s
|
303
322
|
end
|
304
323
|
|
305
324
|
#
|
@@ -356,6 +375,7 @@ module Metro
|
|
356
375
|
def base_update
|
357
376
|
updaters.each { |updater| updater.update }
|
358
377
|
update
|
378
|
+
updaters.reject! { |updater| updater.completed? }
|
359
379
|
end
|
360
380
|
|
361
381
|
#
|
@@ -476,5 +496,20 @@ module Metro
|
|
476
496
|
end
|
477
497
|
end
|
478
498
|
|
499
|
+
|
500
|
+
#
|
501
|
+
# A Scene represented as a hash currently only contains the drawers
|
502
|
+
#
|
503
|
+
# @return a hash of all the drawers
|
504
|
+
#
|
505
|
+
def to_hash
|
506
|
+
drawn = drawers.find_all{|draw| draw.saveable? }.inject({}) do |hash,drawer|
|
507
|
+
drawer_hash = drawer.to_hash
|
508
|
+
hash.merge drawer_hash
|
509
|
+
end
|
510
|
+
|
511
|
+
drawn
|
512
|
+
end
|
513
|
+
|
479
514
|
end
|
480
515
|
end
|
data/lib/metro/scenes.rb
CHANGED
@@ -34,12 +34,12 @@ module Metro
|
|
34
34
|
#
|
35
35
|
def find(scene_name)
|
36
36
|
found_scene = scenes_hash[scene_name]
|
37
|
-
|
38
|
-
|
39
|
-
found_scene
|
37
|
+
|
38
|
+
if found_scene
|
39
|
+
found_scene.constantize
|
40
|
+
else
|
41
|
+
create_missing_scene(scene_name)
|
40
42
|
end
|
41
|
-
|
42
|
-
found_scene
|
43
43
|
end
|
44
44
|
|
45
45
|
def create_missing_scene(scene_name)
|
@@ -87,11 +87,12 @@ module Metro
|
|
87
87
|
# as well as the class name constants to allow for the scenes to be found.
|
88
88
|
#
|
89
89
|
def scenes_hash
|
90
|
-
@scenes_hash ||= Scene.scenes.inject({}) do |dict,
|
90
|
+
@scenes_hash ||= Scene.scenes.inject({}) do |dict,scene_classname|
|
91
|
+
scene = scene_classname.constantize
|
91
92
|
name = scene.scene_name
|
92
|
-
dict[name] =
|
93
|
-
dict[name.to_sym] =
|
94
|
-
dict[scene] =
|
93
|
+
dict[name] = scene_classname
|
94
|
+
dict[name.to_sym] = scene_classname
|
95
|
+
dict[scene] = scene_classname
|
95
96
|
dict
|
96
97
|
end
|
97
98
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative '../events/hit_list'
|
2
|
+
|
3
|
+
module Metro
|
4
|
+
|
5
|
+
class EditTransitionScene < Metro::TransitionScene
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
#
|
9
|
+
# The EditTransitionScene needs to have all the drawers
|
10
|
+
# cleared from the class because it may still have
|
11
|
+
# drawers from other things that this was executed.
|
12
|
+
#
|
13
|
+
# This is a product of using the classes to store the definitions
|
14
|
+
# of scene. This means we need to change this so that it is much
|
15
|
+
# easier to dup scenes.
|
16
|
+
#
|
17
|
+
self.class.drawings.clear
|
18
|
+
self.class.draw :overlay, model: "Metro::Models::GridDrawer"
|
19
|
+
add_actors_to_scene
|
20
|
+
after_initialize
|
21
|
+
end
|
22
|
+
|
23
|
+
def prepare_transition_from(old_scene)
|
24
|
+
next_scene.prepare_transition_from(old_scene)
|
25
|
+
@previous_scene = old_scene
|
26
|
+
|
27
|
+
# Set the view name to the previous scene's view name
|
28
|
+
self.class.view_name old_scene.view_name
|
29
|
+
self.class.view.format = old_scene.class.view.format
|
30
|
+
|
31
|
+
# import all the actors from the previous scene into the current scene.
|
32
|
+
old_scene.class.actors.each do |scene_actor|
|
33
|
+
self.class.draw scene_actor.name, scene_actor.options
|
34
|
+
end
|
35
|
+
|
36
|
+
add_actors_to_scene
|
37
|
+
end
|
38
|
+
|
39
|
+
def show
|
40
|
+
window.show_cursor
|
41
|
+
end
|
42
|
+
|
43
|
+
event :on_up, KbE do
|
44
|
+
transition_to next_scene.scene_name
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Generate a hitlist which manages the click start, hold, and release
|
49
|
+
# of the mouse button.
|
50
|
+
#
|
51
|
+
def hitlist
|
52
|
+
@hitlist ||= HitList.new(drawers)
|
53
|
+
end
|
54
|
+
|
55
|
+
event :on_down, MsLeft do |event|
|
56
|
+
hitlist.hit(event)
|
57
|
+
end
|
58
|
+
|
59
|
+
event :on_hold, MsLeft do |event|
|
60
|
+
hitlist.update(event)
|
61
|
+
end
|
62
|
+
|
63
|
+
event :on_up, MsLeft do |event|
|
64
|
+
hitlist.release(event)
|
65
|
+
end
|
66
|
+
|
67
|
+
event :on_up, KbS do
|
68
|
+
save_view
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|