cyberarm_engine 0.13.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -8
  3. data/.rubocop.yml +8 -0
  4. data/.travis.yml +5 -5
  5. data/Gemfile +6 -6
  6. data/LICENSE.txt +21 -21
  7. data/README.md +73 -43
  8. data/Rakefile +10 -10
  9. data/assets/textures/default.png +0 -0
  10. data/bin/console +14 -14
  11. data/bin/setup +8 -8
  12. data/cyberarm_engine.gemspec +39 -36
  13. data/lib/cyberarm_engine.rb +64 -47
  14. data/lib/cyberarm_engine/animator.rb +56 -54
  15. data/lib/cyberarm_engine/background.rb +179 -175
  16. data/lib/cyberarm_engine/background_nine_slice.rb +125 -0
  17. data/lib/cyberarm_engine/bounding_box.rb +150 -150
  18. data/lib/cyberarm_engine/cache.rb +4 -0
  19. data/lib/cyberarm_engine/cache/download_manager.rb +121 -0
  20. data/lib/cyberarm_engine/common.rb +96 -96
  21. data/lib/cyberarm_engine/config_file.rb +46 -0
  22. data/lib/cyberarm_engine/game_object.rb +248 -257
  23. data/lib/cyberarm_engine/game_state.rb +92 -89
  24. data/lib/cyberarm_engine/model.rb +207 -0
  25. data/lib/cyberarm_engine/model/material.rb +21 -0
  26. data/lib/cyberarm_engine/model/model_object.rb +131 -0
  27. data/lib/cyberarm_engine/model/parser.rb +74 -0
  28. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -0
  29. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -0
  30. data/lib/cyberarm_engine/model_cache.rb +31 -0
  31. data/lib/cyberarm_engine/opengl.rb +28 -0
  32. data/lib/cyberarm_engine/opengl/light.rb +50 -0
  33. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -0
  34. data/lib/cyberarm_engine/opengl/perspective_camera.rb +38 -0
  35. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -0
  36. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +164 -0
  37. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +289 -0
  38. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +22 -0
  39. data/lib/cyberarm_engine/opengl/shader.rb +406 -0
  40. data/lib/cyberarm_engine/opengl/texture.rb +69 -0
  41. data/lib/cyberarm_engine/ray.rb +56 -56
  42. data/lib/cyberarm_engine/stats.rb +21 -0
  43. data/lib/cyberarm_engine/text.rb +160 -146
  44. data/lib/cyberarm_engine/timer.rb +23 -23
  45. data/lib/cyberarm_engine/transform.rb +296 -273
  46. data/lib/cyberarm_engine/ui/border_canvas.rb +102 -101
  47. data/lib/cyberarm_engine/ui/dsl.rb +138 -99
  48. data/lib/cyberarm_engine/ui/element.rb +315 -276
  49. data/lib/cyberarm_engine/ui/elements/button.rb +160 -67
  50. data/lib/cyberarm_engine/ui/elements/check_box.rb +51 -59
  51. data/lib/cyberarm_engine/ui/elements/container.rb +256 -176
  52. data/lib/cyberarm_engine/ui/elements/edit_box.rb +179 -0
  53. data/lib/cyberarm_engine/ui/elements/edit_line.rb +262 -172
  54. data/lib/cyberarm_engine/ui/elements/flow.rb +15 -17
  55. data/lib/cyberarm_engine/ui/elements/image.rb +72 -52
  56. data/lib/cyberarm_engine/ui/elements/label.rb +156 -50
  57. data/lib/cyberarm_engine/ui/elements/list_box.rb +82 -0
  58. data/lib/cyberarm_engine/ui/elements/progress.rb +51 -50
  59. data/lib/cyberarm_engine/ui/elements/radio.rb +6 -0
  60. data/lib/cyberarm_engine/ui/elements/slider.rb +104 -0
  61. data/lib/cyberarm_engine/ui/elements/stack.rb +11 -13
  62. data/lib/cyberarm_engine/ui/elements/text_block.rb +156 -0
  63. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +65 -56
  64. data/lib/cyberarm_engine/ui/event.rb +47 -47
  65. data/lib/cyberarm_engine/ui/gui_state.rb +226 -135
  66. data/lib/cyberarm_engine/ui/style.rb +38 -37
  67. data/lib/cyberarm_engine/ui/theme.rb +182 -120
  68. data/lib/cyberarm_engine/vector.rb +293 -203
  69. data/lib/cyberarm_engine/version.rb +4 -4
  70. data/lib/cyberarm_engine/{engine.rb → window.rb} +114 -101
  71. metadata +88 -18
  72. data/lib/cyberarm_engine/gosu_ext/circle.rb +0 -9
  73. data/lib/cyberarm_engine/shader.rb +0 -262
@@ -0,0 +1,179 @@
1
+ module CyberarmEngine
2
+ class Element
3
+ class EditBox < EditLine
4
+ def initialize(*args)
5
+ super(*args)
6
+
7
+ @active_line = 0
8
+
9
+ @repeatable_keys = [
10
+ {
11
+ key: Gosu::KB_UP,
12
+ down: false,
13
+ repeat_delay: 50,
14
+ last_repeat: 0,
15
+ action: proc { move(:up) }
16
+ },
17
+ {
18
+ key: Gosu::KB_DOWN,
19
+ down: false,
20
+ repeat_delay: 50,
21
+ last_repeat: 0,
22
+ action: proc { move(:down) }
23
+ }
24
+ ]
25
+ end
26
+
27
+ def update
28
+ super
29
+
30
+ caret_stay_left_of_last_newline
31
+ calculate_active_line
32
+
33
+ @repeatable_keys.each do |key|
34
+ if key[:down] && (Gosu.milliseconds > key[:last_repeat] + key[:repeat_delay])
35
+ key[:action].call
36
+ key[:last_repeat] = Gosu.milliseconds
37
+ end
38
+ end
39
+ end
40
+
41
+ def draw_caret
42
+ Gosu.draw_rect(caret_position, @text.y + @active_line * @text.textobject.height, @caret_width, @caret_height,
43
+ @caret_color, @z)
44
+ end
45
+
46
+ def draw_selection
47
+ selection_width = caret_position - selection_start_position
48
+
49
+ Gosu.draw_rect(selection_start_position, @text.y, selection_width, @text.textobject.height,
50
+ default(:selection_color), @z)
51
+ end
52
+
53
+ def text_input_position_for(_method)
54
+ line = @text_input.text[0...@text_input.caret_pos].lines.last
55
+ _x = @text.x + @offset_x
56
+
57
+ if @type == :password
58
+ _x + @text.width(default(:password_character) * line.length)
59
+ else
60
+ _x + @text.width(line)
61
+ end
62
+ end
63
+
64
+ def set_position(int)
65
+ int = 0 if int < 0
66
+ @text_input.selection_start = @text_input.caret_pos = int
67
+ end
68
+
69
+ def calculate_active_line
70
+ sub_text = @text_input.text[0...@text_input.caret_pos]
71
+ @active_line = sub_text.lines.size - 1
72
+ end
73
+
74
+ def caret_stay_left_of_last_newline
75
+ @text_input.text += "\n" unless @text_input.text.end_with?("\n")
76
+
77
+ eof = @text_input.text.chomp.length
78
+ set_position(eof) if @text_input.caret_pos > eof
79
+ end
80
+
81
+ def caret_position_under_mouse(mouse_x, mouse_y)
82
+ active_line = row_at(mouse_y)
83
+ right_offset = column_at(mouse_x, mouse_y)
84
+
85
+ buffer = @text_input.text.lines[0..active_line].join if active_line != 0
86
+ buffer = @text_input.text.lines.first if active_line == 0
87
+ line = buffer.lines.last
88
+
89
+ if buffer.chars.last == "\n"
90
+ (buffer.length - line.length) + right_offset - 1
91
+ else
92
+ (buffer.length - line.length) + right_offset
93
+ end
94
+ end
95
+
96
+ def move_caret_to_mouse(mouse_x, mouse_y)
97
+ set_position(caret_position_under_mouse(mouse_x, mouse_y))
98
+ end
99
+
100
+ def row_at(y)
101
+ ((y - @text.y) / @text.textobject.height).round
102
+ end
103
+
104
+ def column_at(x, y)
105
+ row = row_at(y)
106
+
107
+ buffer = @text_input.text.lines[0..row].join if row != 0
108
+ buffer = @text_input.text.lines.first if row == 0
109
+
110
+ line = @text_input.text.lines[row]
111
+ line ||= ""
112
+ column = 0
113
+
114
+ line.length.times do |_i|
115
+ break if @text.textobject.text_width(line[0...column]) >= (x - @text.x).clamp(0.0, Float::INFINITY)
116
+
117
+ column += 1
118
+ end
119
+
120
+ column
121
+ end
122
+
123
+ def button_down(id)
124
+ super
125
+
126
+ @repeatable_keys.detect do |key|
127
+ next unless key[:key] == id
128
+
129
+ key[:down] = true
130
+ key[:last_repeat] = Gosu.milliseconds + key[:repeat_delay]
131
+ return true
132
+ end
133
+
134
+ case id
135
+ when Gosu::KB_ENTER, Gosu::KB_RETURN
136
+ caret_pos = @text_input.caret_pos
137
+ @text_input.text = @text_input.text.insert(@text_input.caret_pos, "\n")
138
+ @text_input.caret_pos = @text_input.selection_start = caret_pos + 1
139
+ end
140
+ end
141
+
142
+ def button_up(id)
143
+ super
144
+
145
+ @repeatable_keys.detect do |key|
146
+ if key[:key] == id
147
+ key[:down] = false
148
+ return true
149
+ end
150
+ end
151
+ end
152
+
153
+ def move(direction)
154
+ pos = @text_input.caret_pos
155
+ line = nil
156
+
157
+ case direction
158
+ when :up
159
+ return if @active_line == 0
160
+ when :down
161
+ return if @active_line == @text_input.text.chomp.lines
162
+
163
+ text = @text_input.text.chomp.lines[0..@active_line].join("\n")
164
+ pos = text.length
165
+ end
166
+
167
+ set_position(pos)
168
+ end
169
+
170
+ def drag_update(_sender, x, y, _button)
171
+ int = caret_position_under_mouse(x, y)
172
+ int = 0 if int < 0
173
+ @text_input.caret_pos = int
174
+
175
+ :handled
176
+ end
177
+ end
178
+ end
179
+ end
@@ -1,172 +1,262 @@
1
- module CyberarmEngine
2
- class Element
3
- class EditLine < Button
4
- def initialize(text, options = {}, block = nil)
5
- super(text, options, block)
6
-
7
- @type = default(:type)
8
-
9
- @caret_width = default(:caret_width)
10
- @caret_height= @text.height
11
- @caret_color = default(:caret_color)
12
- @caret_interval = default(:caret_interval)
13
- @caret_last_interval = Gosu.milliseconds
14
- @show_caret = true
15
-
16
- @text_input = Gosu::TextInput.new
17
- @text_input.text = text
18
-
19
- @offset_x = 0
20
-
21
- return self
22
- end
23
-
24
- def render
25
- Gosu.clip_to(@text.x, @text.y, @style.width, @text.height) do
26
- Gosu.translate(-@offset_x, 0) do
27
- draw_selection
28
- draw_caret if @focus && @show_caret
29
- draw_text
30
- end
31
- end
32
- end
33
-
34
- def draw_caret
35
- Gosu.draw_rect(caret_position, @text.y, @caret_width, @caret_height, @caret_color, @z)
36
- end
37
-
38
- def draw_selection
39
- selection_width = caret_position - selection_start_position
40
-
41
- Gosu.draw_rect(selection_start_position, @text.y, selection_width, @text.height, default(:selection_color), @z)
42
- end
43
-
44
- def update
45
- if @type == :password
46
- @text.text = default(:password_character) * @text_input.text.length
47
- else
48
- @text.text = @text_input.text
49
- end
50
-
51
- if Gosu.milliseconds >= @caret_last_interval + @caret_interval
52
- @caret_last_interval = Gosu.milliseconds
53
-
54
- @show_caret = !@show_caret
55
- end
56
-
57
- keep_caret_visible
58
- end
59
-
60
- def move_caret_to_mouse(mouse_x)
61
- 1.upto(@text.text.length) do |i|
62
- if mouse_x < @text.x + @text.textobject.text_width(@text.text[0...i])
63
- @text_input.caret_pos = @text_input.selection_start = i - 1;
64
- return
65
- end
66
- end
67
-
68
- @text_input.caret_pos = @text_input.selection_start = @text_input.text.length
69
- end
70
-
71
- def keep_caret_visible
72
- caret_pos = (caret_position - @text.x) + @caret_width
73
-
74
- @last_text ||= "/\\"
75
- @last_pos ||= -1
76
-
77
- puts "caret pos: #{caret_pos}, width: #{@width}, offset: #{@offset_x}" if (@last_text != @text.text) || (@last_pos != caret_pos)
78
-
79
- @last_text = @text.text
80
- @last_pos = caret_pos
81
-
82
-
83
- if caret_pos.between?(@offset_x, @width + @offset_x)
84
- # Do nothing
85
-
86
- elsif caret_pos < @offset_x
87
- if caret_pos > @width
88
- @offset_x = caret_pos + @width
89
- else
90
- @offset_x = 0
91
- end
92
-
93
- elsif caret_pos > @width
94
- @offset_x = caret_pos - @width
95
- puts "triggered"
96
-
97
- else
98
- # Reset to Zero
99
- @offset_x = 0
100
- end
101
- end
102
-
103
- def left_mouse_button(sender, x, y)
104
- super
105
- window.text_input = @text_input
106
-
107
- @caret_last_interval = Gosu.milliseconds
108
- @show_caret = true
109
-
110
- move_caret_to_mouse(x)
111
-
112
- return :handled
113
- end
114
-
115
- def enter(sender)
116
- if @focus
117
- @style.background_canvas.background = default(:active, :background)
118
- @text.color = default(:active, :color)
119
- else
120
- @style.background_canvas.background = default(:hover, :background)
121
- @text.color = default(:hover, :color)
122
- end
123
-
124
- return :handled
125
- end
126
-
127
- def leave(sender)
128
- unless @focus
129
- super
130
- end
131
-
132
- return :handled
133
- end
134
-
135
- def blur(sender)
136
- @focus = false
137
- @style.background_canvas.background = default(:background)
138
- @text.color = default(:color)
139
- window.text_input = nil
140
-
141
- return :handled
142
- end
143
-
144
- def caret_position
145
- text_input_position_for(:caret_pos)
146
- end
147
-
148
- def selection_start_position
149
- text_input_position_for(:selection_start)
150
- end
151
-
152
- def text_input_position_for(method)
153
- if @type == :password
154
- @text.x + @text.textobject.text_width(default(:password_character) * @text_input.text[0..@text_input.send(method)].length)
155
- else
156
- @text.x + @text.textobject.text_width(@text_input.text[0..@text_input.send(method)])
157
- end
158
- end
159
-
160
- def recalculate
161
- super
162
-
163
- @width = dimensional_size(@style.width, :width) || default(:width)
164
- update_background
165
- end
166
-
167
- def value
168
- @text_input.text
169
- end
170
- end
171
- end
172
- end
1
+ module CyberarmEngine
2
+ class Element
3
+ class EditLine < Button
4
+ def initialize(text, options = {}, block = nil)
5
+ @filter = options.delete(:filter)
6
+ super(text, options, block)
7
+
8
+ @type = default(:type)
9
+
10
+ @caret_width = default(:caret_width)
11
+ @caret_height = @text.textobject.height
12
+ @caret_color = default(:caret_color)
13
+ @caret_interval = default(:caret_interval)
14
+ @caret_last_interval = Gosu.milliseconds
15
+ @show_caret = true
16
+
17
+ @text_input = Gosu::TextInput.new
18
+ @text_input.text = text
19
+ @last_text_value = text
20
+
21
+ if @filter && @filter.respond_to?(:call)
22
+ @text_input.instance_variable_set(:@filter, @filter)
23
+
24
+ def @text_input.filter(text_in)
25
+ @filter.call(text_in)
26
+ end
27
+ end
28
+
29
+ @offset_x = 0
30
+ @offset_y = 0
31
+
32
+ event(:begin_drag)
33
+ event(:drag_update)
34
+ event(:end_drag)
35
+ end
36
+
37
+ def render
38
+ Gosu.clip_to(@text.x, @text.y, @width, @height) do
39
+ Gosu.translate(-@offset_x, -@offset_y) do
40
+ draw_selection
41
+ draw_caret if @focus && @show_caret
42
+ draw_text
43
+ end
44
+ end
45
+ end
46
+
47
+ def draw_text
48
+ @text.draw(:draw_text)
49
+ end
50
+
51
+ def draw_caret
52
+ Gosu.draw_rect(caret_position, @text.y, @caret_width, @caret_height, @caret_color, @z)
53
+ end
54
+
55
+ def draw_selection
56
+ selection_width = caret_position - selection_start_position
57
+
58
+ Gosu.draw_rect(selection_start_position, @text.y, selection_width, @text.height, default(:selection_color), @z)
59
+ end
60
+
61
+ def update
62
+ @text.text = if @type == :password
63
+ default(:password_character) * @text_input.text.length
64
+ else
65
+ @text_input.text
66
+ end
67
+
68
+ if @last_text_value != value
69
+ @last_text_value = value
70
+ @show_caret = true
71
+ @caret_last_interval = Gosu.milliseconds
72
+
73
+ publish(:changed, value)
74
+ end
75
+
76
+ if Gosu.milliseconds >= @caret_last_interval + @caret_interval
77
+ @caret_last_interval = Gosu.milliseconds
78
+
79
+ @show_caret = !@show_caret
80
+ end
81
+
82
+ keep_caret_visible
83
+ end
84
+
85
+ def button_down(id)
86
+ handle_keyboard_shortcuts(id)
87
+ end
88
+
89
+ def handle_keyboard_shortcuts(id)
90
+ return unless @focus && @enabled
91
+
92
+ if Gosu.button_down?(Gosu::KB_LEFT_CONTROL) || Gosu.button_down?(Gosu::KB_RIGHT_CONTROL)
93
+ case id
94
+ when Gosu::KB_A
95
+ @text_input.selection_start = 0
96
+ @text_input.caret_pos = @text_input.text.length
97
+
98
+ when Gosu::KB_C
99
+ if @text_input.selection_start < @text_input.caret_pos
100
+ Clipboard.copy(@text_input.text[@text_input.selection_start...@text_input.caret_pos])
101
+ else
102
+ Clipboard.copy(@text_input.text[@text_input.caret_pos...@text_input.selection_start])
103
+ end
104
+
105
+ when Gosu::KB_X
106
+ chars = @text_input.text.chars
107
+
108
+ if @text_input.selection_start < @text_input.caret_pos
109
+ Clipboard.copy(@text_input.text[@text_input.selection_start...@text_input.caret_pos])
110
+ chars.slice!(@text_input.selection_start, @text_input.caret_pos)
111
+ else
112
+ Clipboard.copy(@text_input.text[@text_input.caret_pos...@text_input.selection_start])
113
+ chars.slice!(@text_input.caret_pos, @text_input.selection_start)
114
+ end
115
+
116
+ @text_input.text = chars.join
117
+
118
+ when Gosu::KB_V
119
+ if instance_of?(EditLine) # EditLine assumes a single line of text
120
+ @text_input.text = @text_input.text.insert(@text_input.caret_pos,
121
+ Clipboard.paste.encode("UTF-8").gsub("\n", ""))
122
+ else
123
+ @text_input.text = @text_input.text.insert(@text_input.caret_pos, Clipboard.paste.encode("UTF-8"))
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ def caret_position_under_mouse(mouse_x)
130
+ 1.upto(@text.text.length) do |i|
131
+ return i - 1 if mouse_x < @text.x - @offset_x + @text.width(@text.text[0...i])
132
+ end
133
+
134
+ @text_input.text.length
135
+ end
136
+
137
+ def move_caret_to_mouse(mouse_x, _mouse_y)
138
+ @text_input.caret_pos = @text_input.selection_start = caret_position_under_mouse(mouse_x)
139
+ end
140
+
141
+ def keep_caret_visible
142
+ caret_pos = (caret_position - @text.x) + @caret_width
143
+
144
+ @last_text ||= "/\\"
145
+ @last_pos ||= -1
146
+
147
+ @last_text = @text.text
148
+ @last_pos = caret_pos
149
+
150
+ if caret_pos.between?(@offset_x, @width + @offset_x)
151
+ # Do nothing
152
+
153
+ elsif caret_pos < @offset_x
154
+ @offset_x = if caret_pos > @width
155
+ caret_pos + @width
156
+ else
157
+ 0
158
+ end
159
+
160
+ elsif caret_pos > @width
161
+ @offset_x = caret_pos - @width
162
+
163
+ else
164
+ # Reset to Zero
165
+ @offset_x = 0
166
+ end
167
+ end
168
+
169
+ def caret_position
170
+ text_input_position_for(:caret_pos)
171
+ end
172
+
173
+ def selection_start_position
174
+ text_input_position_for(:selection_start)
175
+ end
176
+
177
+ def text_input_position_for(method)
178
+ if @type == :password
179
+ @text.x + @text.width(default(:password_character) * @text_input.text[0...@text_input.send(method)].length)
180
+ else
181
+ @text.x + @text.width(@text_input.text[0...@text_input.send(method)])
182
+ end
183
+ end
184
+
185
+ def left_mouse_button(sender, x, y)
186
+ super
187
+ window.text_input = @text_input
188
+
189
+ @caret_last_interval = Gosu.milliseconds
190
+ @show_caret = true
191
+
192
+ move_caret_to_mouse(x, y)
193
+
194
+ :handled
195
+ end
196
+
197
+ def enter(_sender)
198
+ if @focus
199
+ @style.background_canvas.background = default(:active, :background)
200
+ @text.color = default(:active, :color)
201
+ else
202
+ @style.background_canvas.background = default(:hover, :background)
203
+ @text.color = default(:hover, :color)
204
+ end
205
+
206
+ :handled
207
+ end
208
+
209
+ def leave(sender)
210
+ super unless @focus
211
+
212
+ :handled
213
+ end
214
+
215
+ def blur(_sender)
216
+ @focus = false
217
+ @style.background_canvas.background = default(:background)
218
+ @text.color = default(:color)
219
+ window.text_input = nil
220
+
221
+ :handled
222
+ end
223
+
224
+ def draggable?(button)
225
+ button == :left
226
+ end
227
+
228
+ def begin_drag(_sender, x, _y, _button)
229
+ @drag_start = x
230
+ @offset_drag_start = @offset_x
231
+ @drag_caret_position = @text_input.caret_pos
232
+
233
+ :handled
234
+ end
235
+
236
+ def drag_update(_sender, x, _y, _button)
237
+ @text_input.caret_pos = caret_position_under_mouse(x)
238
+
239
+ :handled
240
+ end
241
+
242
+ def end_drag(_sender, _x, _y, _button)
243
+ :handled
244
+ end
245
+
246
+ def recalculate
247
+ super
248
+
249
+ @width = dimensional_size(@style.width, :width) || default(:width)
250
+ update_background
251
+ end
252
+
253
+ def value
254
+ @text_input.text
255
+ end
256
+
257
+ def value=(string)
258
+ @text_input.text = string
259
+ end
260
+ end
261
+ end
262
+ end