metro 0.3.2 → 0.3.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 +51 -20
- data/changelog.md +9 -0
- data/lib/metro/events/hit_list.rb +7 -8
- data/lib/metro/font.rb +3 -0
- data/lib/metro/game.rb +7 -3
- data/lib/metro/models/model.rb +16 -13
- data/lib/metro/models/properties/animation_property.rb +5 -1
- data/lib/metro/models/properties/dimensions_property.rb +8 -7
- data/lib/metro/models/properties/font_property.rb +2 -1
- data/lib/metro/models/properties/model_property.rb +84 -0
- data/lib/metro/models/properties/property.rb +2 -1
- data/lib/metro/models/ui/border.rb +69 -0
- data/lib/metro/models/ui/fps.rb +54 -0
- data/lib/metro/models/ui/generic.rb +8 -1
- data/lib/metro/models/ui/grid_drawer.rb +17 -5
- data/lib/metro/models/ui/image.rb +40 -8
- data/lib/metro/models/ui/label.rb +48 -7
- data/lib/metro/models/ui/menu.rb +61 -8
- data/lib/metro/models/ui/model_label.rb +65 -0
- data/lib/metro/models/ui/model_labeler.rb +79 -0
- data/lib/metro/models/ui/rectangle.rb +6 -0
- data/lib/metro/scene.rb +1 -1
- data/lib/metro/transitions/edit_transition_scene.rb +28 -1
- data/lib/metro/units/dimensions.rb +29 -2
- data/lib/metro/units/point.rb +16 -4
- data/lib/metro/units/rectangle_bounds.rb +38 -16
- data/lib/metro/version.rb +1 -1
- data/lib/setup_handlers/reload_game_on_game_file_changes.rb +6 -1
- data/lib/templates/game/scenes/first_scene.rb +4 -0
- metadata +14 -8
@@ -0,0 +1,54 @@
|
|
1
|
+
module Metro
|
2
|
+
module UI
|
3
|
+
|
4
|
+
class FPS < Metro::Model
|
5
|
+
|
6
|
+
property :placement, type: :text, default: 'top'
|
7
|
+
property :color, default: "rgba(255,255,255,1.0)"
|
8
|
+
|
9
|
+
property :label, type: :model do
|
10
|
+
create "metro::ui::label", text: "FPS: 0", color: color
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid_placements
|
14
|
+
@valid_placements ||= begin
|
15
|
+
{
|
16
|
+
top_left: { position: Game.bounds.top_left, align: 'left', vertical_align: 'top' },
|
17
|
+
top: { position: Point.at(Game.center.x, Game.bounds.top), align: 'center', vertical_align: 'top' },
|
18
|
+
top_right: { position: Game.bounds.top_right, align: 'right', vertical_align: 'top' },
|
19
|
+
right: { position: Point.at(Game.bounds.right, Game.center.y), align: 'right', vertical_align: 'center' },
|
20
|
+
bottom_right: { position: Game.bounds.bottom_right, align: 'right', vertical_align: 'bottom' },
|
21
|
+
bottom: { position: Point.at(Game.center.x, Game.bounds.bottom), align: 'right', vertical_align: 'bottom' },
|
22
|
+
bottom_left: { position: Game.bounds.bottom_right, align: 'left', vertical_align: 'bottom' },
|
23
|
+
left: { position: Point.at(Game.bounds.left, Game.center.y), align: 'left', vertical_align: 'center' }
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
@valid_placements.default = :top
|
28
|
+
@valid_placements
|
29
|
+
end
|
30
|
+
|
31
|
+
def show
|
32
|
+
place_label
|
33
|
+
end
|
34
|
+
|
35
|
+
def place_label
|
36
|
+
placement_hash = valid_placements[placement.to_sym]
|
37
|
+
|
38
|
+
label.align = placement_hash[:align]
|
39
|
+
label.vertical_align = placement_hash[:vertical_align]
|
40
|
+
label.position = placement_hash[:position]
|
41
|
+
end
|
42
|
+
|
43
|
+
def update
|
44
|
+
label.text = "FPS: #{Gosu.fps}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def draw
|
48
|
+
label.draw
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -18,7 +18,14 @@ module Metro
|
|
18
18
|
#
|
19
19
|
class Generic < Model
|
20
20
|
|
21
|
-
|
21
|
+
# @attribute
|
22
|
+
# Sets whether the generic model has warned the user in the logs about it
|
23
|
+
# being a generic model.
|
24
|
+
property :warned, type: :boolean, default: false
|
25
|
+
|
26
|
+
def show
|
27
|
+
self.saveable_to_view = false
|
28
|
+
end
|
22
29
|
|
23
30
|
def draw
|
24
31
|
log.warn cannot_draw_message unless warned
|
@@ -15,23 +15,35 @@ module Metro
|
|
15
15
|
#
|
16
16
|
class GridDrawer < Model
|
17
17
|
|
18
|
+
# @attribute
|
19
|
+
# The position to start drawing the grid
|
18
20
|
property :position, default: Point.at(0,0,100)
|
21
|
+
|
22
|
+
# @attribute
|
23
|
+
# The color of the grid lines
|
19
24
|
property :color, default: "rgba(255,255,255,0.1)"
|
25
|
+
|
26
|
+
# @attribute
|
27
|
+
# The interval which to draw the lines
|
20
28
|
property :spacing, type: :numeric, default: 10
|
21
29
|
|
30
|
+
# @attribute
|
31
|
+
# The dimension of the grid
|
22
32
|
property :dimensions do
|
23
33
|
Dimensions.of Game.width, Game.height
|
24
34
|
end
|
25
35
|
|
26
|
-
|
27
|
-
|
28
|
-
|
36
|
+
# @attribute
|
37
|
+
# This controls whether the grid should be drawn. By default
|
38
|
+
# the grid will be drawn.
|
39
|
+
property :enabled, type: :boolean, default: true
|
29
40
|
|
30
|
-
def
|
31
|
-
false
|
41
|
+
def show
|
42
|
+
self.saveable_to_view = false
|
32
43
|
end
|
33
44
|
|
34
45
|
def draw
|
46
|
+
return unless enabled
|
35
47
|
draw_horizontal_lines
|
36
48
|
draw_vertical_lines
|
37
49
|
end
|
@@ -13,32 +13,47 @@ module Metro
|
|
13
13
|
#
|
14
14
|
class Image < Model
|
15
15
|
|
16
|
+
# @attribute
|
17
|
+
# The position of the image
|
16
18
|
property :position
|
17
19
|
|
20
|
+
# @attribute
|
21
|
+
# The scale of the image
|
18
22
|
property :scale, default: Scale.one
|
19
23
|
|
24
|
+
# @attribute
|
25
|
+
# The color of the image, by default this is white to display the image
|
26
|
+
# as normal, but this can be used to augment the look of the image. Mostly
|
27
|
+
# color is use for the sub-property :alpha which allows an image to be
|
28
|
+
# faded-in and faded-out
|
20
29
|
property :color
|
21
30
|
|
31
|
+
# @attribute
|
32
|
+
# The angle at which to draw the image
|
22
33
|
property :angle, type: :numeric, default: 0
|
23
34
|
|
35
|
+
# @attribute
|
36
|
+
# The center x position of the image as expressed in a scale of from left
|
37
|
+
# to right (0.0 to 1.0).
|
24
38
|
property :center_x, type: :numeric, default: 0.5
|
39
|
+
|
40
|
+
# @attribute
|
41
|
+
# The center y position of the image as expressed in a scale of from top
|
42
|
+
# to bottom (0.0 to 1.0).
|
25
43
|
property :center_y, type: :numeric, default: 0.5
|
26
44
|
|
45
|
+
# @attribute
|
46
|
+
# The image asset to draw.
|
27
47
|
property :image
|
28
48
|
|
49
|
+
# @attribute
|
50
|
+
# The dimensions of the image.
|
29
51
|
property :dimensions do
|
30
52
|
image.dimensions
|
31
53
|
end
|
32
54
|
|
33
|
-
def contains?(x,y)
|
34
|
-
bounds.contains?(x,y)
|
35
|
-
end
|
36
|
-
|
37
55
|
def bounds
|
38
|
-
Bounds.new
|
39
|
-
y: y - (height * center_y),
|
40
|
-
width: width,
|
41
|
-
height: height
|
56
|
+
Bounds.new left: left_x, right: right_x, top: top_y, bottom: bottom_y
|
42
57
|
end
|
43
58
|
|
44
59
|
def draw
|
@@ -49,6 +64,23 @@ module Metro
|
|
49
64
|
color
|
50
65
|
end
|
51
66
|
|
67
|
+
private
|
68
|
+
|
69
|
+
def left_x
|
70
|
+
x - (width * center_x)
|
71
|
+
end
|
72
|
+
|
73
|
+
def right_x
|
74
|
+
left_x + width
|
75
|
+
end
|
76
|
+
|
77
|
+
def top_y
|
78
|
+
y - (height * center_y)
|
79
|
+
end
|
80
|
+
|
81
|
+
def bottom_y
|
82
|
+
top_y + height
|
83
|
+
end
|
52
84
|
end
|
53
85
|
|
54
86
|
end
|
@@ -15,21 +15,54 @@ module Metro
|
|
15
15
|
#
|
16
16
|
class Label < Model
|
17
17
|
|
18
|
+
# @attribute
|
19
|
+
# The position of the label
|
18
20
|
property :position
|
19
21
|
|
22
|
+
# @attribute
|
23
|
+
# The scale of the text
|
20
24
|
property :scale, default: Scale.one
|
21
25
|
|
26
|
+
# @attribute
|
27
|
+
# The text color
|
22
28
|
property :color, default: "rgba(255,255,255,1.0)"
|
23
29
|
|
30
|
+
# @attribute
|
31
|
+
# The font to use for the label text
|
24
32
|
property :font, default: { size: 20 }
|
25
33
|
|
34
|
+
# @attribute
|
35
|
+
# The text to appear on the label
|
26
36
|
property :text
|
27
37
|
|
38
|
+
# @attribute
|
39
|
+
# The alignment for the label. This influences where the text draws in
|
40
|
+
# relation to the specified position. Your choices are 'left', 'center',
|
41
|
+
# and 'right'. The default is 'left'.
|
28
42
|
property :align, type: :text, default: "left"
|
43
|
+
|
44
|
+
# @attribute
|
45
|
+
# The vertical alignment for the label. This influences where the text
|
46
|
+
# draws in relation to the specified position. Your choices are 'top',
|
47
|
+
# 'center', and 'bottom'. This default is 'top'
|
29
48
|
property :vertical_align, type: :text, default: "top"
|
30
49
|
|
50
|
+
# @attribute
|
51
|
+
# When calculating the dimensions of the label, this is the minimum
|
52
|
+
# dimensions. This is necessary in cases when the text is blank. This
|
53
|
+
# allows for the label to have size when in the edit mode.
|
54
|
+
property :minimum_dimensions, type: :dimensions, default: "16,16"
|
55
|
+
|
56
|
+
# @attribute
|
57
|
+
# The dimensions of label. If the label text is blank, then the dimensions
|
58
|
+
# of the label will return a minimum dimension.
|
31
59
|
property :dimensions do
|
32
|
-
Dimensions.of (longest_line * x_factor), (line_height * line_count *
|
60
|
+
calculated = Dimensions.of (longest_line * x_factor), (line_height * line_count * y_factor)
|
61
|
+
[ calculated, minimum_dimensions ].max
|
62
|
+
end
|
63
|
+
|
64
|
+
def bounds
|
65
|
+
Bounds.new left: left_x, right: right_x, top: top_y, bottom: bottom_y
|
33
66
|
end
|
34
67
|
|
35
68
|
def draw
|
@@ -38,15 +71,23 @@ module Metro
|
|
38
71
|
end
|
39
72
|
end
|
40
73
|
|
41
|
-
|
42
|
-
|
74
|
+
private
|
75
|
+
|
76
|
+
def left_x
|
77
|
+
line_count.times.map { |index| x_position(index) }.min
|
43
78
|
end
|
44
79
|
|
45
|
-
def
|
46
|
-
|
80
|
+
def right_x
|
81
|
+
left_x + width
|
47
82
|
end
|
48
83
|
|
49
|
-
|
84
|
+
def top_y
|
85
|
+
y_position(0)
|
86
|
+
end
|
87
|
+
|
88
|
+
def bottom_y
|
89
|
+
top_y + height
|
90
|
+
end
|
50
91
|
|
51
92
|
def line_height
|
52
93
|
font.height
|
@@ -61,7 +102,7 @@ module Metro
|
|
61
102
|
end
|
62
103
|
|
63
104
|
def longest_line
|
64
|
-
parsed_text.map { |line| line_width(line) }.max
|
105
|
+
parsed_text.map { |line| line_width(line) }.max || 0
|
65
106
|
end
|
66
107
|
|
67
108
|
def line_count
|
data/lib/metro/models/ui/menu.rb
CHANGED
@@ -56,20 +56,42 @@ module Metro
|
|
56
56
|
#
|
57
57
|
class Menu < Model
|
58
58
|
|
59
|
+
# @attribute
|
60
|
+
# The position of the menu
|
59
61
|
property :position, default: Game.center
|
62
|
+
|
63
|
+
# @attribute
|
64
|
+
# The alpha level of the menu from 0 to 255.
|
60
65
|
property :alpha, default: 255
|
61
66
|
|
67
|
+
# @attribute
|
68
|
+
# The scale at which the menu should be drawn.
|
62
69
|
property :scale, default: Scale.one
|
63
70
|
|
64
|
-
|
71
|
+
# @attribute
|
72
|
+
# The distance between each of the menu items
|
73
|
+
property :padding, default: 20
|
65
74
|
|
75
|
+
# @attribute
|
76
|
+
# The dimensions of the menu. This is based on the items within the
|
77
|
+
# menu.
|
66
78
|
property :dimensions do
|
67
|
-
Dimensions.
|
79
|
+
Dimensions.of (right_x - left_x), (bottom_y - top_y)
|
68
80
|
end
|
69
81
|
|
82
|
+
# @attribute
|
83
|
+
# The options that are displayed in the menu. These are by default
|
84
|
+
# 'metro::ui::labels' But can be defined more dynamically as neeeded.
|
85
|
+
#
|
86
|
+
# @see Metro::Model::Property::OptionsProperty
|
70
87
|
property :options
|
71
88
|
|
89
|
+
# @attribute
|
90
|
+
# The color for all the currently unselected items.
|
72
91
|
property :unselected_color, type: :color, default: "rgba(119,119,119,1.0)"
|
92
|
+
|
93
|
+
# @attribute
|
94
|
+
# The color of the item that currently has focus.
|
73
95
|
property :selected_color, type: :color, default: "rgba(255,255,255,1.0)"
|
74
96
|
|
75
97
|
def alpha_changed(alpha)
|
@@ -82,20 +104,51 @@ module Metro
|
|
82
104
|
self.unselected_color_alpha = alpha
|
83
105
|
end
|
84
106
|
|
107
|
+
# @attribute
|
108
|
+
# The sample sound that plays when a selection has been made.
|
85
109
|
property :selection_sample, type: :sample, path: "menu-selection.wav"
|
110
|
+
|
111
|
+
# @attribute
|
112
|
+
# The sample sound when moving between the different options in the menu.
|
86
113
|
property :movement_sample, type: :sample, path: "menu-movement.wav"
|
87
114
|
|
115
|
+
# @attribute
|
116
|
+
# Determines whether the menu is currently enabled or disabled.
|
88
117
|
property :enabled, type: :boolean, default: true
|
89
118
|
|
90
|
-
#
|
119
|
+
# @attribute
|
120
|
+
# Allows the menu to be layouted out in a 'horizontal' or 'vertical'
|
121
|
+
# fashion. By default this is 'vertical'
|
91
122
|
property :layout, type: :text, default: "vertical"
|
92
123
|
|
93
|
-
def
|
94
|
-
|
124
|
+
def bounds
|
125
|
+
Bounds.new left: left_x, right: right_x, top: top_y, bottom: bottom_y
|
95
126
|
end
|
96
127
|
|
97
|
-
|
98
|
-
|
128
|
+
#
|
129
|
+
# When the position has changed on every other time beside the first time
|
130
|
+
# we want to update the position of all the options defined in the menu.
|
131
|
+
#
|
132
|
+
def position_changed(new_position)
|
133
|
+
return unless properties[:position]
|
134
|
+
difference = Point.parse(new_position) - Point.parse(properties[:position])
|
135
|
+
options.each { |option| option.position += difference }
|
136
|
+
end
|
137
|
+
|
138
|
+
def left_x
|
139
|
+
options.map {|option| option.bounds.left }.min
|
140
|
+
end
|
141
|
+
|
142
|
+
def right_x
|
143
|
+
options.map {|option| option.bounds.right }.max
|
144
|
+
end
|
145
|
+
|
146
|
+
def top_y
|
147
|
+
options.map {|option| option.bounds.top }.min
|
148
|
+
end
|
149
|
+
|
150
|
+
def bottom_y
|
151
|
+
options.map {|option| option.bounds.bottom }.max
|
99
152
|
end
|
100
153
|
|
101
154
|
# @TODO: enable the user to define the events for this interaction
|
@@ -153,7 +206,7 @@ module Metro
|
|
153
206
|
end
|
154
207
|
|
155
208
|
def draw
|
156
|
-
options.
|
209
|
+
options.each { |label| label.draw }
|
157
210
|
end
|
158
211
|
|
159
212
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Metro
|
2
|
+
module UI
|
3
|
+
|
4
|
+
#
|
5
|
+
# The model label will draw a bounding box and label around another model
|
6
|
+
#
|
7
|
+
# The model label is used by the model labeler which is a facet of the
|
8
|
+
# edit scene
|
9
|
+
#
|
10
|
+
class ModelLabel < Metro::Model
|
11
|
+
|
12
|
+
# Stores the model that is currently being labeled.
|
13
|
+
attr_accessor :target
|
14
|
+
|
15
|
+
def bounds=(bounds)
|
16
|
+
bounding_box.position = bounds.top_left
|
17
|
+
label.position = bounds.top_left + Point.at(4,2,label_z_order)
|
18
|
+
label_background.position = label.position - Point.at(2,0,1)
|
19
|
+
end
|
20
|
+
|
21
|
+
property :bounding_box_color, type: :color, default: "rgba(255,0,0,0.5)"
|
22
|
+
property :font, default: { size: 16 }
|
23
|
+
property :label_color, type: :color, default: "rgba(255,255,255,1.0)"
|
24
|
+
property :label_background_color, type: :color, default: "rgba(255,0,0,0.5)"
|
25
|
+
|
26
|
+
property :should_draw_bounding_box, type: :boolean, default: true
|
27
|
+
property :should_draw_label, type: :boolean, default: true
|
28
|
+
|
29
|
+
property :bounding_box, type: :model do
|
30
|
+
create "metro::ui::border", color: bounding_box_color,
|
31
|
+
dimensions: target.bounds.dimensions
|
32
|
+
end
|
33
|
+
|
34
|
+
property :label, type: :model do
|
35
|
+
create "metro::ui::label", text: target.name, font: font,
|
36
|
+
position: target.bounds.top_left + Point.at(4,2,label_z_order)
|
37
|
+
end
|
38
|
+
|
39
|
+
def label_z_order
|
40
|
+
target.respond_to?(:z_order) ? target.z_order + 2 : 0
|
41
|
+
end
|
42
|
+
|
43
|
+
property :label_background, type: :model do
|
44
|
+
create "metro::ui::rectangle", color: label_background_color,
|
45
|
+
position: label.position - Point.at(2,0,1),
|
46
|
+
dimensions: label.dimensions + Dimensions.of(6,4)
|
47
|
+
end
|
48
|
+
|
49
|
+
def draw
|
50
|
+
draw_bounding_box if should_draw_bounding_box
|
51
|
+
draw_label if should_draw_label
|
52
|
+
end
|
53
|
+
|
54
|
+
def draw_bounding_box
|
55
|
+
bounding_box.draw
|
56
|
+
end
|
57
|
+
|
58
|
+
def draw_label
|
59
|
+
label_background.draw
|
60
|
+
label.draw
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|