cyberarm_engine 0.24.5 → 0.25.0

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 (93) 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/Gemfile.lock +25 -24
  7. data/LICENSE.txt +21 -21
  8. data/README.md +74 -74
  9. data/Rakefile +10 -10
  10. data/assets/shaders/fragment/g_buffer.glsl +30 -30
  11. data/assets/shaders/fragment/lighting.glsl +115 -115
  12. data/assets/shaders/include/light_struct.glsl +11 -11
  13. data/assets/shaders/include/material_struct.glsl +16 -16
  14. data/assets/shaders/vertex/g_buffer.glsl +28 -28
  15. data/assets/shaders/vertex/lighting.glsl +24 -24
  16. data/bin/console +14 -14
  17. data/bin/setup +8 -8
  18. data/cyberarm_engine.gemspec +36 -36
  19. data/lib/cyberarm_engine/animator.rb +219 -219
  20. data/lib/cyberarm_engine/background.rb +158 -180
  21. data/lib/cyberarm_engine/background_image.rb +93 -93
  22. data/lib/cyberarm_engine/background_nine_slice.rb +142 -142
  23. data/lib/cyberarm_engine/bounding_box.rb +150 -150
  24. data/lib/cyberarm_engine/builtin/intro_state.rb +130 -130
  25. data/lib/cyberarm_engine/cache/download_manager.rb +123 -123
  26. data/lib/cyberarm_engine/cache.rb +4 -4
  27. data/lib/cyberarm_engine/common.rb +131 -128
  28. data/lib/cyberarm_engine/config_file.rb +46 -46
  29. data/lib/cyberarm_engine/console/command.rb +157 -157
  30. data/lib/cyberarm_engine/console/commands/help_command.rb +43 -43
  31. data/lib/cyberarm_engine/console/subcommand.rb +99 -99
  32. data/lib/cyberarm_engine/console.rb +248 -248
  33. data/lib/cyberarm_engine/game_object.rb +244 -244
  34. data/lib/cyberarm_engine/game_state.rb +124 -124
  35. data/lib/cyberarm_engine/gosu_ext/draw_arc.rb +111 -98
  36. data/lib/cyberarm_engine/gosu_ext/draw_circle.rb +30 -30
  37. data/lib/cyberarm_engine/gosu_ext/draw_path.rb +17 -17
  38. data/lib/cyberarm_engine/model/material.rb +21 -21
  39. data/lib/cyberarm_engine/model/mesh.rb +131 -131
  40. data/lib/cyberarm_engine/model/parser.rb +74 -74
  41. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -138
  42. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -154
  43. data/lib/cyberarm_engine/model.rb +216 -216
  44. data/lib/cyberarm_engine/model_cache.rb +31 -31
  45. data/lib/cyberarm_engine/notification.rb +82 -82
  46. data/lib/cyberarm_engine/notification_manager.rb +241 -241
  47. data/lib/cyberarm_engine/opengl/light.rb +52 -52
  48. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -46
  49. data/lib/cyberarm_engine/opengl/perspective_camera.rb +41 -41
  50. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -249
  51. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +167 -167
  52. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +307 -307
  53. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +33 -33
  54. data/lib/cyberarm_engine/opengl/shader.rb +408 -408
  55. data/lib/cyberarm_engine/opengl/texture.rb +69 -69
  56. data/lib/cyberarm_engine/opengl.rb +53 -53
  57. data/lib/cyberarm_engine/ray.rb +56 -56
  58. data/lib/cyberarm_engine/stats.rb +200 -200
  59. data/lib/cyberarm_engine/text.rb +260 -260
  60. data/lib/cyberarm_engine/timer.rb +23 -23
  61. data/lib/cyberarm_engine/transform.rb +296 -296
  62. data/lib/cyberarm_engine/trees/aabb_node.rb +126 -126
  63. data/lib/cyberarm_engine/trees/aabb_tree.rb +55 -55
  64. data/lib/cyberarm_engine/trees/aabb_tree_debug.rb +29 -29
  65. data/lib/cyberarm_engine/ui/border_canvas.rb +102 -102
  66. data/lib/cyberarm_engine/ui/dsl.rb +142 -142
  67. data/lib/cyberarm_engine/ui/element.rb +662 -662
  68. data/lib/cyberarm_engine/ui/elements/button.rb +100 -100
  69. data/lib/cyberarm_engine/ui/elements/check_box.rb +54 -54
  70. data/lib/cyberarm_engine/ui/elements/container.rb +407 -404
  71. data/lib/cyberarm_engine/ui/elements/edit_box.rb +179 -179
  72. data/lib/cyberarm_engine/ui/elements/edit_line.rb +297 -297
  73. data/lib/cyberarm_engine/ui/elements/flow.rb +15 -15
  74. data/lib/cyberarm_engine/ui/elements/image.rb +72 -72
  75. data/lib/cyberarm_engine/ui/elements/list_box.rb +79 -79
  76. data/lib/cyberarm_engine/ui/elements/menu.rb +27 -27
  77. data/lib/cyberarm_engine/ui/elements/menu_item.rb +6 -6
  78. data/lib/cyberarm_engine/ui/elements/progress.rb +93 -93
  79. data/lib/cyberarm_engine/ui/elements/radio.rb +6 -6
  80. data/lib/cyberarm_engine/ui/elements/slider.rb +107 -107
  81. data/lib/cyberarm_engine/ui/elements/stack.rb +11 -11
  82. data/lib/cyberarm_engine/ui/elements/text_block.rb +222 -216
  83. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +67 -67
  84. data/lib/cyberarm_engine/ui/event.rb +54 -54
  85. data/lib/cyberarm_engine/ui/gui_state.rb +326 -321
  86. data/lib/cyberarm_engine/ui/style.rb +61 -50
  87. data/lib/cyberarm_engine/ui/theme.rb +225 -225
  88. data/lib/cyberarm_engine/vector.rb +312 -312
  89. data/lib/cyberarm_engine/version.rb +4 -4
  90. data/lib/cyberarm_engine/window.rb +195 -195
  91. data/lib/cyberarm_engine.rb +76 -70
  92. data/mrbgem.rake +29 -29
  93. metadata +3 -3
@@ -1,216 +1,222 @@
1
- module CyberarmEngine
2
- class Element
3
- class TextBlock < Element
4
- def initialize(text, options = {}, block = nil)
5
- super(options, block)
6
-
7
- @text = Text.new(
8
- text, font: @options[:font], z: @z, color: @options[:color],
9
- size: @options[:text_size], shadow: @options[:text_shadow],
10
- static: @options[:text_static],
11
- shadow_size: @options[:text_shadow_size],
12
- shadow_color: @options[:text_shadow_color],
13
- border: @options[:text_border],
14
- border_size: @options[:text_border_size],
15
- border_color: @options[:text_border_color]
16
- )
17
-
18
- @raw_text = text
19
- end
20
-
21
- def update
22
- super
23
-
24
- if @text.textobject.name != safe_style_fetch(:font)
25
- set_font
26
- root.gui_state.request_recalculate
27
- end
28
- end
29
-
30
- def render
31
- # Gosu.clip_to is too expensive to always use so check if we actually need it.
32
- if @text.width > width || @text.height > height
33
- Gosu.clip_to(@x, @y, width, height) do
34
- @text.draw
35
- end
36
- else
37
- @text.draw
38
- end
39
- end
40
-
41
- def layout
42
- unless @enabled
43
- @text.color = @style.disabled[:color]
44
- else
45
- @text.color = @style.color
46
- end
47
-
48
- @width = 0
49
- @height = 0
50
-
51
- _width = dimensional_size(@style.width, :width)
52
- _height = dimensional_size(@style.height, :height)
53
-
54
- handle_text_wrapping(_width)
55
-
56
- @width = _width || @text.width.floor
57
- @height = _height || @text.height.floor
58
-
59
- @text.y = @style.border_thickness_top + @style.padding_top + @y
60
- @text.z = @z + 3
61
-
62
- if (text_alignment = @options[:text_align] || @options[:text_h_align])
63
- case text_alignment
64
- when :left
65
- @text.x = @style.border_thickness_left + @style.padding_left + @x
66
- when :center
67
- @text.x = if @text.width <= width
68
- @x + width / 2 - @text.width / 2
69
- else # Act as left aligned
70
- @style.border_thickness_left + @style.padding_left + @x
71
- end
72
- when :right
73
- @text.x = @x + outer_width - (@text.width + @style.border_thickness_right + @style.padding_right)
74
- end
75
- end
76
-
77
- if (vertical_alignment = @options[:text_v_align])
78
- case vertical_alignment
79
- when :center
80
- @text.y = if @text.height <= height
81
- @y + height / 2 - @text.height / 2
82
- else
83
- @style.border_thickness_top + @style.padding_top + @y
84
- end
85
- when :bottom
86
- @text.y = @y + outer_height - (@text.height + @style.border_thickness_bottom + @style.padding_bottom)
87
- end
88
- end
89
-
90
- update_background
91
- end
92
-
93
- def handle_text_wrapping(max_width)
94
- max_width ||= @parent&.content_width
95
- max_width ||= @x - (window.width + noncontent_width)
96
- wrap_behavior = style.text_wrap
97
- copy = @raw_text.to_s.dup
98
-
99
- # Only perform text wrapping: if it is enabled, is possible to wrap, and text is too long to fit on one line
100
- if wrap_behavior != :none && line_width(copy[0]) <= max_width && line_width(copy) > max_width
101
- breaks = [] # list of indexes to insert a line break
102
- line_start = 0
103
- line_end = copy.length
104
-
105
- stalled = false
106
- stalled_interations = 0
107
- max_stalled_iterations = 10
108
- checked_copy_length = line_width(copy[line_start..line_end])
109
-
110
- # find length of lines
111
- while line_width(copy[line_start..line_end]) > max_width && stalled_interations < max_stalled_iterations
112
- search_start = line_start
113
- search_end = line_end
114
-
115
- # Perform a binary search to find length of line
116
- while search_start < search_end
117
- midpoint = ((search_start.to_f + search_end) / 2.0).floor
118
-
119
- if line_width(copy[line_start..midpoint]) > max_width
120
- search_end = midpoint
121
- else
122
- search_start = midpoint + 1
123
- end
124
- end
125
-
126
- if wrap_behavior == :word_wrap
127
- word_search_end = search_end
128
- failed = false
129
-
130
- until(copy[word_search_end].to_s.match(/[[:punct:]]| /))
131
- word_search_end -= 1
132
-
133
- if word_search_end <= 1 || word_search_end < line_start
134
- failed = true
135
- break
136
- end
137
- end
138
-
139
- line_start = failed ? search_end : word_search_end + 1 # walk in front of punctuation
140
- else
141
- line_start = search_end
142
- end
143
-
144
- breaks << line_start
145
-
146
- # Prevent locking up due to outer while loop text width < max_width check not being satisfied.
147
- stalled = checked_copy_length == line_width(copy[line_start..line_end])
148
- checked_copy_length = line_width(copy[line_start..line_end])
149
-
150
- stalled_interations += 1 if stalled
151
- stalled_interations = 0 unless stalled
152
- end
153
-
154
- breaks.each_with_index do |pos, index|
155
- copy.insert(pos + index, "\n") if pos + index >= 0 && pos + index < copy.length
156
- end
157
- end
158
-
159
- @text.text = copy
160
- end
161
-
162
- def line_width(text)
163
- (@text.textobject.markup_width(text.to_s) + noncontent_width)
164
- end
165
-
166
- def value
167
- @raw_text
168
- end
169
-
170
- def value=(value)
171
- old_value = @raw_text
172
- @raw_text = value.to_s.chomp
173
-
174
- old_width = width
175
- old_height = height
176
-
177
- if old_width != width || old_height != height
178
- root.gui_state.request_recalculate
179
- else
180
- recalculate
181
- end
182
-
183
- root.gui_state.request_repaint if old_value != @raw_text
184
-
185
- publish(:changed, self.value)
186
- end
187
- end
188
-
189
- class Banner < TextBlock
190
- end
191
-
192
- class Title < TextBlock
193
- end
194
-
195
- class Subtitle < TextBlock
196
- end
197
-
198
- class Tagline < TextBlock
199
- end
200
-
201
- class Caption < TextBlock
202
- end
203
-
204
- class Para < TextBlock
205
- end
206
-
207
- class Inscription < TextBlock
208
- end
209
-
210
- class ToolTip < TextBlock
211
- end
212
-
213
- class Link < TextBlock
214
- end
215
- end
216
- end
1
+ module CyberarmEngine
2
+ class Element
3
+ class TextBlock < Element
4
+ def initialize(text, options = {}, block = nil)
5
+ super(options, block)
6
+
7
+ @text = Text.new(
8
+ text, font: @options[:font], z: @z, color: @options[:color],
9
+ size: @options[:text_size], shadow: @options[:text_shadow],
10
+ static: @options[:text_static],
11
+ shadow_size: @options[:text_shadow_size],
12
+ shadow_color: @options[:text_shadow_color],
13
+ border: @options[:text_border],
14
+ border_size: @options[:text_border_size],
15
+ border_color: @options[:text_border_color]
16
+ )
17
+
18
+ @raw_text = text
19
+ @text_width = @text.width
20
+ @text_height = @text.height
21
+ end
22
+
23
+ def update
24
+ super
25
+
26
+ if @text.textobject.name != safe_style_fetch(:font)
27
+ set_font
28
+ root.gui_state.request_recalculate
29
+ end
30
+ end
31
+
32
+ def render
33
+ # Gosu.clip_to is too expensive to always use so check if we actually need it.
34
+ if @text_width > width || @text_height > height
35
+ Gosu.clip_to(@x, @y, width, height) do
36
+ @text.draw
37
+ end
38
+ else
39
+ @text.draw
40
+ end
41
+ end
42
+
43
+ def layout
44
+ unless @enabled
45
+ @text.color = @style.disabled[:color]
46
+ else
47
+ @text.color = @style.color
48
+ end
49
+
50
+ @width = 0
51
+ @height = 0
52
+
53
+ _width = dimensional_size(@style.width, :width)
54
+ _height = dimensional_size(@style.height, :height)
55
+
56
+ handle_text_wrapping(_width)
57
+
58
+ # Update cached text width and height
59
+ @text_width = @text.width
60
+ @text_height = @text.height
61
+
62
+ @width = _width || @text_width.floor
63
+ @height = _height || @text_height.floor
64
+
65
+ @text.y = @style.border_thickness_top + @style.padding_top + @y
66
+ @text.z = @z + 3
67
+
68
+ if (text_alignment = @options[:text_align] || @options[:text_h_align])
69
+ case text_alignment
70
+ when :left
71
+ @text.x = @style.border_thickness_left + @style.padding_left + @x
72
+ when :center
73
+ @text.x = if @text_width <= width
74
+ @x + width / 2 - @text_width / 2
75
+ else # Act as left aligned
76
+ @style.border_thickness_left + @style.padding_left + @x
77
+ end
78
+ when :right
79
+ @text.x = @x + outer_width - (@text_width + @style.border_thickness_right + @style.padding_right)
80
+ end
81
+ end
82
+
83
+ if (vertical_alignment = @options[:text_v_align])
84
+ case vertical_alignment
85
+ when :center
86
+ @text.y = if @text_height <= height
87
+ @y + height / 2 - @text_height / 2
88
+ else
89
+ @style.border_thickness_top + @style.padding_top + @y
90
+ end
91
+ when :bottom
92
+ @text.y = @y + outer_height - (@text_height + @style.border_thickness_bottom + @style.padding_bottom)
93
+ end
94
+ end
95
+
96
+ update_background
97
+ end
98
+
99
+ def handle_text_wrapping(max_width)
100
+ max_width ||= @parent&.content_width
101
+ max_width ||= @x - (window.width + noncontent_width)
102
+ wrap_behavior = style.text_wrap
103
+ copy = @raw_text.to_s.dup
104
+
105
+ # Only perform text wrapping: if it is enabled, is possible to wrap, and text is too long to fit on one line
106
+ if wrap_behavior != :none && line_width(copy[0]) <= max_width && line_width(copy) > max_width
107
+ breaks = [] # list of indexes to insert a line break
108
+ line_start = 0
109
+ line_end = copy.length
110
+
111
+ stalled = false
112
+ stalled_interations = 0
113
+ max_stalled_iterations = 10
114
+ checked_copy_length = line_width(copy[line_start..line_end])
115
+
116
+ # find length of lines
117
+ while line_width(copy[line_start..line_end]) > max_width && stalled_interations < max_stalled_iterations
118
+ search_start = line_start
119
+ search_end = line_end
120
+
121
+ # Perform a binary search to find length of line
122
+ while search_start < search_end
123
+ midpoint = ((search_start.to_f + search_end) / 2.0).floor
124
+
125
+ if line_width(copy[line_start..midpoint]) > max_width
126
+ search_end = midpoint
127
+ else
128
+ search_start = midpoint + 1
129
+ end
130
+ end
131
+
132
+ if wrap_behavior == :word_wrap
133
+ word_search_end = search_end
134
+ failed = false
135
+
136
+ until(copy[word_search_end].to_s.match(/[[:punct:]]| /))
137
+ word_search_end -= 1
138
+
139
+ if word_search_end <= 1 || word_search_end < line_start
140
+ failed = true
141
+ break
142
+ end
143
+ end
144
+
145
+ line_start = failed ? search_end : word_search_end + 1 # walk in front of punctuation
146
+ else
147
+ line_start = search_end
148
+ end
149
+
150
+ breaks << line_start
151
+
152
+ # Prevent locking up due to outer while loop text width < max_width check not being satisfied.
153
+ stalled = checked_copy_length == line_width(copy[line_start..line_end])
154
+ checked_copy_length = line_width(copy[line_start..line_end])
155
+
156
+ stalled_interations += 1 if stalled
157
+ stalled_interations = 0 unless stalled
158
+ end
159
+
160
+ breaks.each_with_index do |pos, index|
161
+ copy.insert(pos + index, "\n") if pos + index >= 0 && pos + index < copy.length
162
+ end
163
+ end
164
+
165
+ @text.text = copy
166
+ end
167
+
168
+ def line_width(text)
169
+ (@text.textobject.markup_width(text.to_s) + noncontent_width)
170
+ end
171
+
172
+ def value
173
+ @raw_text
174
+ end
175
+
176
+ def value=(value)
177
+ old_value = @raw_text
178
+ @raw_text = value.to_s.chomp
179
+
180
+ old_width = width
181
+ old_height = height
182
+
183
+ if old_width != width || old_height != height
184
+ root.gui_state.request_recalculate
185
+ else
186
+ recalculate
187
+ end
188
+
189
+ root.gui_state.request_repaint if old_value != @raw_text
190
+
191
+ publish(:changed, self.value)
192
+ end
193
+ end
194
+
195
+ class Banner < TextBlock
196
+ end
197
+
198
+ class Title < TextBlock
199
+ end
200
+
201
+ class Subtitle < TextBlock
202
+ end
203
+
204
+ class Tagline < TextBlock
205
+ end
206
+
207
+ class Caption < TextBlock
208
+ end
209
+
210
+ class Para < TextBlock
211
+ end
212
+
213
+ class Inscription < TextBlock
214
+ end
215
+
216
+ class ToolTip < TextBlock
217
+ end
218
+
219
+ class Link < TextBlock
220
+ end
221
+ end
222
+ end
@@ -1,67 +1,67 @@
1
- module CyberarmEngine
2
- class Element
3
- class ToggleButton < Button
4
- attr_reader :toggled, :value
5
-
6
- def initialize(options, block = nil)
7
- if options.dig(:theme, :ToggleButton, :checkmark_image)
8
- options[:theme][:ToggleButton][:image_width] ||= options[:theme][:TextBlock][:text_size]
9
- super(get_image(options.dig(:theme, :ToggleButton, :checkmark_image)), options, block)
10
- else
11
- super(options[:checkmark], options, block)
12
- end
13
-
14
- @value = options[:checked] || false
15
-
16
- if @value
17
- @raw_text = @options[:checkmark]
18
- else
19
- @raw_text = ""
20
- end
21
- end
22
-
23
- def clicked_left_mouse_button(_sender, _x, _y)
24
- self.value = !@value
25
-
26
- @block.call(self) if @block
27
-
28
- :handled
29
- end
30
-
31
- def render
32
- if @image
33
- draw_image if @value
34
- else
35
- draw_text
36
- end
37
- end
38
-
39
- def recalculate
40
- super
41
- return if @image
42
-
43
- _width = dimensional_size(@style.width, :width)
44
- _height = dimensional_size(@style.height, :height)
45
-
46
- @width = _width || @text.textobject.text_width(@options[:checkmark])
47
- @height = _height || @text.height
48
-
49
- update_background
50
- end
51
-
52
- def value=(boolean)
53
- @value = boolean
54
-
55
- if boolean
56
- @raw_text = @options[:checkmark]
57
- else
58
- @raw_text = ""
59
- end
60
-
61
- recalculate
62
-
63
- publish(:changed, @value)
64
- end
65
- end
66
- end
67
- end
1
+ module CyberarmEngine
2
+ class Element
3
+ class ToggleButton < Button
4
+ attr_reader :toggled, :value
5
+
6
+ def initialize(options, block = nil)
7
+ if options.dig(:theme, :ToggleButton, :checkmark_image)
8
+ options[:theme][:ToggleButton][:image_width] ||= options[:theme][:TextBlock][:text_size]
9
+ super(get_image(options.dig(:theme, :ToggleButton, :checkmark_image)), options, block)
10
+ else
11
+ super(options[:checkmark], options, block)
12
+ end
13
+
14
+ @value = options[:checked] || false
15
+
16
+ if @value
17
+ @raw_text = @options[:checkmark]
18
+ else
19
+ @raw_text = ""
20
+ end
21
+ end
22
+
23
+ def clicked_left_mouse_button(_sender, _x, _y)
24
+ self.value = !@value
25
+
26
+ @block.call(self) if @block
27
+
28
+ :handled
29
+ end
30
+
31
+ def render
32
+ if @image
33
+ draw_image if @value
34
+ else
35
+ draw_text
36
+ end
37
+ end
38
+
39
+ def recalculate
40
+ super
41
+ return if @image
42
+
43
+ _width = dimensional_size(@style.width, :width)
44
+ _height = dimensional_size(@style.height, :height)
45
+
46
+ @width = _width || @text.textobject.text_width(@options[:checkmark])
47
+ @height = _height || @text.height
48
+
49
+ update_background
50
+ end
51
+
52
+ def value=(boolean)
53
+ @value = boolean
54
+
55
+ if boolean
56
+ @raw_text = @options[:checkmark]
57
+ else
58
+ @raw_text = ""
59
+ end
60
+
61
+ recalculate
62
+
63
+ publish(:changed, @value)
64
+ end
65
+ end
66
+ end
67
+ end