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