cyberarm_engine 0.13.1 → 0.17.1

Sign up to get free protection for your applications and to get access to all the features.
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