cyberarm_engine 0.19.0 → 0.19.1

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -8
  3. data/.rubocop.yml +7 -7
  4. data/.travis.yml +5 -5
  5. data/Gemfile +6 -6
  6. data/LICENSE.txt +21 -21
  7. data/README.md +74 -74
  8. data/Rakefile +10 -10
  9. data/bin/console +14 -14
  10. data/bin/setup +8 -8
  11. data/cyberarm_engine.gemspec +39 -39
  12. data/lib/cyberarm_engine/animator.rb +219 -219
  13. data/lib/cyberarm_engine/background.rb +179 -179
  14. data/lib/cyberarm_engine/background_nine_slice.rb +142 -142
  15. data/lib/cyberarm_engine/bounding_box.rb +150 -150
  16. data/lib/cyberarm_engine/builtin/intro_state.rb +130 -130
  17. data/lib/cyberarm_engine/cache/download_manager.rb +121 -121
  18. data/lib/cyberarm_engine/cache.rb +4 -4
  19. data/lib/cyberarm_engine/common.rb +113 -113
  20. data/lib/cyberarm_engine/config_file.rb +46 -46
  21. data/lib/cyberarm_engine/console/command.rb +157 -157
  22. data/lib/cyberarm_engine/console/commands/help_command.rb +43 -43
  23. data/lib/cyberarm_engine/console/subcommand.rb +99 -99
  24. data/lib/cyberarm_engine/console.rb +248 -248
  25. data/lib/cyberarm_engine/game_object.rb +248 -248
  26. data/lib/cyberarm_engine/game_state.rb +97 -97
  27. data/lib/cyberarm_engine/model/material.rb +21 -21
  28. data/lib/cyberarm_engine/model/model_object.rb +131 -131
  29. data/lib/cyberarm_engine/model/parser.rb +74 -74
  30. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -138
  31. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -154
  32. data/lib/cyberarm_engine/model.rb +212 -212
  33. data/lib/cyberarm_engine/model_cache.rb +31 -31
  34. data/lib/cyberarm_engine/opengl/light.rb +50 -50
  35. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -46
  36. data/lib/cyberarm_engine/opengl/perspective_camera.rb +38 -38
  37. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -249
  38. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +164 -164
  39. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +298 -298
  40. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +22 -22
  41. data/lib/cyberarm_engine/opengl/shader.rb +406 -406
  42. data/lib/cyberarm_engine/opengl/texture.rb +69 -69
  43. data/lib/cyberarm_engine/opengl.rb +28 -28
  44. data/lib/cyberarm_engine/ray.rb +56 -56
  45. data/lib/cyberarm_engine/stats.rb +21 -21
  46. data/lib/cyberarm_engine/text.rb +197 -197
  47. data/lib/cyberarm_engine/timer.rb +23 -23
  48. data/lib/cyberarm_engine/transform.rb +296 -296
  49. data/lib/cyberarm_engine/ui/border_canvas.rb +102 -102
  50. data/lib/cyberarm_engine/ui/dsl.rb +139 -139
  51. data/lib/cyberarm_engine/ui/element.rb +488 -488
  52. data/lib/cyberarm_engine/ui/elements/button.rb +97 -97
  53. data/lib/cyberarm_engine/ui/elements/check_box.rb +54 -54
  54. data/lib/cyberarm_engine/ui/elements/container.rb +256 -256
  55. data/lib/cyberarm_engine/ui/elements/edit_box.rb +179 -179
  56. data/lib/cyberarm_engine/ui/elements/edit_line.rb +263 -263
  57. data/lib/cyberarm_engine/ui/elements/flow.rb +15 -15
  58. data/lib/cyberarm_engine/ui/elements/image.rb +72 -72
  59. data/lib/cyberarm_engine/ui/elements/list_box.rb +88 -82
  60. data/lib/cyberarm_engine/ui/elements/progress.rb +51 -51
  61. data/lib/cyberarm_engine/ui/elements/radio.rb +6 -6
  62. data/lib/cyberarm_engine/ui/elements/slider.rb +104 -104
  63. data/lib/cyberarm_engine/ui/elements/stack.rb +11 -11
  64. data/lib/cyberarm_engine/ui/elements/text_block.rb +162 -162
  65. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +65 -65
  66. data/lib/cyberarm_engine/ui/event.rb +54 -54
  67. data/lib/cyberarm_engine/ui/gui_state.rb +256 -256
  68. data/lib/cyberarm_engine/ui/style.rb +49 -49
  69. data/lib/cyberarm_engine/ui/theme.rb +207 -207
  70. data/lib/cyberarm_engine/vector.rb +293 -293
  71. data/lib/cyberarm_engine/version.rb +4 -4
  72. data/lib/cyberarm_engine/window.rb +120 -120
  73. data/lib/cyberarm_engine.rb +71 -71
  74. metadata +3 -3
@@ -1,150 +1,150 @@
1
- module CyberarmEngine
2
- class BoundingBox
3
- attr_accessor :min, :max
4
-
5
- def initialize(*args)
6
- case args.size
7
- when 0
8
- @min = Vector.new(0, 0, 0)
9
- @max = Vector.new(0, 0, 0)
10
- when 2
11
- @min = args.first.clone
12
- @max = args.last.clone
13
- when 4
14
- @min = Vector.new(args[0], args[1], 0)
15
- @max = Vector.new(args[2], args[3], 0)
16
- when 6
17
- @min = Vector.new(args[0], args[1], args[2])
18
- @max = Vector.new(args[3], args[4], args[5])
19
- else
20
- raise "Invalid number of arguments! Got: #{args.size}, expected: 0, 2, 4, or 6."
21
- end
22
- end
23
-
24
- def ==(other)
25
- @min == other.min &&
26
- @max == other.max
27
- end
28
-
29
- # returns a new bounding box that includes both bounding boxes
30
- def union(other)
31
- temp = BoundingBox.new
32
- temp.min.x = [@min.x, other.min.x].min
33
- temp.min.y = [@min.y, other.min.y].min
34
- temp.min.z = [@min.z, other.min.z].min
35
-
36
- temp.max.x = [@max.x, other.max.x].max
37
- temp.max.y = [@max.y, other.max.y].max
38
- temp.max.z = [@max.z, other.max.z].max
39
-
40
- temp
41
- end
42
-
43
- # returns the difference between both bounding boxes
44
- def difference(other)
45
- temp = BoundingBox.new
46
- temp.min = @min - other.min
47
- temp.max = @max - other.max
48
-
49
- temp
50
- end
51
-
52
- # returns whether bounding box intersects other
53
- def intersect?(other)
54
- if other.is_a?(Ray)
55
- other.intersect?(self)
56
- elsif other.is_a?(BoundingBox)
57
- (@min.x <= other.max.x && @max.x >= other.min.x) &&
58
- (@min.y <= other.max.y && @max.y >= other.min.y) &&
59
- (@min.z <= other.max.z && @max.z >= other.min.z)
60
- else
61
- raise "Unknown collider: #{other.class}"
62
- end
63
- end
64
-
65
- # does this bounding box envelop other bounding box? (inclusive of border)
66
- def contains?(other)
67
- other.min.x >= min.x && other.min.y >= min.y && other.min.z >= min.z &&
68
- other.max.x <= max.x && other.max.y <= max.y && other.max.z <= max.z
69
- end
70
-
71
- # returns whether the 3D vector is inside of the bounding box
72
- def inside?(vector)
73
- (vector.x.between?(@min.x, @max.x) || vector.x.between?(@max.x, @min.x)) &&
74
- (vector.y.between?(@min.y, @max.y) || vector.y.between?(@max.y, @min.y)) &&
75
- (vector.z.between?(@min.z, @max.z) || vector.z.between?(@max.z, @min.z))
76
- end
77
-
78
- # returns whether the 2D vector is inside of the bounding box
79
- def point?(vector)
80
- (vector.x.between?(@min.x, @max.x) || vector.x.between?(@max.x, @min.x)) &&
81
- (vector.y.between?(@min.y, @max.y) || vector.y.between?(@max.y, @min.y))
82
- end
83
-
84
- def volume
85
- width * height * depth
86
- end
87
-
88
- def width
89
- @max.x - @min.x
90
- end
91
-
92
- def height
93
- @max.y - @min.y
94
- end
95
-
96
- def depth
97
- @max.z - @min.z
98
- end
99
-
100
- def normalize(entity)
101
- temp = BoundingBox.new
102
- temp.min.x = @min.x.to_f * entity.scale.x
103
- temp.min.y = @min.y.to_f * entity.scale.y
104
- temp.min.z = @min.z.to_f * entity.scale.z
105
-
106
- temp.max.x = @max.x.to_f * entity.scale.x
107
- temp.max.y = @max.y.to_f * entity.scale.y
108
- temp.max.z = @max.z.to_f * entity.scale.z
109
-
110
- temp
111
- end
112
-
113
- def normalize_with_offset(entity)
114
- temp = BoundingBox.new
115
- temp.min.x = @min.x.to_f * entity.scale.x + entity.position.x
116
- temp.min.y = @min.y.to_f * entity.scale.y + entity.position.y
117
- temp.min.z = @min.z.to_f * entity.scale.z + entity.position.z
118
-
119
- temp.max.x = @max.x.to_f * entity.scale.x + entity.position.x
120
- temp.max.y = @max.y.to_f * entity.scale.y + entity.position.y
121
- temp.max.z = @max.z.to_f * entity.scale.z + entity.position.z
122
-
123
- temp
124
- end
125
-
126
- def +(other)
127
- box = BoundingBox.new
128
- box.min = min + other.min
129
- box.min = max + other.max
130
-
131
- box
132
- end
133
-
134
- def -(other)
135
- box = BoundingBox.new
136
- box.min = min - other.min
137
- box.min = max - other.max
138
-
139
- box
140
- end
141
-
142
- def sum
143
- @min.sum + @max.sum
144
- end
145
-
146
- def clone
147
- BoundingBox.new(@min.x, @min.y, @min.z, @max.x, @max.y, @max.z)
148
- end
149
- end
150
- end
1
+ module CyberarmEngine
2
+ class BoundingBox
3
+ attr_accessor :min, :max
4
+
5
+ def initialize(*args)
6
+ case args.size
7
+ when 0
8
+ @min = Vector.new(0, 0, 0)
9
+ @max = Vector.new(0, 0, 0)
10
+ when 2
11
+ @min = args.first.clone
12
+ @max = args.last.clone
13
+ when 4
14
+ @min = Vector.new(args[0], args[1], 0)
15
+ @max = Vector.new(args[2], args[3], 0)
16
+ when 6
17
+ @min = Vector.new(args[0], args[1], args[2])
18
+ @max = Vector.new(args[3], args[4], args[5])
19
+ else
20
+ raise "Invalid number of arguments! Got: #{args.size}, expected: 0, 2, 4, or 6."
21
+ end
22
+ end
23
+
24
+ def ==(other)
25
+ @min == other.min &&
26
+ @max == other.max
27
+ end
28
+
29
+ # returns a new bounding box that includes both bounding boxes
30
+ def union(other)
31
+ temp = BoundingBox.new
32
+ temp.min.x = [@min.x, other.min.x].min
33
+ temp.min.y = [@min.y, other.min.y].min
34
+ temp.min.z = [@min.z, other.min.z].min
35
+
36
+ temp.max.x = [@max.x, other.max.x].max
37
+ temp.max.y = [@max.y, other.max.y].max
38
+ temp.max.z = [@max.z, other.max.z].max
39
+
40
+ temp
41
+ end
42
+
43
+ # returns the difference between both bounding boxes
44
+ def difference(other)
45
+ temp = BoundingBox.new
46
+ temp.min = @min - other.min
47
+ temp.max = @max - other.max
48
+
49
+ temp
50
+ end
51
+
52
+ # returns whether bounding box intersects other
53
+ def intersect?(other)
54
+ if other.is_a?(Ray)
55
+ other.intersect?(self)
56
+ elsif other.is_a?(BoundingBox)
57
+ (@min.x <= other.max.x && @max.x >= other.min.x) &&
58
+ (@min.y <= other.max.y && @max.y >= other.min.y) &&
59
+ (@min.z <= other.max.z && @max.z >= other.min.z)
60
+ else
61
+ raise "Unknown collider: #{other.class}"
62
+ end
63
+ end
64
+
65
+ # does this bounding box envelop other bounding box? (inclusive of border)
66
+ def contains?(other)
67
+ other.min.x >= min.x && other.min.y >= min.y && other.min.z >= min.z &&
68
+ other.max.x <= max.x && other.max.y <= max.y && other.max.z <= max.z
69
+ end
70
+
71
+ # returns whether the 3D vector is inside of the bounding box
72
+ def inside?(vector)
73
+ (vector.x.between?(@min.x, @max.x) || vector.x.between?(@max.x, @min.x)) &&
74
+ (vector.y.between?(@min.y, @max.y) || vector.y.between?(@max.y, @min.y)) &&
75
+ (vector.z.between?(@min.z, @max.z) || vector.z.between?(@max.z, @min.z))
76
+ end
77
+
78
+ # returns whether the 2D vector is inside of the bounding box
79
+ def point?(vector)
80
+ (vector.x.between?(@min.x, @max.x) || vector.x.between?(@max.x, @min.x)) &&
81
+ (vector.y.between?(@min.y, @max.y) || vector.y.between?(@max.y, @min.y))
82
+ end
83
+
84
+ def volume
85
+ width * height * depth
86
+ end
87
+
88
+ def width
89
+ @max.x - @min.x
90
+ end
91
+
92
+ def height
93
+ @max.y - @min.y
94
+ end
95
+
96
+ def depth
97
+ @max.z - @min.z
98
+ end
99
+
100
+ def normalize(entity)
101
+ temp = BoundingBox.new
102
+ temp.min.x = @min.x.to_f * entity.scale.x
103
+ temp.min.y = @min.y.to_f * entity.scale.y
104
+ temp.min.z = @min.z.to_f * entity.scale.z
105
+
106
+ temp.max.x = @max.x.to_f * entity.scale.x
107
+ temp.max.y = @max.y.to_f * entity.scale.y
108
+ temp.max.z = @max.z.to_f * entity.scale.z
109
+
110
+ temp
111
+ end
112
+
113
+ def normalize_with_offset(entity)
114
+ temp = BoundingBox.new
115
+ temp.min.x = @min.x.to_f * entity.scale.x + entity.position.x
116
+ temp.min.y = @min.y.to_f * entity.scale.y + entity.position.y
117
+ temp.min.z = @min.z.to_f * entity.scale.z + entity.position.z
118
+
119
+ temp.max.x = @max.x.to_f * entity.scale.x + entity.position.x
120
+ temp.max.y = @max.y.to_f * entity.scale.y + entity.position.y
121
+ temp.max.z = @max.z.to_f * entity.scale.z + entity.position.z
122
+
123
+ temp
124
+ end
125
+
126
+ def +(other)
127
+ box = BoundingBox.new
128
+ box.min = min + other.min
129
+ box.min = max + other.max
130
+
131
+ box
132
+ end
133
+
134
+ def -(other)
135
+ box = BoundingBox.new
136
+ box.min = min - other.min
137
+ box.min = max - other.max
138
+
139
+ box
140
+ end
141
+
142
+ def sum
143
+ @min.sum + @max.sum
144
+ end
145
+
146
+ def clone
147
+ BoundingBox.new(@min.x, @min.y, @min.z, @max.x, @max.y, @max.z)
148
+ end
149
+ end
150
+ end
@@ -1,131 +1,131 @@
1
- module CyberarmEngine
2
- class IntroState < CyberarmEngine::GameState
3
- def setup
4
- @display_width = 800
5
- @display_height = 600
6
-
7
- @title_size = 56
8
- @caption_size = 24
9
-
10
- @title = CyberarmEngine::Text.new("", size: @title_size, shadow_color: 0xaa_222222)
11
- @caption = CyberarmEngine::Text.new("", size: @caption_size, shadow_color: 0xaa_222222)
12
-
13
- @spacer_width = 256
14
- @spacer_height = 6
15
- @padding = 6
16
-
17
- @cyberarm_engine_logo = get_image "#{CYBERARM_ENGINE_ROOT_PATH}/assets/textures/logo.png"
18
-
19
- @gosu_logo = generate_proxy("Gosu", "Game Library", 0xff_111111)
20
- @ruby_logo = generate_proxy("Ruby", "Programming Language", 0xff_880000)
21
- @opengl_logo = generate_proxy("OpenGL", "Graphics API", 0xff_5586a4) if defined?(OpenGL)
22
-
23
- base_time = Gosu.milliseconds
24
-
25
- @born_time = Gosu.milliseconds
26
- @continue_after = 5_000
27
-
28
- @animators = [
29
- Animator.new(start_time: base_time += 1000, duration: 100, from: 0.0, to: 1.0, tween: :ease_in_out),
30
- Animator.new(start_time: base_time += -500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
31
- Animator.new(start_time: base_time += 500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
32
- Animator.new(start_time: base_time += 500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
33
- Animator.new(start_time: base_time + 500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
34
- Animator.new(start_time: Gosu.milliseconds + @continue_after - 1_000, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
35
-
36
- Animator.new(start_time: Gosu.milliseconds + 250, duration: 500, from: 0.0, to: 1.0, tween: :swing_to) # CyberarmEngine LOGO
37
- ]
38
- end
39
-
40
- def draw
41
- Gosu.draw_rect(0, 0, window.width, window.height, 0xff_222222)
42
-
43
- scale = (@display_width - @padding * 2).to_f / @cyberarm_engine_logo.width * @animators.last.transition
44
-
45
- @cyberarm_engine_logo.draw_rot(
46
- window.width / 2,
47
- (window.height) / 2 - @cyberarm_engine_logo.height / 2 - @padding * 2,
48
- 2,
49
- 0,
50
- 0.5,
51
- 0.5,
52
- scale,
53
- scale
54
- )
55
-
56
- Gosu.draw_rect(
57
- window.width / 2 - (@display_width / 2 + @padding),
58
- window.height / 2 - @spacer_height / 2,
59
- @display_width + @padding,
60
- @spacer_height * @animators[0].transition,
61
- Gosu::Color::WHITE
62
- )
63
-
64
- @title.x = window.width / 2 - @title.text_width / 2
65
- @title.y = (window.height / 2 + (@spacer_height / 2) + @padding) * @animators[1].transition
66
- @title.text = "Powered By"
67
-
68
- Gosu.clip_to(0, window.height / 2 + (@spacer_height / 2), window.width, @title.height) do
69
- @title.draw
70
- end
71
-
72
- y = @title.y + @title.height * 2
73
-
74
- Gosu.clip_to(0, y, window.width, @gosu_logo.height) do
75
- Gosu.translate(@opengl_logo.nil? ? @ruby_logo.width / 2 : 0, 0) do
76
- @gosu_logo.draw(
77
- window.width.to_f / 2 - @ruby_logo.width / 2 - (@ruby_logo.width - @padding),
78
- y * @animators[2].transition,
79
- 2
80
- )
81
- @ruby_logo.draw(
82
- window.width.to_f / 2 - @ruby_logo.width / 2,
83
- y * @animators[3].transition,
84
- 2
85
- )
86
- @opengl_logo&.draw(
87
- window.width.to_f / 2 - @ruby_logo.width / 2 + (@ruby_logo.width - @padding),
88
- y * @animators[4].transition,
89
- 2
90
- )
91
- end
92
- end
93
-
94
- Gosu.draw_rect(0, 0, window.width, window.height, Gosu::Color.rgba(0, 0, 0, 255 * @animators[5].transition), 10_000)
95
- end
96
-
97
- def update
98
- @animators.each(&:update)
99
-
100
- return unless Gosu.milliseconds - @born_time >= @continue_after
101
-
102
- pop_state
103
- push_state(@options[:forward], @options[:forward_options] || {}) if @options[:forward]
104
- end
105
-
106
- def button_down(_id)
107
- @continue_after = 0
108
- end
109
-
110
- def generate_proxy(title, caption, color_hint)
111
- @title.text = title
112
- @caption.text = caption
113
-
114
- width = @spacer_width + 2 * @padding
115
- height = @title_size + @caption_size + @spacer_height + 2 * @padding + @spacer_height
116
-
117
- Gosu.record(width.ceil, height.ceil) do
118
- @title.x = (width - @padding * 2) / 2 - @title.text_width / 2
119
- @title.y = @padding
120
- @title.draw
121
-
122
- Gosu.draw_rect(0, @padding + @title_size + @padding, @spacer_width, @spacer_height, Gosu::Color::WHITE)
123
- Gosu.draw_rect(1, @padding + @title_size + @padding + 1, @spacer_width - 2, @spacer_height - 2, color_hint)
124
-
125
- @caption.x = (width - @padding * 2) / 2 - @caption.text_width / 2
126
- @caption.y = @padding + @title_size + @padding + @spacer_height + @padding
127
- @caption.draw
128
- end
129
- end
130
- end
1
+ module CyberarmEngine
2
+ class IntroState < CyberarmEngine::GameState
3
+ def setup
4
+ @display_width = 800
5
+ @display_height = 600
6
+
7
+ @title_size = 56
8
+ @caption_size = 24
9
+
10
+ @title = CyberarmEngine::Text.new("", size: @title_size, shadow_color: 0xaa_222222)
11
+ @caption = CyberarmEngine::Text.new("", size: @caption_size, shadow_color: 0xaa_222222)
12
+
13
+ @spacer_width = 256
14
+ @spacer_height = 6
15
+ @padding = 6
16
+
17
+ @cyberarm_engine_logo = get_image "#{CYBERARM_ENGINE_ROOT_PATH}/assets/textures/logo.png"
18
+
19
+ @gosu_logo = generate_proxy("Gosu", "Game Library", 0xff_111111)
20
+ @ruby_logo = generate_proxy("Ruby", "Programming Language", 0xff_880000)
21
+ @opengl_logo = generate_proxy("OpenGL", "Graphics API", 0xff_5586a4) if defined?(OpenGL)
22
+
23
+ base_time = Gosu.milliseconds
24
+
25
+ @born_time = Gosu.milliseconds
26
+ @continue_after = 5_000
27
+
28
+ @animators = [
29
+ Animator.new(start_time: base_time += 1000, duration: 100, from: 0.0, to: 1.0, tween: :ease_in_out),
30
+ Animator.new(start_time: base_time += -500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
31
+ Animator.new(start_time: base_time += 500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
32
+ Animator.new(start_time: base_time += 500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
33
+ Animator.new(start_time: base_time + 500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
34
+ Animator.new(start_time: Gosu.milliseconds + @continue_after - 1_000, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
35
+
36
+ Animator.new(start_time: Gosu.milliseconds + 250, duration: 500, from: 0.0, to: 1.0, tween: :swing_to) # CyberarmEngine LOGO
37
+ ]
38
+ end
39
+
40
+ def draw
41
+ Gosu.draw_rect(0, 0, window.width, window.height, 0xff_222222)
42
+
43
+ scale = (@display_width - @padding * 2).to_f / @cyberarm_engine_logo.width * @animators.last.transition
44
+
45
+ @cyberarm_engine_logo.draw_rot(
46
+ window.width / 2,
47
+ (window.height) / 2 - @cyberarm_engine_logo.height / 2 - @padding * 2,
48
+ 2,
49
+ 0,
50
+ 0.5,
51
+ 0.5,
52
+ scale,
53
+ scale
54
+ )
55
+
56
+ Gosu.draw_rect(
57
+ window.width / 2 - (@display_width / 2 + @padding),
58
+ window.height / 2 - @spacer_height / 2,
59
+ @display_width + @padding,
60
+ @spacer_height * @animators[0].transition,
61
+ Gosu::Color::WHITE
62
+ )
63
+
64
+ @title.x = window.width / 2 - @title.text_width / 2
65
+ @title.y = (window.height / 2 + (@spacer_height / 2) + @padding) * @animators[1].transition
66
+ @title.text = "Powered By"
67
+
68
+ Gosu.clip_to(0, window.height / 2 + (@spacer_height / 2), window.width, @title.height) do
69
+ @title.draw
70
+ end
71
+
72
+ y = @title.y + @title.height * 2
73
+
74
+ Gosu.clip_to(0, y, window.width, @gosu_logo.height) do
75
+ Gosu.translate(@opengl_logo.nil? ? @ruby_logo.width / 2 : 0, 0) do
76
+ @gosu_logo.draw(
77
+ window.width.to_f / 2 - @ruby_logo.width / 2 - (@ruby_logo.width - @padding),
78
+ y * @animators[2].transition,
79
+ 2
80
+ )
81
+ @ruby_logo.draw(
82
+ window.width.to_f / 2 - @ruby_logo.width / 2,
83
+ y * @animators[3].transition,
84
+ 2
85
+ )
86
+ @opengl_logo&.draw(
87
+ window.width.to_f / 2 - @ruby_logo.width / 2 + (@ruby_logo.width - @padding),
88
+ y * @animators[4].transition,
89
+ 2
90
+ )
91
+ end
92
+ end
93
+
94
+ Gosu.draw_rect(0, 0, window.width, window.height, Gosu::Color.rgba(0, 0, 0, 255 * @animators[5].transition), 10_000)
95
+ end
96
+
97
+ def update
98
+ @animators.each(&:update)
99
+
100
+ return unless Gosu.milliseconds - @born_time >= @continue_after
101
+
102
+ pop_state
103
+ push_state(@options[:forward], @options[:forward_options] || {}) if @options[:forward]
104
+ end
105
+
106
+ def button_down(_id)
107
+ @continue_after = 0
108
+ end
109
+
110
+ def generate_proxy(title, caption, color_hint)
111
+ @title.text = title
112
+ @caption.text = caption
113
+
114
+ width = @spacer_width + 2 * @padding
115
+ height = @title_size + @caption_size + @spacer_height + 2 * @padding + @spacer_height
116
+
117
+ Gosu.record(width.ceil, height.ceil) do
118
+ @title.x = (width - @padding * 2) / 2 - @title.text_width / 2
119
+ @title.y = @padding
120
+ @title.draw
121
+
122
+ Gosu.draw_rect(0, @padding + @title_size + @padding, @spacer_width, @spacer_height, Gosu::Color::WHITE)
123
+ Gosu.draw_rect(1, @padding + @title_size + @padding + 1, @spacer_width - 2, @spacer_height - 2, color_hint)
124
+
125
+ @caption.x = (width - @padding * 2) / 2 - @caption.text_width / 2
126
+ @caption.y = @padding + @title_size + @padding + @spacer_height + @padding
127
+ @caption.draw
128
+ end
129
+ end
130
+ end
131
131
  end