cyberarm_engine 0.14.0 → 0.18.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -0
  3. data/Gemfile +1 -1
  4. data/README.md +5 -4
  5. data/Rakefile +1 -1
  6. data/assets/textures/default.png +0 -0
  7. data/assets/textures/logo.png +0 -0
  8. data/cyberarm_engine.gemspec +11 -9
  9. data/lib/cyberarm_engine.rb +19 -7
  10. data/lib/cyberarm_engine/animator.rb +13 -11
  11. data/lib/cyberarm_engine/background.rb +19 -15
  12. data/lib/cyberarm_engine/background_nine_slice.rb +125 -0
  13. data/lib/cyberarm_engine/bounding_box.rb +18 -18
  14. data/lib/cyberarm_engine/builtin/intro_state.rb +128 -0
  15. data/lib/cyberarm_engine/cache.rb +4 -0
  16. data/lib/cyberarm_engine/cache/download_manager.rb +121 -0
  17. data/lib/cyberarm_engine/common.rb +18 -13
  18. data/lib/cyberarm_engine/config_file.rb +2 -2
  19. data/lib/cyberarm_engine/game_object.rb +63 -72
  20. data/lib/cyberarm_engine/game_state.rb +11 -3
  21. data/lib/cyberarm_engine/model.rb +207 -0
  22. data/lib/cyberarm_engine/model/material.rb +21 -0
  23. data/lib/cyberarm_engine/model/model_object.rb +131 -0
  24. data/lib/cyberarm_engine/model/parser.rb +74 -0
  25. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -0
  26. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -0
  27. data/lib/cyberarm_engine/model_cache.rb +31 -0
  28. data/lib/cyberarm_engine/opengl.rb +28 -0
  29. data/lib/cyberarm_engine/opengl/light.rb +50 -0
  30. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -0
  31. data/lib/cyberarm_engine/opengl/perspective_camera.rb +38 -0
  32. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -0
  33. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +164 -0
  34. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +289 -0
  35. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +22 -0
  36. data/lib/cyberarm_engine/{shader.rb → opengl/shader.rb} +51 -43
  37. data/lib/cyberarm_engine/opengl/texture.rb +69 -0
  38. data/lib/cyberarm_engine/ray.rb +5 -5
  39. data/lib/cyberarm_engine/stats.rb +2 -2
  40. data/lib/cyberarm_engine/text.rb +51 -27
  41. data/lib/cyberarm_engine/timer.rb +1 -1
  42. data/lib/cyberarm_engine/transform.rb +43 -20
  43. data/lib/cyberarm_engine/ui/border_canvas.rb +4 -3
  44. data/lib/cyberarm_engine/ui/dsl.rb +45 -12
  45. data/lib/cyberarm_engine/ui/element.rb +211 -61
  46. data/lib/cyberarm_engine/ui/elements/button.rb +72 -42
  47. data/lib/cyberarm_engine/ui/elements/check_box.rb +5 -2
  48. data/lib/cyberarm_engine/ui/elements/container.rb +81 -29
  49. data/lib/cyberarm_engine/ui/elements/edit_box.rb +175 -2
  50. data/lib/cyberarm_engine/ui/elements/edit_line.rb +139 -48
  51. data/lib/cyberarm_engine/ui/elements/flow.rb +1 -1
  52. data/lib/cyberarm_engine/ui/elements/image.rb +32 -12
  53. data/lib/cyberarm_engine/ui/elements/list_box.rb +78 -2
  54. data/lib/cyberarm_engine/ui/elements/progress.rb +5 -5
  55. data/lib/cyberarm_engine/ui/elements/radio.rb +1 -1
  56. data/lib/cyberarm_engine/ui/elements/slider.rb +13 -16
  57. data/lib/cyberarm_engine/ui/elements/stack.rb +1 -1
  58. data/lib/cyberarm_engine/ui/elements/text_block.rb +153 -0
  59. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +27 -19
  60. data/lib/cyberarm_engine/ui/event.rb +7 -7
  61. data/lib/cyberarm_engine/ui/gui_state.rb +88 -16
  62. data/lib/cyberarm_engine/ui/style.rb +23 -11
  63. data/lib/cyberarm_engine/ui/theme.rb +95 -21
  64. data/lib/cyberarm_engine/vector.rb +33 -30
  65. data/lib/cyberarm_engine/version.rb +2 -2
  66. data/lib/cyberarm_engine/window.rb +35 -18
  67. metadata +70 -18
  68. data/lib/cyberarm_engine/ui/elements/label.rb +0 -52
@@ -1,6 +1,7 @@
1
1
  module CyberarmEngine
2
2
  class BorderCanvas
3
3
  attr_reader :element, :top, :right, :bottom, :left
4
+
4
5
  def initialize(element:)
5
6
  @element = element
6
7
 
@@ -25,7 +26,7 @@ module CyberarmEngine
25
26
 
26
27
  elsif color.is_a?(Array)
27
28
  if color.size == 1
28
- color=color.first
29
+ color = color.first
29
30
 
30
31
  elsif color.size == 2
31
32
  @top.background = color.first
@@ -61,7 +62,7 @@ module CyberarmEngine
61
62
 
62
63
  def update
63
64
  # TOP
64
- @top.x = @element.x# + @element.border_thickness_left
65
+ @top.x = @element.x # + @element.border_thickness_left
65
66
  @top.y = @element.y
66
67
  @top.z = @element.z
67
68
 
@@ -98,4 +99,4 @@ module CyberarmEngine
98
99
  @left.update
99
100
  end
100
101
  end
101
- end
102
+ end
@@ -8,64 +8,97 @@ module CyberarmEngine
8
8
  container(CyberarmEngine::Element::Stack, options, &block)
9
9
  end
10
10
 
11
+ # TODO: Remove in version 0.16.0+
11
12
  def label(text, options = {}, &block)
12
13
  options[:parent] = element_parent
13
14
  options[:theme] = current_theme
14
15
 
15
- add_element( Element::Label.new(text, options, block) )
16
+ add_element(Element::TextBlock.new(text, options, block))
17
+ end
18
+
19
+ [
20
+ "Banner",
21
+ "Title",
22
+ "Subtitle",
23
+ "Tagline",
24
+ "Caption",
25
+ "Para",
26
+ "Inscription",
27
+ "Link"
28
+ ].each do |const|
29
+ define_method(:"#{const.downcase}") do |text, options = {}, &block|
30
+ options[:parent] = element_parent
31
+ options[:theme] = current_theme
32
+
33
+ add_element(Element.const_get(const).new(text, options, block))
34
+ end
16
35
  end
17
36
 
18
37
  def button(text, options = {}, &block)
19
38
  options[:parent] = element_parent
20
39
  options[:theme] = current_theme
21
40
 
22
- add_element( Element::Button.new(text, options, block) { if block.is_a?(Proc); block.call; end } )
41
+ add_element(Element::Button.new(text, options, block) { block.call if block.is_a?(Proc) })
42
+ end
43
+
44
+ def list_box(options = {}, &block)
45
+ options[:parent] = element_parent
46
+ options[:theme] = current_theme
47
+
48
+ add_element(Element::ListBox.new(options, block) { block.call if block.is_a?(Proc) })
23
49
  end
24
50
 
25
51
  def edit_line(text, options = {}, &block)
26
52
  options[:parent] = element_parent
27
53
  options[:theme] = current_theme
28
54
 
29
- add_element( Element::EditLine.new(text, options, block) )
55
+ add_element(Element::EditLine.new(text, options, block))
56
+ end
57
+
58
+ def edit_box(text, options = {}, &block)
59
+ options[:parent] = element_parent
60
+ options[:theme] = current_theme
61
+
62
+ add_element(Element::EditBox.new(text, options, block))
30
63
  end
31
64
 
32
65
  def toggle_button(options = {}, &block)
33
66
  options[:parent] = element_parent
34
67
  options[:theme] = current_theme
35
68
 
36
- add_element( Element::ToggleButton.new(options, block) )
69
+ add_element(Element::ToggleButton.new(options, block))
37
70
  end
38
71
 
39
72
  def check_box(text, options = {}, &block)
40
73
  options[:parent] = element_parent
41
74
  options[:theme] = current_theme
42
75
 
43
- add_element( Element::CheckBox.new(text, options, block) )
76
+ add_element(Element::CheckBox.new(text, options, block))
44
77
  end
45
78
 
46
79
  def image(path, options = {}, &block)
47
80
  options[:parent] = element_parent
48
81
  options[:theme] = current_theme
49
82
 
50
- add_element( Element::Image.new(path, options, block) )
83
+ add_element(Element::Image.new(path, options, block))
51
84
  end
52
85
 
53
86
  def progress(options = {}, &block)
54
87
  options[:parent] = element_parent
55
88
  options[:theme] = current_theme
56
89
 
57
- add_element( Element::Progress.new(options, block) )
90
+ add_element(Element::Progress.new(options, block))
58
91
  end
59
92
 
60
93
  def slider(options = {}, &block)
61
94
  options[:parent] = element_parent
62
95
  options[:theme] = current_theme
63
96
 
64
- add_element( Element::Slider.new(options, block) )
97
+ add_element(Element::Slider.new(options, block))
65
98
  end
66
99
 
67
100
  def background(color = Gosu::Color::NONE)
68
- element_parent.style.background = color
101
+ element_parent.style.default[:background] = color
69
102
  end
70
103
 
71
104
  def theme(theme)
@@ -79,7 +112,7 @@ module CyberarmEngine
79
112
  private def add_element(element)
80
113
  element_parent.add(element)
81
114
 
82
- return element
115
+ element
83
116
  end
84
117
 
85
118
  private def element_parent
@@ -100,7 +133,7 @@ module CyberarmEngine
100
133
 
101
134
  $__current_container__ = old_parent
102
135
 
103
- return _container
136
+ _container
104
137
  end
105
138
  end
106
- end
139
+ end
@@ -13,13 +13,18 @@ module CyberarmEngine
13
13
  @options = options
14
14
  @block = block
15
15
 
16
- @focus = false
17
- @enabled = true
18
- @visible = true
19
- @tip = @options[:tip] ? @options[:tip] : ""
16
+ @focus = @options[:focus].nil? ? false : @options[:focus]
17
+ @enabled = @options[:enabled].nil? ? true : @options[:enabled]
18
+ @visible = @options[:visible].nil? ? true : @options[:visible]
19
+ @tip = @options[:tip] || ""
20
+
21
+ @debug_color = @options[:debug_color].nil? ? Gosu::Color::RED : @options[:debug_color]
20
22
 
21
23
  @style = Style.new(options)
22
24
 
25
+ @root ||= nil
26
+ @gui_state ||= nil
27
+
23
28
  @x = @style.x
24
29
  @y = @style.y
25
30
  @z = @style.z
@@ -27,76 +32,105 @@ module CyberarmEngine
27
32
  @width = 0
28
33
  @height = 0
29
34
 
30
- @fixed_x = @x if @x != 0
31
- @fixed_y = @y if @y != 0
32
-
33
35
  @style.width = default(:width) || nil
34
36
  @style.height = default(:height) || nil
35
37
 
36
38
  @style.background_canvas = Background.new
37
39
  @style.border_canvas = BorderCanvas.new(element: self)
38
40
 
41
+ @style_event = :default
42
+
39
43
  stylize
40
44
 
41
45
  default_events
46
+
47
+ root.gui_state.request_focus(self) if @options[:autofocus]
42
48
  end
43
49
 
44
50
  def stylize
45
- set_border_thickness(@style.border_thickness)
51
+ set_static_position
52
+
53
+ set_padding
54
+ set_margin
46
55
 
47
- set_padding(@style.padding)
56
+ set_background
48
57
 
49
- set_margin(@style.margin)
58
+ set_border_thickness
59
+ set_border_color
60
+ end
50
61
 
51
- set_background(@style.background)
52
- set_border_color(@style.border_color)
62
+ def safe_style_fetch(*args)
63
+ @style.hash.dig(@style_event, *args) || @style.hash.dig(:default, *args) || default(*args)
53
64
  end
54
65
 
55
- def set_background(background)
56
- @style.background = background
57
- @style.background_canvas.background = background
66
+ def set_static_position
67
+ @x = @style.x if @style.x != 0
68
+ @y = @style.y if @style.y != 0
58
69
  end
59
70
 
60
- def set_border_thickness(border_thickness)
61
- @style.border_thickness = border_thickness
71
+ def set_background
72
+ @style.background = safe_style_fetch(:background)
62
73
 
63
- @style.border_thickness_left = default(:border_thickness_left) || @style.border_thickness
64
- @style.border_thickness_right = default(:border_thickness_right) || @style.border_thickness
65
- @style.border_thickness_top = default(:border_thickness_top) || @style.border_thickness
66
- @style.border_thickness_bottom = default(:border_thickness_bottom) || @style.border_thickness
74
+ @style.background_canvas.background = @style.background
67
75
  end
68
76
 
69
- def set_border_color(color)
70
- @style.border_color = color
77
+ def set_border_thickness
78
+ @style.border_thickness = safe_style_fetch(:border_thickness)
71
79
 
72
- @style.border_color_left = default(:border_color_left) || @style.border_color
73
- @style.border_color_right = default(:border_color_right) || @style.border_color
74
- @style.border_color_top = default(:border_color_top) || @style.border_color
75
- @style.border_color_bottom = default(:border_color_bottom) || @style.border_color
80
+ @style.border_thickness_left = safe_style_fetch(:border_thickness_left) || @style.border_thickness
81
+ @style.border_thickness_right = safe_style_fetch(:border_thickness_right) || @style.border_thickness
82
+ @style.border_thickness_top = safe_style_fetch(:border_thickness_top) || @style.border_thickness
83
+ @style.border_thickness_bottom = safe_style_fetch(:border_thickness_bottom) || @style.border_thickness
84
+ end
76
85
 
77
- @style.border_canvas.color = color
86
+ def set_border_color
87
+ @style.border_color = safe_style_fetch(:border_color)
88
+
89
+ @style.border_color_left = safe_style_fetch(:border_color_left) || @style.border_color
90
+ @style.border_color_right = safe_style_fetch(:border_color_right) || @style.border_color
91
+ @style.border_color_top = safe_style_fetch(:border_color_top) || @style.border_color
92
+ @style.border_color_bottom = safe_style_fetch(:border_color_bottom) || @style.border_color
93
+
94
+ @style.border_canvas.color = [
95
+ @style.border_color_top,
96
+ @style.border_color_right,
97
+ @style.border_color_bottom,
98
+ @style.border_color_left
99
+ ]
100
+ end
101
+
102
+ def set_padding
103
+ @style.padding = safe_style_fetch(:padding)
104
+
105
+ @style.padding_left = safe_style_fetch(:padding_left) || @style.padding
106
+ @style.padding_right = safe_style_fetch(:padding_right) || @style.padding
107
+ @style.padding_top = safe_style_fetch(:padding_top) || @style.padding
108
+ @style.padding_bottom = safe_style_fetch(:padding_bottom) || @style.padding
78
109
  end
79
110
 
80
- def set_padding(padding)
81
- @style.padding = padding
111
+ def set_margin
112
+ @style.margin = safe_style_fetch(:margin)
82
113
 
83
- @style.padding_left = default(:padding_left) || @style.padding
84
- @style.padding_right = default(:padding_right) || @style.padding
85
- @style.padding_top = default(:padding_top) || @style.padding
86
- @style.padding_bottom = default(:padding_bottom) || @style.padding
114
+ @style.margin_left = safe_style_fetch(:margin_left) || @style.margin
115
+ @style.margin_right = safe_style_fetch(:margin_right) || @style.margin
116
+ @style.margin_top = safe_style_fetch(:margin_top) || @style.margin
117
+ @style.margin_bottom = safe_style_fetch(:margin_bottom) || @style.margin
87
118
  end
88
119
 
89
- def set_margin(margin)
90
- @style.margin = margin
120
+ def update_styles(event = :default)
121
+ _style = @style.send(event)
122
+ @style_event = event
123
+
124
+ if @text.is_a?(CyberarmEngine::Text)
125
+ @text.color = _style&.dig(:color) || @style.default[:color]
126
+ @text.swap_font(_style&.dig(:text_size) || @style.default[:text_size], _style&.dig(:font) || @style.default[:font])
127
+ end
91
128
 
92
- @style.margin_left = default(:margin_left) || @style.margin
93
- @style.margin_right = default(:margin_right) || @style.margin
94
- @style.margin_top = default(:margin_top) || @style.margin
95
- @style.margin_bottom = default(:margin_bottom) || @style.margin
129
+ (root&.gui_state || @gui_state).request_recalculate
96
130
  end
97
131
 
98
132
  def default_events
99
- [:left, :middle, :right].each do |button|
133
+ %i[left middle right].each do |button|
100
134
  event(:"#{button}_mouse_button")
101
135
  event(:"released_#{button}_mouse_button")
102
136
  event(:"clicked_#{button}_mouse_button")
@@ -110,11 +144,74 @@ module CyberarmEngine
110
144
  event(:hover)
111
145
  event(:leave)
112
146
 
147
+ event(:focus)
113
148
  event(:blur)
114
149
 
115
150
  event(:changed)
116
151
  end
117
152
 
153
+ def enter(_sender)
154
+ @focus = false unless window.button_down?(Gosu::MsLeft)
155
+
156
+ if !@enabled
157
+ update_styles(:disabled)
158
+ elsif @focus
159
+ update_styles(:active)
160
+ else
161
+ update_styles(:hover)
162
+ end
163
+
164
+ :handled
165
+ end
166
+
167
+ def left_mouse_button(_sender, _x, _y)
168
+ @focus = true
169
+
170
+ unless @enabled
171
+ update_styles(:disabled)
172
+ else
173
+ update_styles(:active)
174
+ end
175
+
176
+ window.current_state.focus = self
177
+
178
+ :handled
179
+ end
180
+
181
+ def released_left_mouse_button(sender, _x, _y)
182
+ enter(sender)
183
+
184
+ :handled
185
+ end
186
+
187
+ def clicked_left_mouse_button(_sender, _x, _y)
188
+ @block&.call(self) if @enabled && !self.is_a?(Container)
189
+
190
+ :handled
191
+ end
192
+
193
+ def leave(_sender)
194
+ if @enabled
195
+ update_styles
196
+ else
197
+ update_styles(:disabled)
198
+ end
199
+
200
+ :handled
201
+ end
202
+
203
+ def blur(_sender)
204
+ @focus = false
205
+
206
+ if @enabled
207
+ update_styles
208
+ else
209
+ update_styles(:disabled)
210
+ end
211
+
212
+ :handled
213
+ end
214
+
118
215
  def enabled?
119
216
  @enabled
120
217
  end
@@ -129,21 +226,51 @@ module CyberarmEngine
129
226
  end
130
227
 
131
228
  def show
229
+ bool = visible?
132
230
  @visible = true
133
- root.gui_state.request_recalculate
231
+ root.gui_state.request_recalculate unless bool
134
232
  end
135
233
 
136
234
  def hide
235
+ bool = visible?
137
236
  @visible = false
138
- root.gui_state.request_recalculate
237
+ root.gui_state.request_recalculate if bool
139
238
  end
140
239
 
141
240
  def draw
142
- return unless @visible
241
+ return unless visible?
143
242
 
144
243
  @style.background_canvas.draw
145
244
  @style.border_canvas.draw
146
- render
245
+
246
+ Gosu.clip_to(@x, @y, width, height) do
247
+ render
248
+ end
249
+ end
250
+
251
+ def debug_draw
252
+ return if defined?(GUI_DEBUG_ONLY_ELEMENT) && self.class == GUI_DEBUG_ONLY_ELEMENT
253
+
254
+ Gosu.draw_line(
255
+ x, y, @debug_color,
256
+ x + outer_width, y, @debug_color,
257
+ Float::INFINITY
258
+ )
259
+ Gosu.draw_line(
260
+ x + outer_width, y, @debug_color,
261
+ x + outer_width, y + outer_height, @debug_color,
262
+ Float::INFINITY
263
+ )
264
+ Gosu.draw_line(
265
+ x + outer_width, y + outer_height, @debug_color,
266
+ x, y + outer_height, @debug_color,
267
+ Float::INFINITY
268
+ )
269
+ Gosu.draw_line(
270
+ x, outer_height, @debug_color,
271
+ x, y, @debug_color,
272
+ Float::INFINITY
273
+ )
147
274
  end
148
275
 
149
276
  def update
@@ -155,7 +282,7 @@ module CyberarmEngine
155
282
  def button_up(id)
156
283
  end
157
284
 
158
- def draggable?(button)
285
+ def draggable?(_button)
159
286
  false
160
287
  end
161
288
 
@@ -164,7 +291,7 @@ module CyberarmEngine
164
291
 
165
292
  def hit?(x, y)
166
293
  x.between?(@x, @x + width) &&
167
- y.between?(@y, @y + height)
294
+ y.between?(@y, @y + height)
168
295
  end
169
296
 
170
297
  def width
@@ -215,21 +342,36 @@ module CyberarmEngine
215
342
  (@style.border_thickness_top + @style.padding_top) + (@style.padding_bottom + @style.border_thickness_bottom)
216
343
  end
217
344
 
218
- private def dimensional_size(size, dimension)
219
- raise "dimension must be either :width or :height" unless dimension == :width || dimension == :height
345
+ def scroll_width
346
+ @children.sum { |c| c.width } + noncontent_width
347
+ end
348
+
349
+ def scroll_height
350
+ @children.sum { |c| c.height } + noncontent_height
351
+ end
352
+
353
+ def max_scroll_width
354
+ scroll_width - width
355
+ end
356
+
357
+ def max_scroll_height
358
+ scroll_height - height
359
+ end
360
+
361
+ def dimensional_size(size, dimension)
362
+ raise "dimension must be either :width or :height" unless %i[width height].include?(dimension)
363
+
220
364
  if size && size.is_a?(Numeric)
221
365
  if size.between?(0.0, 1.0)
222
- ((@parent.send(:"content_#{dimension}") - self.send(:"noncontent_#{dimension}")) * size).round
366
+ ((@parent.send(:"content_#{dimension}") - send(:"noncontent_#{dimension}")) * size).round
223
367
  else
224
368
  size
225
369
  end
226
- else
227
- nil
228
370
  end
229
371
  end
230
372
 
231
373
  def background=(_background)
232
- @style.background_canvas.background=(_background)
374
+ @style.background_canvas.background = _background
233
375
  update_background
234
376
  end
235
377
 
@@ -252,11 +394,9 @@ module CyberarmEngine
252
394
  @root = parent
253
395
 
254
396
  loop do
255
- if @root.parent.nil?
256
- break
257
- else
258
- @root = @root.parent
259
- end
397
+ break unless @root&.parent
398
+
399
+ @root = @root.parent
260
400
  end
261
401
  end
262
402
 
@@ -267,6 +407,12 @@ module CyberarmEngine
267
407
  @gui_state != nil
268
408
  end
269
409
 
410
+ def focus(_)
411
+ warn "#{self.class}#focus was not overridden!"
412
+
413
+ :handled
414
+ end
415
+
270
416
  def recalculate
271
417
  raise "#{self.class}#recalculate was not overridden!"
272
418
  end
@@ -278,12 +424,16 @@ module CyberarmEngine
278
424
  raise "#{self.class}#value was not overridden!"
279
425
  end
280
426
 
281
- def value=(value)
427
+ def value=(_value)
282
428
  raise "#{self.class}#value= was not overridden!"
283
429
  end
284
430
 
285
431
  def to_s
286
- "#{self.class} x=#{x} y=#{y} width=#{width} height=#{height} value=#{ value.is_a?(String) ? "\"#{value}\"" : value }"
432
+ "#{self.class} x=#{x} y=#{y} width=#{width} height=#{height} value=#{value.is_a?(String) ? "\"#{value}\"" : value}"
433
+ end
434
+
435
+ def inspect
436
+ to_s
287
437
  end
288
438
  end
289
- end
439
+ end