metro 0.3.3 → 0.3.4
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 +8 -1
- data/lib/core_ext/class.rb +14 -0
- data/lib/metro.rb +1 -0
- data/lib/metro/events/event_data.rb +3 -4
- data/lib/metro/events/event_state_manager.rb +63 -0
- data/lib/metro/events/events.rb +3 -0
- data/lib/metro/events/hit_list.rb +4 -5
- data/lib/metro/events/unknown_sender.rb +1 -1
- data/lib/metro/models/model.rb +14 -25
- data/lib/metro/models/model_factory.rb +1 -1
- data/lib/metro/models/models.rb +62 -0
- data/lib/metro/models/properties/position_property.rb +1 -1
- data/lib/metro/models/ui/animated_sprite.rb +85 -0
- data/lib/metro/models/ui/border.rb +44 -18
- data/lib/metro/models/ui/fps.rb +1 -1
- data/lib/metro/models/ui/generic.rb +24 -3
- data/lib/metro/models/ui/model_label.rb +1 -1
- data/lib/metro/models/ui/model_labeler.rb +2 -2
- data/lib/metro/models/ui/rectangle.rb +1 -1
- data/lib/metro/models/ui/sprite.rb +79 -0
- data/lib/metro/models/ui/ui.rb +12 -0
- data/lib/metro/scene.rb +13 -61
- data/lib/metro/scenes.rb +11 -13
- data/lib/metro/transitions/edit_transition_scene.rb +2 -2
- data/lib/metro/units/calculation_validations.rb +74 -0
- data/lib/metro/units/dimensions.rb +11 -19
- data/lib/metro/units/point.rb +6 -22
- data/lib/metro/units/rectangle_bounds.rb +10 -6
- data/lib/metro/units/scale.rb +7 -0
- data/lib/metro/units/units.rb +1 -0
- data/lib/metro/version.rb +1 -1
- data/lib/metro/window.rb +7 -3
- data/lib/setup_handlers/reload_game_on_game_file_changes.rb +6 -6
- data/lib/templates/game/models/hero.rb +35 -6
- data/lib/templates/model.rb.tt +1 -1
- data/spec/core_ext/string_spec.rb +0 -20
- data/spec/metro/units/point_spec.rb +132 -0
- data/spec/setup_handlers/exit_if_dry_run_spec.rb +27 -0
- data/spec/setup_handlers/reload_game_on_game_file_changes_spec.rb +68 -0
- metadata +21 -9
data/changelog.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Metro
|
2
2
|
|
3
|
+
## 0.3.4 / 2012-12-14
|
4
|
+
|
5
|
+
* `metro::ui::sprite` and `metro::ui::animated_sprite` model classes
|
6
|
+
to make it easier to take care of all the basic model attributes.
|
7
|
+
* Event Management changed in the background. The API remains the
|
8
|
+
same.
|
9
|
+
|
3
10
|
## 0.3.3 / 2012-11-28
|
4
11
|
|
5
12
|
* Edit Mode - actors within a scene can have their position edited
|
@@ -7,7 +14,7 @@
|
|
7
14
|
specified will appear within the scene with name and bounding box.
|
8
15
|
* Dimensions can now be defined as strings
|
9
16
|
* Game bounds and Game dimensions return objects of that type
|
10
|
-
* `
|
17
|
+
* `metro::ui::fps` added and has some shortcut placements settings
|
11
18
|
|
12
19
|
## 0.3.2 / 2012-11-26
|
13
20
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
class Class
|
3
|
+
|
4
|
+
#
|
5
|
+
# Within Metro often times a Class or the name of the class is being used.
|
6
|
+
# ActiveSupport provides the constantize on Strings and Symbols but does
|
7
|
+
# not provide it on Class. So instead of providing redundant checks in
|
8
|
+
# places this monkeypatch simply makes Classes adhere to the same interface.
|
9
|
+
#
|
10
|
+
# @return [Class] itself.
|
11
|
+
def constantize
|
12
|
+
self
|
13
|
+
end
|
14
|
+
end
|
data/lib/metro.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
module Metro
|
2
2
|
class EventData
|
3
3
|
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :mouse_point, :created_at
|
5
5
|
|
6
6
|
def initialize(window)
|
7
7
|
@created_at = Time.now
|
8
|
-
@
|
9
|
-
@mouse_y = window.mouse_y
|
8
|
+
@mouse_point = Metro::Units::Point.at window.mouse_x, window.mouse_y
|
10
9
|
|
11
10
|
capture_modifier_keys(window)
|
12
11
|
end
|
@@ -23,7 +22,7 @@ module Metro
|
|
23
22
|
|
24
23
|
#
|
25
24
|
# TODO: This attempt to reduce duplication is brittle and will likely end in heartache.
|
26
|
-
#
|
25
|
+
#
|
27
26
|
|
28
27
|
def self.modifier_key_list_names
|
29
28
|
@modifier_key_list_names ||= %w[ KbLeftControl KbRightControl
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative 'event_relay'
|
2
|
+
|
3
|
+
module Metro
|
4
|
+
|
5
|
+
class EventStateManager
|
6
|
+
def initialize
|
7
|
+
@current_state = []
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_accessor :window
|
11
|
+
|
12
|
+
attr_reader :current_state
|
13
|
+
|
14
|
+
#
|
15
|
+
# Clear all the event relays of the current game state
|
16
|
+
#
|
17
|
+
def clear
|
18
|
+
current_state.clear
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Fire events for held buttons within the current game state
|
23
|
+
#
|
24
|
+
def fire_events_for_held_buttons
|
25
|
+
current_state.each {|cs| cs.fire_events_for_held_buttons }
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Fire events for button up for the current game state
|
30
|
+
#
|
31
|
+
def fire_button_up(id)
|
32
|
+
current_state.each {|cs| cs.fire_button_up(id) }
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Fire events for button down within the current game state
|
37
|
+
#
|
38
|
+
def fire_button_down(id)
|
39
|
+
current_state.each {|cs| cs.fire_button_down(id) }
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Fire notification events within the current game state
|
44
|
+
#
|
45
|
+
def fire_events_for_notification(event,sender)
|
46
|
+
current_state.each {|cs| cs.fire_events_for_notification(event,sender) }
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# An an event relay to the current game state
|
51
|
+
#
|
52
|
+
def add_events_for_target(target,events)
|
53
|
+
relay = EventRelay.new(target,window)
|
54
|
+
|
55
|
+
events.each do |target_event|
|
56
|
+
relay.send target_event.event, *target_event.buttons, &target_event.block
|
57
|
+
end
|
58
|
+
|
59
|
+
current_state.push relay
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -10,7 +10,6 @@ module Metro
|
|
10
10
|
# hit_list.update(next_event)
|
11
11
|
# hit_list.release(last_event)
|
12
12
|
#
|
13
|
-
#
|
14
13
|
# @see EditTransitionScene
|
15
14
|
#
|
16
15
|
class HitList
|
@@ -22,7 +21,7 @@ module Metro
|
|
22
21
|
attr_reader :drawers
|
23
22
|
|
24
23
|
def hit(event)
|
25
|
-
add drawers_at(event.
|
24
|
+
add drawers_at(event.mouse_point)
|
26
25
|
save_event event
|
27
26
|
end
|
28
27
|
|
@@ -41,8 +40,8 @@ module Metro
|
|
41
40
|
clear
|
42
41
|
end
|
43
42
|
|
44
|
-
def drawers_at(
|
45
|
-
hit_drawers = drawers.find_all { |drawer| drawer.bounds.contains?(
|
43
|
+
def drawers_at(point)
|
44
|
+
hit_drawers = drawers.find_all { |drawer| drawer.bounds.contains?(point) }
|
46
45
|
|
47
46
|
# assumed that we only want one item
|
48
47
|
top_drawer = hit_drawers.inject(hit_drawers.first) {|top,drawer| drawer.z_order > top.z_order ? drawer : top }
|
@@ -51,7 +50,7 @@ module Metro
|
|
51
50
|
|
52
51
|
def offset_from_last_event(event)
|
53
52
|
return Point.zero unless @last_event
|
54
|
-
|
53
|
+
event.mouse_point - @last_event.mouse_point
|
55
54
|
end
|
56
55
|
|
57
56
|
def save_event(event)
|
data/lib/metro/models/model.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'key_value_coding'
|
2
2
|
require_relative 'properties/property'
|
3
|
+
require_relative 'models'
|
3
4
|
|
4
5
|
module Metro
|
5
6
|
|
@@ -64,6 +65,11 @@ module Metro
|
|
64
65
|
#
|
65
66
|
def draw ; end
|
66
67
|
|
68
|
+
def self.model_name(model_name=nil)
|
69
|
+
@model_name ||= to_s.underscore
|
70
|
+
model_name ? @model_name = model_name.to_s : @model_name
|
71
|
+
end
|
72
|
+
|
67
73
|
#
|
68
74
|
# @return [String] the name of the model class.
|
69
75
|
#
|
@@ -129,7 +135,7 @@ module Metro
|
|
129
135
|
#
|
130
136
|
def create(model_name,options={})
|
131
137
|
# @TODO: this is another path that parallels the ModelFactory
|
132
|
-
model_class = Metro::
|
138
|
+
model_class = Metro::Models.find(model_name)
|
133
139
|
mc = model_class.new options
|
134
140
|
mc.scene = scene
|
135
141
|
mc.window = window
|
@@ -211,37 +217,20 @@ module Metro
|
|
211
217
|
#
|
212
218
|
# Captures all classes that subclass Model.
|
213
219
|
#
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
models_hash[model.to_s] = model.to_s
|
218
|
-
models_hash[model.to_s.downcase] = model.to_s
|
219
|
-
models_hash[model.to_s.underscore] = model.to_s
|
220
|
+
def self.inherited(base)
|
221
|
+
models << base.to_s
|
222
|
+
Models.add(base)
|
220
223
|
end
|
221
224
|
|
222
225
|
#
|
223
|
-
#
|
226
|
+
# All subclasses of Model, this should be all the defined
|
224
227
|
#
|
225
|
-
|
226
|
-
|
227
|
-
models_hash[name]
|
228
|
-
end
|
229
|
-
|
230
|
-
def self.models_hash
|
231
|
-
@models_hash ||= HashWithIndifferentAccess.new("Metro::UI::Generic")
|
228
|
+
def self.models
|
229
|
+
@models ||= []
|
232
230
|
end
|
233
231
|
|
234
232
|
end
|
235
233
|
end
|
236
234
|
|
237
|
-
require_relative 'ui/
|
238
|
-
require_relative 'ui/label'
|
239
|
-
require_relative 'ui/menu'
|
240
|
-
require_relative 'ui/image'
|
241
|
-
require_relative 'ui/rectangle'
|
242
|
-
require_relative 'ui/grid_drawer'
|
243
|
-
require_relative 'ui/border'
|
244
|
-
require_relative 'ui/model_label'
|
245
|
-
require_relative 'ui/model_labeler'
|
246
|
-
require_relative 'ui/fps'
|
235
|
+
require_relative 'ui/ui'
|
247
236
|
require_relative 'audio/song'
|
@@ -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,85 @@
|
|
1
|
+
module Metro
|
2
|
+
module UI
|
3
|
+
|
4
|
+
#
|
5
|
+
# A sprite is a Metro model that is specially designed to draw and manage
|
6
|
+
# an animation. A sprite maintains an animation, location information, and
|
7
|
+
# rotation.
|
8
|
+
#
|
9
|
+
class AnimatedSprite < Model
|
10
|
+
|
11
|
+
# @attribute
|
12
|
+
# The animation that will be drawn for the sprite
|
13
|
+
property :animation
|
14
|
+
|
15
|
+
# @attribute
|
16
|
+
# The point at which the sprite should be drawn
|
17
|
+
property :position
|
18
|
+
|
19
|
+
# @attribute
|
20
|
+
# This is the color of the spirte. The color usually remains white, and
|
21
|
+
# the color property is implemented by the `alpha` value is the one thing
|
22
|
+
# that is altered to fade in and fade out the sprite.
|
23
|
+
property :color
|
24
|
+
|
25
|
+
# @attribute
|
26
|
+
# The scale at which to draw the sprite. This is default scale of 1.
|
27
|
+
property :scale
|
28
|
+
|
29
|
+
# @attribute
|
30
|
+
# The center, horizontal position, as expressed in a ratio, of the image.
|
31
|
+
property :center_x, type: :numeric, default: 0.0
|
32
|
+
|
33
|
+
# @attribute
|
34
|
+
# The center, vertical position, as expressed in a ratio, of the image.
|
35
|
+
property :center_y, type: :numeric, default: 0.0
|
36
|
+
|
37
|
+
# @attribute
|
38
|
+
# The angle at which the sprite should be drawn. This is by default 0.
|
39
|
+
property :angle
|
40
|
+
|
41
|
+
# @attribute
|
42
|
+
# The height and width of the sprite is based on the image of the sprite.
|
43
|
+
property :dimensions do
|
44
|
+
Dimensions.of current_image.width, current_image.height
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [RectangleBounds] the bounds of the sprite.
|
48
|
+
def bounds
|
49
|
+
Bounds.new left: left, right: right, top: top, bottom: bottom
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Float] the left-most x position of the sprite
|
53
|
+
def left
|
54
|
+
x - width * center_x
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Float] the right-most x position of the sprite
|
58
|
+
def right
|
59
|
+
left + width * x_factor
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [Float] the top-most y position of the sprite
|
63
|
+
def top
|
64
|
+
y - height * center_y
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [Float] the bottom-most y position of the sprite
|
68
|
+
def bottom
|
69
|
+
top + height * y_factor
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Gosu::Image] the current image in the animation sequence.
|
73
|
+
def current_image
|
74
|
+
animation.image
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# By default the sprite will draw the current image of the animation.
|
79
|
+
#
|
80
|
+
def draw
|
81
|
+
current_image.draw_rot x, y, z_order, angle, center_x, center_y, x_factor, y_factor, color
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -5,7 +5,7 @@ module Metro
|
|
5
5
|
# Draws a rectanglar border around the specififed position and dimensions
|
6
6
|
# with the width provided. This is an unfilled rectangle.
|
7
7
|
#
|
8
|
-
class Border <
|
8
|
+
class Border < Model
|
9
9
|
|
10
10
|
# @attribute
|
11
11
|
# The starting position of the border.
|
@@ -35,32 +35,58 @@ module Metro
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def draw_top
|
38
|
-
|
39
|
-
width + x,y,color,
|
40
|
-
x + width,y + border,color,
|
41
|
-
x + border,y + border,color,z_order)
|
38
|
+
draw_line left_with_border, top, right, top_with_border
|
42
39
|
end
|
43
40
|
|
44
41
|
def draw_left
|
45
|
-
|
46
|
-
border + x,y,color,
|
47
|
-
x + border,y + border + height,color,
|
48
|
-
x,y + border + height,color,z_order)
|
42
|
+
draw_line left, top, left_with_border, bottom_with_border
|
49
43
|
end
|
50
44
|
|
51
45
|
def draw_right
|
52
|
-
|
53
|
-
x + width + border,y,color,
|
54
|
-
x + width + border,y + border + height,color,
|
55
|
-
x + width,y + border + height,color,z_order)
|
56
|
-
|
46
|
+
draw_line right, top, right_with_border, bottom_with_border
|
57
47
|
end
|
58
48
|
|
59
49
|
def draw_bottom
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
50
|
+
draw_line left_with_border, bottom, right,bottom_with_border
|
51
|
+
end
|
52
|
+
|
53
|
+
def draw_line(start_x,start_y,finish_x,finish_y)
|
54
|
+
window.draw_quad start_x, start_y, color,
|
55
|
+
finish_x, start_y, color,
|
56
|
+
finish_x, finish_y, color,
|
57
|
+
start_x, finish_y, color, z_order
|
58
|
+
end
|
59
|
+
|
60
|
+
def left
|
61
|
+
x
|
62
|
+
end
|
63
|
+
|
64
|
+
def left_with_border
|
65
|
+
x + border
|
66
|
+
end
|
67
|
+
|
68
|
+
def right
|
69
|
+
x + width
|
70
|
+
end
|
71
|
+
|
72
|
+
def right_with_border
|
73
|
+
right + border
|
74
|
+
end
|
75
|
+
|
76
|
+
def top
|
77
|
+
y
|
78
|
+
end
|
79
|
+
|
80
|
+
def top_with_border
|
81
|
+
top + border
|
82
|
+
end
|
83
|
+
|
84
|
+
def bottom
|
85
|
+
y + height
|
86
|
+
end
|
87
|
+
|
88
|
+
def bottom_with_border
|
89
|
+
bottom + border
|
64
90
|
end
|
65
91
|
|
66
92
|
end
|