cyberarm_engine 0.13.1 → 0.17.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -0
  3. data/Gemfile +1 -1
  4. data/README.md +1 -1
  5. data/Rakefile +1 -1
  6. data/assets/textures/default.png +0 -0
  7. data/cyberarm_engine.gemspec +12 -9
  8. data/lib/cyberarm_engine.rb +20 -5
  9. data/lib/cyberarm_engine/animator.rb +6 -4
  10. data/lib/cyberarm_engine/background.rb +19 -15
  11. data/lib/cyberarm_engine/background_nine_slice.rb +125 -0
  12. data/lib/cyberarm_engine/bounding_box.rb +18 -18
  13. data/lib/cyberarm_engine/cache.rb +4 -0
  14. data/lib/cyberarm_engine/cache/download_manager.rb +121 -0
  15. data/lib/cyberarm_engine/common.rb +16 -16
  16. data/lib/cyberarm_engine/config_file.rb +2 -2
  17. data/lib/cyberarm_engine/game_object.rb +63 -72
  18. data/lib/cyberarm_engine/game_state.rb +6 -3
  19. data/lib/cyberarm_engine/model.rb +207 -0
  20. data/lib/cyberarm_engine/model/material.rb +21 -0
  21. data/lib/cyberarm_engine/model/model_object.rb +131 -0
  22. data/lib/cyberarm_engine/model/parser.rb +74 -0
  23. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -0
  24. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -0
  25. data/lib/cyberarm_engine/model_cache.rb +31 -0
  26. data/lib/cyberarm_engine/opengl.rb +28 -0
  27. data/lib/cyberarm_engine/opengl/light.rb +50 -0
  28. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -0
  29. data/lib/cyberarm_engine/opengl/perspective_camera.rb +38 -0
  30. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -0
  31. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +164 -0
  32. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +289 -0
  33. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +22 -0
  34. data/lib/cyberarm_engine/{shader.rb → opengl/shader.rb} +51 -43
  35. data/lib/cyberarm_engine/opengl/texture.rb +69 -0
  36. data/lib/cyberarm_engine/ray.rb +5 -5
  37. data/lib/cyberarm_engine/stats.rb +21 -0
  38. data/lib/cyberarm_engine/text.rb +45 -31
  39. data/lib/cyberarm_engine/timer.rb +1 -1
  40. data/lib/cyberarm_engine/transform.rb +43 -20
  41. data/lib/cyberarm_engine/ui/border_canvas.rb +4 -3
  42. data/lib/cyberarm_engine/ui/dsl.rb +49 -10
  43. data/lib/cyberarm_engine/ui/element.rb +73 -21
  44. data/lib/cyberarm_engine/ui/elements/button.rb +121 -28
  45. data/lib/cyberarm_engine/ui/elements/check_box.rb +25 -33
  46. data/lib/cyberarm_engine/ui/elements/container.rb +113 -33
  47. data/lib/cyberarm_engine/ui/elements/edit_box.rb +179 -0
  48. data/lib/cyberarm_engine/ui/elements/edit_line.rb +145 -45
  49. data/lib/cyberarm_engine/ui/elements/flow.rb +1 -3
  50. data/lib/cyberarm_engine/ui/elements/image.rb +32 -12
  51. data/lib/cyberarm_engine/ui/elements/label.rb +122 -16
  52. data/lib/cyberarm_engine/ui/elements/list_box.rb +82 -0
  53. data/lib/cyberarm_engine/ui/elements/progress.rb +6 -5
  54. data/lib/cyberarm_engine/ui/elements/radio.rb +6 -0
  55. data/lib/cyberarm_engine/ui/elements/slider.rb +104 -0
  56. data/lib/cyberarm_engine/ui/elements/stack.rb +1 -3
  57. data/lib/cyberarm_engine/ui/elements/text_block.rb +156 -0
  58. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +40 -31
  59. data/lib/cyberarm_engine/ui/event.rb +7 -7
  60. data/lib/cyberarm_engine/ui/gui_state.rb +118 -6
  61. data/lib/cyberarm_engine/ui/style.rb +10 -9
  62. data/lib/cyberarm_engine/ui/theme.rb +84 -22
  63. data/lib/cyberarm_engine/vector.rb +33 -30
  64. data/lib/cyberarm_engine/version.rb +2 -2
  65. data/lib/cyberarm_engine/{engine.rb → window.rb} +32 -19
  66. metadata +87 -18
  67. data/lib/cyberarm_engine/gosu_ext/circle.rb +0 -9
@@ -15,20 +15,18 @@ module CyberarmEngine
15
15
 
16
16
  return unless enabled?
17
17
 
18
- if respond_to?(event)
19
- return :handled if send(event, self, *args) == :handled
20
- end
18
+ return :handled if respond_to?(event) && (send(event, self, *args) == :handled)
21
19
 
22
20
  @event_handler[event].reverse_each do |handler|
23
21
  return :handled if handler.call(self, *args) == :handled
24
22
  end
25
23
 
26
24
  parent.publish(event, *args) if parent
27
- return nil
25
+ nil
28
26
  end
29
27
 
30
28
  def event(event)
31
- @event_handler ||= Hash.new
29
+ @event_handler ||= {}
32
30
  @event_handler[event] ||= []
33
31
  end
34
32
  end
@@ -37,11 +35,13 @@ module CyberarmEngine
37
35
  attr_reader :publisher, :event, :handler
38
36
 
39
37
  def initialize(publisher, event, handler)
40
- @publisher, @event, @handler = publisher, event, handler
38
+ @publisher = publisher
39
+ @event = event
40
+ @handler = handler
41
41
  end
42
42
 
43
43
  def unsubscribe
44
44
  @publisher.unsubscribe(self)
45
45
  end
46
46
  end
47
- end
47
+ end
@@ -17,17 +17,25 @@ module CyberarmEngine
17
17
  @active_width = window.width
18
18
  @active_height = window.height
19
19
 
20
+ @menu = nil
20
21
  @focus = nil
21
22
  @mouse_over = nil
22
23
  @mouse_down_on = {}
23
24
  @mouse_down_position = {}
25
+ @last_mouse_pos = nil
26
+ @dragging_element = nil
24
27
  @pending_recalculate_request = false
28
+
29
+ @tip = Element::ToolTip.new("", parent: @root_container, z: Float::INFINITY)
30
+ @menu = nil
31
+ @min_drag_distance = 0
32
+ @mouse_pos = Vector.new
25
33
  end
26
34
 
27
35
  # throws :blur event to focused element and sets GuiState focused element
28
36
  # Does NOT throw :focus event at element or set element as focused
29
37
  def focus=(element)
30
- @focus.publish(:blur) if @focus and element && @focus != element
38
+ @focus.publish(:blur) if @focus && element && @focus != element
31
39
  @focus = element
32
40
  end
33
41
 
@@ -35,15 +43,42 @@ module CyberarmEngine
35
43
  @focus
36
44
  end
37
45
 
46
+ def draw
47
+ super
48
+
49
+ if @menu
50
+ Gosu.flush
51
+ @menu.draw
52
+ end
53
+
54
+ if @tip.value.length.positive?
55
+ Gosu.flush
56
+ @tip.draw
57
+ end
58
+ end
59
+
38
60
  def update
39
61
  if @pending_recalculate_request
40
62
  @root_container.recalculate
63
+ @root_container.recalculate
64
+ @root_container.recalculate
65
+
41
66
  @pending_recalculate_request = false
42
67
  end
43
68
 
69
+ if @pending_focus_request
70
+ @pending_focus_request = false
71
+
72
+ self.focus = @pending_focus_element
73
+ @pending_focus_element.publish(:focus)
74
+ end
75
+
76
+ @menu&.update
44
77
  super
45
78
 
46
- new_mouse_over = @root_container.hit_element?(window.mouse_x, window.mouse_y)
79
+ new_mouse_over = @menu.hit_element?(window.mouse_x, window.mouse_y) if @menu
80
+ new_mouse_over ||= @root_container.hit_element?(window.mouse_x, window.mouse_y)
81
+
47
82
  if new_mouse_over
48
83
  new_mouse_over.publish(:enter) if new_mouse_over != @mouse_over
49
84
  new_mouse_over.publish(:hover)
@@ -56,12 +91,40 @@ module CyberarmEngine
56
91
  redirect_holding_mouse_button(:middle) if @mouse_over && Gosu.button_down?(Gosu::MsMiddle)
57
92
  redirect_holding_mouse_button(:right) if @mouse_over && Gosu.button_down?(Gosu::MsRight)
58
93
 
59
- request_recalculate if @active_width != window.width || @active_height != window.height
94
+ if Vector.new(window.mouse_x, window.mouse_y) == @last_mouse_pos
95
+ if @mouse_over && (Gosu.milliseconds - @mouse_moved_at) > tool_tip_delay
96
+ @tip.value = @mouse_over.tip if @mouse_over
97
+ @tip.x = window.mouse_x - @tip.width / 2
98
+ @tip.x = 0 if @tip.x < 0
99
+ @tip.x = window.width - @tip.width if @tip.x + @tip.width > window.width
100
+ @tip.y = window.mouse_y - @tip.height
101
+ @tip.y = 0 if @tip.y < 0
102
+ @tip.y = window.height - @tip.height if @tip.y + @tip.height > window.height
103
+ @tip.update
104
+ @tip.recalculate
105
+ else
106
+ @tip.value = ""
107
+ end
108
+ else
109
+ @mouse_moved_at = Gosu.milliseconds
110
+ end
111
+
112
+ @last_mouse_pos = Vector.new(window.mouse_x, window.mouse_y)
113
+ @mouse_pos = @last_mouse_pos.clone
114
+
115
+ if @active_width != window.width || @active_height != window.height
116
+ request_recalculate
117
+ @root_container.publish(:window_size_changed)
118
+ end
60
119
 
61
120
  @active_width = window.width
62
121
  @active_height = window.height
63
122
  end
64
123
 
124
+ def tool_tip_delay
125
+ 250 # ms
126
+ end
127
+
65
128
  def button_down(id)
66
129
  super
67
130
 
@@ -72,7 +135,11 @@ module CyberarmEngine
72
135
  redirect_mouse_button(:middle)
73
136
  when Gosu::MsRight
74
137
  redirect_mouse_button(:right)
138
+ when Gosu::KbF5
139
+ request_recalculate
75
140
  end
141
+
142
+ @focus.button_down(id) if @focus.respond_to?(:button_down)
76
143
  end
77
144
 
78
145
  def button_up(id)
@@ -90,9 +157,13 @@ module CyberarmEngine
90
157
  when Gosu::MsWheelDown
91
158
  redirect_mouse_wheel(:down)
92
159
  end
160
+
161
+ @focus.button_up(id) if @focus.respond_to?(:button_up)
93
162
  end
94
163
 
95
164
  def redirect_mouse_button(button)
165
+ hide_menu unless @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
166
+
96
167
  if @focus && @mouse_over != @focus
97
168
  @focus.publish(:blur)
98
169
  @focus = nil
@@ -110,9 +181,19 @@ module CyberarmEngine
110
181
  end
111
182
 
112
183
  def redirect_released_mouse_button(button)
184
+ hide_menu if @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
185
+
113
186
  if @mouse_over
114
187
  @mouse_over.publish(:"released_#{button}_mouse_button", window.mouse_x, window.mouse_y)
115
- @mouse_over.publish(:"clicked_#{button}_mouse_button", window.mouse_x, window.mouse_y) if @mouse_over == @mouse_down_on[button]
188
+ if @mouse_over == @mouse_down_on[button]
189
+ @mouse_over.publish(:"clicked_#{button}_mouse_button", window.mouse_x,
190
+ window.mouse_y)
191
+ end
192
+ end
193
+
194
+ if @dragging_element
195
+ @dragging_element.publish(:end_drag, window.mouse_x, window.mouse_y, button)
196
+ @dragging_element = nil
116
197
  end
117
198
 
118
199
  @mouse_down_position[button] = nil
@@ -120,7 +201,16 @@ module CyberarmEngine
120
201
  end
121
202
 
122
203
  def redirect_holding_mouse_button(button)
123
- @mouse_over.publish(:"holding_#{button}_mouse_button", window.mouse_x, window.mouse_y) if @mouse_over
204
+ if !@dragging_element && @mouse_down_on[button] && @mouse_down_on[button].draggable?(button) && @mouse_pos.distance(@mouse_down_position[button]) > @min_drag_distance
205
+ @dragging_element = @mouse_down_on[button]
206
+ @dragging_element.publish(:begin_drag, window.mouse_x, window.mouse_y, button)
207
+ end
208
+
209
+ if @dragging_element
210
+ @dragging_element.publish(:drag_update, window.mouse_x, window.mouse_y, button) if @dragging_element
211
+ elsif @mouse_over
212
+ @mouse_over.publish(:"holding_#{button}_mouse_button", window.mouse_x, window.mouse_y)
213
+ end
124
214
  end
125
215
 
126
216
  def redirect_mouse_wheel(button)
@@ -131,5 +221,27 @@ module CyberarmEngine
131
221
  def request_recalculate
132
222
  @pending_recalculate_request = true
133
223
  end
224
+
225
+ def request_focus(element)
226
+ @pending_focus_request = true
227
+ @pending_focus_element = element
228
+ end
229
+
230
+ def show_menu(list_box)
231
+ @menu = list_box
232
+ end
233
+
234
+ def hide_menu
235
+ @menu = nil
236
+ end
237
+
238
+ def to_s
239
+ # "#{self.class} children=#{@children.map { |c| c.to_s }}"
240
+ @root_container.to_s
241
+ end
242
+
243
+ def inspect
244
+ to_s
245
+ end
134
246
  end
135
- end
247
+ end
@@ -1,11 +1,11 @@
1
1
  module Gosu
2
2
  class Color
3
- def _dump(level)
3
+ def _dump(_level)
4
4
  [
5
- "%02X" % self.alpha,
6
- "%02X" % self.red,
7
- "%02X" % self.green,
8
- "%02X" % self.blue
5
+ "%02X" % alpha,
6
+ "%02X" % red,
7
+ "%02X" % green,
8
+ "%02X" % blue
9
9
  ].join
10
10
  end
11
11
 
@@ -21,17 +21,18 @@ module CyberarmEngine
21
21
  @hash = Marshal.load(Marshal.dump(hash))
22
22
  end
23
23
 
24
- def method_missing(method, *args, &block)
24
+ def method_missing(method, *args)
25
25
  if method.to_s.end_with?("=")
26
26
  raise "Did not expect more than 1 argument" if args.size > 1
27
- return @hash[method.to_s.sub("=", "").to_sym] = args.first
27
+
28
+ @hash[method.to_s.sub("=", "").to_sym] = args.first
28
29
 
29
30
  elsif args.size == 0
30
- return @hash[method]
31
+ @hash[method]
31
32
 
32
33
  else
33
34
  raise ArgumentError, "Did not expect arguments"
34
35
  end
35
36
  end
36
37
  end
37
- end
38
+ end
@@ -11,17 +11,21 @@ module CyberarmEngine
11
11
 
12
12
  def theme_defaults(options)
13
13
  raise "Error" unless self.class.ancestors.include?(CyberarmEngine::Element)
14
+
14
15
  _theme = THEME
15
- _theme = _theme.merge(options[:theme]) if options[:theme]
16
+ _theme = deep_merge(_theme, options[:theme]) if options[:theme]
16
17
  _theme.delete(:theme) if options[:theme]
17
18
 
18
19
  hash = {}
19
20
  class_names = self.class.ancestors
20
- class_names = class_names[0..class_names.index(CyberarmEngine::Element)].map! {|c| c.to_s.split("::").last.to_sym}.reverse!
21
+ class_names = class_names[0..class_names.index(CyberarmEngine::Element)].map! do |c|
22
+ c.to_s.split("::").last.to_sym
23
+ end.reverse!
21
24
 
22
25
  class_names.each do |klass|
23
26
  next unless data = _theme.dig(klass)
24
- data.each do |key, value|
27
+
28
+ data.each do |_key, _value|
25
29
  hash.merge!(data)
26
30
  end
27
31
  end
@@ -32,7 +36,7 @@ module CyberarmEngine
32
36
  # Derived from Rails Hash#deep_merge!
33
37
  # Enables passing partial themes through Element options without issue
34
38
  def deep_merge(original, intergrate, &block)
35
- hash = original.merge(intergrate) do |key, this_val, other_val|
39
+ original.merge(intergrate) do |key, this_val, other_val|
36
40
  if this_val.is_a?(Hash) && other_val.is_a?(Hash)
37
41
  deep_merge(this_val, other_val, &block)
38
42
  elsif block_given?
@@ -41,8 +45,6 @@ module CyberarmEngine
41
45
  other_val
42
46
  end
43
47
  end
44
-
45
- return hash
46
48
  end
47
49
 
48
50
  THEME = {
@@ -51,33 +53,40 @@ module CyberarmEngine
51
53
  y: 0,
52
54
  z: 30,
53
55
 
54
- width: nil,
56
+ width: nil,
55
57
  height: nil,
56
- color: Gosu::Color::WHITE,
58
+ color: Gosu::Color::WHITE,
57
59
  background: Gosu::Color::NONE,
58
- margin: 0,
59
- padding: 0,
60
+ margin: 0,
61
+ padding: 0,
60
62
  border_thickness: 0,
61
63
  border_color: Gosu::Color::NONE,
62
- border_radius: 0,
64
+ border_radius: 0
63
65
  },
64
66
 
65
67
  Button: { # < Label
66
- margin: 1,
67
- padding: 4,
68
+ margin: 1,
69
+ padding: 4,
68
70
  border_thickness: 1,
69
71
  border_color: ["ffd59674".hex, "ffff8746".hex],
70
72
  border_radius: 0,
71
73
  background: ["ffc75e61".to_i(16), "ffe26623".to_i(16)],
74
+ text_align: :center,
75
+ text_wrap: :none,
72
76
 
73
77
  hover: {
74
- color: Gosu::Color.rgb(200,200,200),
75
- background: ["ffB23E41".to_i(16), "ffFF7C00".to_i(16)],
78
+ color: Gosu::Color.rgb(200, 200, 200),
79
+ background: ["ffB23E41".to_i(16), "ffFF7C00".to_i(16)]
76
80
  },
77
81
 
78
82
  active: {
79
83
  color: Gosu::Color::BLACK,
80
84
  background: ["ffB23E41".to_i(16)]
85
+ },
86
+
87
+ disabled: {
88
+ color: Gosu::Color::GRAY,
89
+ background: 0xff303030
81
90
  }
82
91
  },
83
92
 
@@ -88,19 +97,63 @@ module CyberarmEngine
88
97
  caret_width: 2,
89
98
  caret_color: Gosu::Color::WHITE,
90
99
  caret_interval: 500,
91
- selection_color: Gosu::Color::GREEN,
100
+ selection_color: Gosu::Color.rgba(255, 128, 50, 200),
101
+ text_align: :left
92
102
  },
93
103
 
94
104
  Image: { # < Element
105
+ color: Gosu::Color::WHITE,
106
+ tileable: false,
95
107
  retro: false
96
108
  },
97
109
 
98
- Label: { # < Element
99
- text_size: 28,
100
- text_shadow: false,
101
- font: "Arial",
102
- margin: 0,
103
- padding: 2
110
+ TextBlock: { # < Element
111
+ text_size: 28,
112
+ text_wrap: :word_wrap, # :word_wrap, :break_word, :none
113
+ text_shadow: false,
114
+ text_align: :left,
115
+ font: "Arial",
116
+ margin: 0,
117
+ padding: 2
118
+ },
119
+
120
+ Banner: { # < TextBlock
121
+ text_size: 48
122
+ },
123
+
124
+ Title: { # < TextBlock
125
+ text_size: 34
126
+ },
127
+
128
+ Subtitle: { # < TextBlock
129
+ text_size: 26
130
+ },
131
+
132
+ Tagline: { # < TextBlock
133
+ text_size: 24
134
+ },
135
+
136
+ Caption: { # < TextBlock
137
+ text_size: 22
138
+ },
139
+
140
+ Para: { # < TextBlock
141
+ text_size: 18
142
+ },
143
+
144
+ Inscription: { # < TextBlock
145
+ text_size: 16
146
+ },
147
+
148
+ ToolTip: { # < TextBlock
149
+ color: Gosu::Color::WHITE,
150
+ padding_top: 4,
151
+ padding_bottom: 4,
152
+ padding_left: 8,
153
+ padding_right: 8,
154
+ border_thickness: 1,
155
+ border_color: 0xffaaaaaa,
156
+ background: 0xff404040
104
157
  },
105
158
 
106
159
  ToggleButton: { # < Button
@@ -114,6 +167,15 @@ module CyberarmEngine
114
167
  fraction_background: [0xffc75e61, 0xffe26623],
115
168
  border_thickness: 1,
116
169
  border_color: [0xffd59674, 0xffff8746]
170
+ },
171
+
172
+ Slider: { # < Element
173
+ width: 250,
174
+ height: 36,
175
+ background: 0xff111111,
176
+ fraction_background: [0xffc75e61, 0xffe26623],
177
+ border_thickness: 1,
178
+ border_color: [0xffd59674, 0xffff8746]
117
179
  }
118
180
  }.freeze
119
181
  end