metro 0.1.5 → 0.1.6
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 +19 -0
- data/changelog.md +8 -0
- data/lib/assets/missing_animation.png +0 -0
- data/lib/commands/generate_model.rb +2 -2
- data/lib/commands/generate_scene.rb +12 -2
- data/lib/commands/generate_view.rb +1 -1
- data/lib/gosu_ext/color.rb +1 -1
- data/lib/gosu_ext/image.rb +5 -0
- data/lib/metro.rb +18 -5
- data/lib/metro/animation/animation.rb +31 -0
- data/lib/metro/asset_path.rb +9 -0
- data/lib/metro/events/event_dictionary.rb +53 -0
- data/lib/metro/events/event_factory.rb +5 -3
- data/lib/metro/events/has_events.rb +5 -6
- data/lib/metro/game.rb +1 -1
- data/lib/metro/models/dimensions.rb +21 -0
- data/lib/metro/models/model.rb +149 -52
- data/lib/metro/models/model_factory.rb +4 -5
- data/lib/metro/models/{generic.rb → models/generic.rb} +0 -0
- data/lib/metro/models/{grid_drawer.rb → models/grid_drawer.rb} +4 -9
- data/lib/metro/models/{image.rb → models/image.rb} +11 -14
- data/lib/metro/models/models/label.rb +44 -0
- data/lib/metro/models/{menu.rb → models/menu.rb} +23 -18
- data/lib/metro/models/{rectangle.rb → models/rectangle.rb} +6 -5
- data/lib/metro/models/point.rb +23 -0
- data/lib/metro/models/properties/angle.rb +43 -0
- data/lib/metro/models/properties/animation.rb +143 -0
- data/lib/metro/models/properties/color.rb +113 -0
- data/lib/metro/models/properties/dimensions.rb +66 -0
- data/lib/metro/models/properties/font.rb +155 -0
- data/lib/metro/models/properties/image.rb +101 -0
- data/lib/metro/models/properties/numeric.rb +29 -0
- data/lib/metro/models/properties/position.rb +84 -0
- data/lib/metro/models/properties/property.rb +111 -0
- data/lib/metro/models/properties/scale.rb +89 -0
- data/lib/metro/models/properties/text.rb +66 -0
- data/lib/metro/models/properties/velocity.rb +80 -0
- data/lib/metro/models/scale.rb +21 -0
- data/lib/metro/scene.rb +19 -1
- data/lib/metro/scenes.rb +91 -31
- data/lib/metro/transitions/scene_transitions.rb +8 -0
- data/lib/metro/version.rb +1 -1
- data/lib/metro/views/view.rb +9 -1
- data/lib/templates/game/metro.tt +1 -1
- data/lib/templates/game/models/game_model.rb +3 -0
- data/lib/templates/game/scenes/brand_scene.rb +1 -1
- data/lib/templates/game/scenes/brand_to_title_scene.rb +1 -1
- data/lib/templates/game/scenes/game_scene.rb +19 -0
- data/lib/templates/game/scenes/title_scene.rb +1 -1
- data/lib/templates/game/views/brand_to_title.yaml +2 -2
- data/lib/templates/game/views/title.yaml +3 -3
- data/lib/templates/{model.rb.erb → model.rb.tt} +1 -1
- data/lib/templates/{scene.rb.erb → scene.rb.tt} +1 -1
- data/lib/templates/view.yaml.tt +6 -0
- data/spec/metro/models/models/label_spec.rb +110 -0
- data/spec/metro/models/properties/color_spec.rb +85 -0
- data/spec/metro/models/properties/font_spec.rb +129 -0
- data/spec/metro/models/properties/numeric_property_spec.rb +46 -0
- data/spec/metro/models/properties/position_property_spec.rb +90 -0
- data/spec/metro/scenes_spec.rb +77 -0
- metadata +50 -16
- data/lib/metro/models/label.rb +0 -63
- data/lib/templates/view.yaml.erb +0 -32
@@ -9,10 +9,9 @@ module Metro
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def create
|
12
|
-
|
13
|
-
actor_class = class_for_actor(model_name(contents))
|
12
|
+
actor_class = class_for_actor(model_name)
|
14
13
|
instance = actor_class.new
|
15
|
-
instance._load options
|
14
|
+
instance._load options
|
16
15
|
instance
|
17
16
|
end
|
18
17
|
|
@@ -20,8 +19,8 @@ module Metro
|
|
20
19
|
options[:from] == :previous_scene
|
21
20
|
end
|
22
21
|
|
23
|
-
def model_name
|
24
|
-
|
22
|
+
def model_name
|
23
|
+
options['model'] || options[:model] || name
|
25
24
|
end
|
26
25
|
|
27
26
|
def class_for_actor(model_name)
|
File without changes
|
@@ -3,16 +3,15 @@ module Metro
|
|
3
3
|
|
4
4
|
class GridDrawer < Model
|
5
5
|
|
6
|
-
|
6
|
+
property :color, default: "rgba(255,255,255,0.1)"
|
7
|
+
property :spacing, type: :numeric, default: 10
|
8
|
+
|
9
|
+
attr_writer :spacing, :height, :width
|
7
10
|
|
8
11
|
def name
|
9
12
|
self.class.name
|
10
13
|
end
|
11
14
|
|
12
|
-
def spacing
|
13
|
-
@spacing ||= 10
|
14
|
-
end
|
15
|
-
|
16
15
|
def height
|
17
16
|
@height || Game.height
|
18
17
|
end
|
@@ -21,10 +20,6 @@ module Metro
|
|
21
20
|
@width || Game.width
|
22
21
|
end
|
23
22
|
|
24
|
-
def color
|
25
|
-
@color ||= Gosu::Color.new("rgba(255,255,255,0.1)")
|
26
|
-
end
|
27
|
-
|
28
23
|
def saveable?
|
29
24
|
false
|
30
25
|
end
|
@@ -9,21 +9,18 @@ module Metro
|
|
9
9
|
#
|
10
10
|
class Image < Model
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
def after_initialize
|
15
|
-
@angle = 0
|
16
|
-
@center_x = @center_y = 0.5
|
17
|
-
@x_factor = @y_factor = 1
|
18
|
-
@z_order = 0
|
19
|
-
@color = Gosu::Color.new "rgba(255,255,255,1.0)"
|
20
|
-
@x = Game.width / 2
|
21
|
-
@y = Game.height / 2
|
22
|
-
end
|
12
|
+
property :position
|
23
13
|
|
24
|
-
|
25
|
-
|
26
|
-
|
14
|
+
property :scale, default: Scale.one
|
15
|
+
|
16
|
+
property :color
|
17
|
+
|
18
|
+
property :angle, type: :numeric, default: 0
|
19
|
+
|
20
|
+
property :center_x, type: :numeric, default: 0.5
|
21
|
+
property :center_y, type: :numeric, default: 0.5
|
22
|
+
|
23
|
+
property :image
|
27
24
|
|
28
25
|
def contains?(x,y)
|
29
26
|
bounds.contains?(x,y)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Metro
|
2
|
+
module Models
|
3
|
+
|
4
|
+
#
|
5
|
+
# Draws a string of text
|
6
|
+
#
|
7
|
+
# @example Using the Label in a view file
|
8
|
+
# model: "metro::models::label"
|
9
|
+
#
|
10
|
+
class Label < Model
|
11
|
+
|
12
|
+
property :position
|
13
|
+
|
14
|
+
property :scale, default: Scale.one
|
15
|
+
|
16
|
+
property :color, default: "rgba(255,255,255,1.0)"
|
17
|
+
|
18
|
+
property :font, default: { size: 20 }
|
19
|
+
|
20
|
+
property :text
|
21
|
+
|
22
|
+
def bounds
|
23
|
+
Bounds.new x, y, x + width, y + height
|
24
|
+
end
|
25
|
+
|
26
|
+
def width
|
27
|
+
font.text_width(text) * x_factor
|
28
|
+
end
|
29
|
+
|
30
|
+
def height
|
31
|
+
font.height * y_factor
|
32
|
+
end
|
33
|
+
|
34
|
+
def contains?(x,y)
|
35
|
+
bounds.contains?(x,y)
|
36
|
+
end
|
37
|
+
|
38
|
+
def draw
|
39
|
+
font.draw text, x, y, z_order, x_factor, y_factor, color
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -10,6 +10,26 @@ module Metro
|
|
10
10
|
#
|
11
11
|
class Menu < Model
|
12
12
|
|
13
|
+
property :position, default: Game.center
|
14
|
+
|
15
|
+
property :scale, default: Scale.one
|
16
|
+
|
17
|
+
property :padding, type: :numeric, default: 40
|
18
|
+
|
19
|
+
property :unselected_color, type: :color, default: "rgba(119,119,119,1.0)"
|
20
|
+
property :selected_color, type: :color, default: "rgba(255,255,255,1.0)"
|
21
|
+
|
22
|
+
def alpha
|
23
|
+
self.unselected_color_alpha
|
24
|
+
end
|
25
|
+
|
26
|
+
def alpha=(value)
|
27
|
+
self.unselected_color_alpha = value.floor
|
28
|
+
self.selected_color_alpha = value.floor
|
29
|
+
end
|
30
|
+
|
31
|
+
property :font
|
32
|
+
|
13
33
|
event :on_up, KbLeft, GpLeft, KbUp, GpUp do
|
14
34
|
previous_option
|
15
35
|
end
|
@@ -24,12 +44,8 @@ module Metro
|
|
24
44
|
|
25
45
|
attr_reader :selected_index, :menu_options
|
26
46
|
|
27
|
-
attr_accessor :padding, :z_order
|
28
|
-
|
29
47
|
def after_initialize
|
30
48
|
@selected_index = 0
|
31
|
-
@padding = 40
|
32
|
-
@z_order = 1
|
33
49
|
end
|
34
50
|
|
35
51
|
def window=(value)
|
@@ -76,17 +92,6 @@ module Metro
|
|
76
92
|
options.length * font.height + (options.length - 1) * padding
|
77
93
|
end
|
78
94
|
|
79
|
-
attr_reader :highlight_color
|
80
|
-
|
81
|
-
def highlight_color=(value)
|
82
|
-
@highlight_color = Gosu::Color.new(value)
|
83
|
-
end
|
84
|
-
|
85
|
-
def alpha=(value)
|
86
|
-
color.alpha = value.floor
|
87
|
-
highlight_color.alpha = value.floor
|
88
|
-
end
|
89
|
-
|
90
95
|
def option_at_index(index)
|
91
96
|
menu_options[index]
|
92
97
|
end
|
@@ -96,11 +101,11 @@ module Metro
|
|
96
101
|
|
97
102
|
option_name = option_at_index(index).name
|
98
103
|
|
99
|
-
draw_color =
|
100
|
-
draw_color =
|
104
|
+
draw_color = unselected_color
|
105
|
+
draw_color = selected_color if index == selected_index
|
101
106
|
|
102
107
|
y_position = y + padding * index
|
103
|
-
font.draw option_name, x, y_position, z_order,
|
108
|
+
font.draw option_name, x, y_position, z_order, x_factor, y_factor, draw_color
|
104
109
|
end
|
105
110
|
end
|
106
111
|
|
@@ -3,12 +3,13 @@ module Metro
|
|
3
3
|
|
4
4
|
class Rectangle < ::Metro::Model
|
5
5
|
|
6
|
-
|
6
|
+
property :position
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
property :z_order, type: :numeric, default: 0
|
9
|
+
|
10
|
+
property :color
|
11
|
+
|
12
|
+
attr_writer :width, :height
|
12
13
|
|
13
14
|
def width
|
14
15
|
@width || window.width
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Metro
|
2
|
+
class Point < Struct.new(:x,:y,:z)
|
3
|
+
def self.zero
|
4
|
+
new 0.0, 0.0, 0.0
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.at(x,y,z=0.0)
|
8
|
+
new x.to_f, y.to_f, z.to_f
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.parse(string)
|
12
|
+
at *string.split(",",3).map(&:to_f)
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method :z_order, :z
|
16
|
+
alias_method :z_order=, :z=
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"#{x},#{y},#{z}"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Metro
|
2
|
+
class Model
|
3
|
+
|
4
|
+
class AngleProperty < Property
|
5
|
+
|
6
|
+
def get(value)
|
7
|
+
value ? value : Angle.new(0.0, options[:step])
|
8
|
+
end
|
9
|
+
|
10
|
+
def set(value)
|
11
|
+
Angle.new(value.to_f, options[:step])
|
12
|
+
end
|
13
|
+
|
14
|
+
class Angle
|
15
|
+
|
16
|
+
attr_reader :value
|
17
|
+
|
18
|
+
def initialize(value = 0.0,step = 1.0)
|
19
|
+
@value = value.to_f
|
20
|
+
@step = step || 1.0
|
21
|
+
end
|
22
|
+
|
23
|
+
def turn(direction)
|
24
|
+
send(direction) if [ :left, :right ].include?(direction)
|
25
|
+
end
|
26
|
+
|
27
|
+
def left
|
28
|
+
@value -= @step
|
29
|
+
end
|
30
|
+
|
31
|
+
def right
|
32
|
+
@value += @step
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_f
|
36
|
+
@value.to_f
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require_relative '../../animation/animation'
|
2
|
+
|
3
|
+
module Metro
|
4
|
+
class Model
|
5
|
+
|
6
|
+
#
|
7
|
+
# A animation property manages an Animation, which is an array of Gosu::Images,
|
8
|
+
# and some metadata.
|
9
|
+
#
|
10
|
+
# @see Animation
|
11
|
+
#
|
12
|
+
# A animation is stored in the properties as a hash representation and is
|
13
|
+
# converted into an Animation when it is retrieved within the system.
|
14
|
+
#
|
15
|
+
# The animate images are cached within the animation property to help
|
16
|
+
# performance by reducing the unncessary creation of similar animations.
|
17
|
+
#
|
18
|
+
# @example Defining an animation property (will default to the missing animation)
|
19
|
+
#
|
20
|
+
# class Scoreboard < Metro::Model
|
21
|
+
# property :animation
|
22
|
+
#
|
23
|
+
# def draw
|
24
|
+
# animation.image.draw text, x, y, z_order, x_factor, y_factor, color
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# @example Defining an animation default.
|
29
|
+
#
|
30
|
+
# class Hero < Metro::Model
|
31
|
+
# property :animation, default: { path: "star.png",
|
32
|
+
# dimensions: Metro::Dimensions.of(25,25) }
|
33
|
+
#
|
34
|
+
# def draw
|
35
|
+
# animation.image.draw text, x, y, z_order, x_factor, y_factor, color
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# @example Using an animation property with a different property name
|
40
|
+
#
|
41
|
+
# class Hero < Metro::Model
|
42
|
+
# property :walking, type: :animation, default: { path: "star.png",
|
43
|
+
# dimensions: Metro::Dimensions.of(25,25) }
|
44
|
+
#
|
45
|
+
# def draw
|
46
|
+
# walking.image.draw text, x, y, z_order, x_factor, y_factor, color
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
class AnimationProperty < Property
|
51
|
+
|
52
|
+
# By default return the default animation when getting a nil or
|
53
|
+
# other unsupported value.
|
54
|
+
get do
|
55
|
+
default_animation
|
56
|
+
end
|
57
|
+
|
58
|
+
# When getting a hash, create the animation with the properties.
|
59
|
+
get Hash do |value|
|
60
|
+
self.class.animation_for value.merge(window: model.window)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Setting the animation with a nil or other unsupported value
|
64
|
+
# will default to the default animation.
|
65
|
+
set do
|
66
|
+
default_animation.to_hash
|
67
|
+
end
|
68
|
+
|
69
|
+
# Setting with an animation will convert it to it's hash representation.
|
70
|
+
set Animation do |image|
|
71
|
+
image.to_hash
|
72
|
+
end
|
73
|
+
|
74
|
+
# Setting with a hash will assume the hash defines an animation.
|
75
|
+
set Hash do |value|
|
76
|
+
value
|
77
|
+
end
|
78
|
+
|
79
|
+
def default_animation
|
80
|
+
self.class.animation_for window: model.window,
|
81
|
+
path: default_image_path,
|
82
|
+
width: default_dimensions.width,
|
83
|
+
height: default_dimensions.height,
|
84
|
+
tileable: false
|
85
|
+
end
|
86
|
+
|
87
|
+
def default_image_path
|
88
|
+
if options[:default] and options[:default][:path]
|
89
|
+
asset_path(options[:default][:path])
|
90
|
+
else
|
91
|
+
metro_asset_path("missing_animation.png")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def default_dimensions
|
96
|
+
if options[:default] and options[:default][:dimensions]
|
97
|
+
options[:default][:dimensions]
|
98
|
+
else
|
99
|
+
Dimensions.of 16.0, 16.0
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# Return an animation for the specified path. On first request it will be loaded from
|
105
|
+
# the file-system. On subsequent requests it will be pulled from the cache.
|
106
|
+
#
|
107
|
+
# @param [Hash] options the relative `path` to the image and the window for which it
|
108
|
+
# will be displayed.
|
109
|
+
#
|
110
|
+
def self.animation_for(options)
|
111
|
+
options.symbolize_keys!
|
112
|
+
window = options[:window]
|
113
|
+
|
114
|
+
absolute_path = path = options[:path]
|
115
|
+
absolute_path = asset_path(absolute_path) unless absolute_path.start_with? "/"
|
116
|
+
|
117
|
+
width = options[:width].to_i
|
118
|
+
height = options[:height].to_i
|
119
|
+
tileable = options[:tileable]
|
120
|
+
|
121
|
+
animation_images = images[path]
|
122
|
+
unless animation_images
|
123
|
+
animation_images = create_image(window,absolute_path,width,height,tileable)
|
124
|
+
images[path] = animation_images
|
125
|
+
end
|
126
|
+
|
127
|
+
Animation.new options.merge(images: animation_images)
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.images
|
131
|
+
@images ||= {}
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def self.create_image(window,path,width,height,tileable)
|
137
|
+
Gosu::Image.load_tiles(window,path,width,height,tileable)
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Metro
|
2
|
+
class Model
|
3
|
+
|
4
|
+
#
|
5
|
+
# A color property maintains a Gosu::Color.
|
6
|
+
#
|
7
|
+
# A color property also defines an alpha property which allows a more direct interface
|
8
|
+
# to setting the alpha property on the color. This is useful in cases for images where
|
9
|
+
# the color remains as white but the alpha value needs to be adjusted.
|
10
|
+
#
|
11
|
+
# A color is stored in the properties as a string representation and is converted into
|
12
|
+
# a Gosu::Color when it is retrieved within the system.
|
13
|
+
#
|
14
|
+
# @example Defining a color property using the color properties default
|
15
|
+
#
|
16
|
+
# class Hero < Metro::Model
|
17
|
+
# property :color
|
18
|
+
#
|
19
|
+
# def draw
|
20
|
+
# image.draw x, y, z_order, x_factor, y_factor, color, :add)
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# @example Defining a color property providing a default
|
26
|
+
#
|
27
|
+
# class Hero < Metro::Model
|
28
|
+
# property :color, default: "rgba(255,0,0,1.0)"
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# @example Using the alpha property
|
32
|
+
#
|
33
|
+
# class Hero < Metro::Model
|
34
|
+
# property :color, default: "rgba(255,0,0,1.0)"
|
35
|
+
#
|
36
|
+
# def become_ghost!
|
37
|
+
# self.alpha = 127
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# @example Using a color property with a different property name
|
42
|
+
#
|
43
|
+
# class Hero < Metro::Model
|
44
|
+
# property :color
|
45
|
+
# property :invincible_color, type: :color, default: "rgba(255,0,255,1.0)"
|
46
|
+
#
|
47
|
+
# def draw
|
48
|
+
# if invincible?
|
49
|
+
# image.draw x, y, z_order, x_factor, y_factor, invincible_color, :add)
|
50
|
+
# else
|
51
|
+
# image.draw x, y, z_order, x_factor, y_factor, color, :add)
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
class ColorProperty < Property
|
57
|
+
|
58
|
+
define_property :alpha
|
59
|
+
|
60
|
+
# By default convert the value to the default color if it
|
61
|
+
# cannot be processed by the other get filters.
|
62
|
+
get do |value|
|
63
|
+
default_color
|
64
|
+
end
|
65
|
+
|
66
|
+
# A color should remain a color.
|
67
|
+
get Gosu::Color do |value|
|
68
|
+
value
|
69
|
+
end
|
70
|
+
|
71
|
+
# A string representation of a color will be converted to a color.
|
72
|
+
# If Gosu::Color does not support the format, then it will default to white.
|
73
|
+
get String do |value|
|
74
|
+
create_color value
|
75
|
+
end
|
76
|
+
|
77
|
+
# By default save the default color string.
|
78
|
+
set do |value|
|
79
|
+
default_color_string
|
80
|
+
end
|
81
|
+
|
82
|
+
# When given a string assume that it is a string representation of color.
|
83
|
+
set String do |value|
|
84
|
+
value
|
85
|
+
end
|
86
|
+
|
87
|
+
# When given a color, convert it into the string representation.
|
88
|
+
set Gosu::Color do |value|
|
89
|
+
value.to_s
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# @return the default color of the color property. This can be set during initialization
|
94
|
+
# by usign the option `default`.
|
95
|
+
#
|
96
|
+
def default_color
|
97
|
+
create_color(default_color_string)
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def default_color_string
|
103
|
+
options[:default] || "rgba(255,255,255,1.0)"
|
104
|
+
end
|
105
|
+
|
106
|
+
def create_color(value)
|
107
|
+
Gosu::Color.new value
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|