metro 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- attr_accessor :warned
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
- def saveable?
27
- false
28
- end
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 contains?(x,y)
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 x: x - (width * center_x),
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 * 2 * y_factor)
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
- def bounds
42
- Bounds.new x: x, y: y, width: width, height: height
74
+ private
75
+
76
+ def left_x
77
+ line_count.times.map { |index| x_position(index) }.min
43
78
  end
44
79
 
45
- def contains?(x,y)
46
- bounds.contains?(x,y)
80
+ def right_x
81
+ left_x + width
47
82
  end
48
83
 
49
- private
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
@@ -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
- property :padding, default: 10
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.none
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
- # Allows the menu to be layouted out horizontal or vertical
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 contains?(x,y)
94
- bounds.contains?(x,y)
124
+ def bounds
125
+ Bounds.new left: left_x, right: right_x, top: top_y, bottom: bottom_y
95
126
  end
96
127
 
97
- def bounds
98
- Bounds.new x: x, y: y, width: width, height: height
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.each_with_index { |label| label.draw }
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