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