cyberarm_engine 0.20.0 → 0.21.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3c68b386d491e804fe89ef1148cd3a6046af34f998e7e3fdaf9e01a390f06f1
4
- data.tar.gz: 99f658599500bad421e0257b073e30581a2792410c4f3eabdbccf0348f5ecb83
3
+ metadata.gz: 7c2a84a8ea330594a18b0768f5453347a50e3c4f5e2c5a896e8f6d24f559b44f
4
+ data.tar.gz: 1c7fc5eb93f3549a8dccc1a38b810ae3d45a264096fccaae0efae8b34778ef3a
5
5
  SHA512:
6
- metadata.gz: a1a08c5926b6f2cfde243e6d920aeb4c4a0b7a0524552d45ddc6ccb662606c44ceb15f161538536aa47ea1d1c0346ef380c5469a8fb1db5e63a63ac637aeb228
7
- data.tar.gz: 05c30bec40740bc07cebb29892e94b535c53fb5439949b61684a3a4c0341df034d689c0b0dae5ae594b37023565592e7d98d3744195aab30aad88c5126940f3e
6
+ metadata.gz: db9cc74b11276ae1f7499a33d79edef4180737906a6bdc5d8d755eb63cee9fdc3cd44349ee11852e519eb9bb16788a4a9f2e46aeb1798404f6570575e76fcc73
7
+ data.tar.gz: 9e2d553ec0871db57ba78397d182aadc78cbc57d401f3dcac5386d008d9cff9254b006753fbbecec8a7931b7f08ce60010308c0c424e2f8caf27f9a3a0da53e3
@@ -0,0 +1,93 @@
1
+ module CyberarmEngine
2
+ class BackgroundImage
3
+ include CyberarmEngine::Common
4
+ attr_accessor :x, :y, :z, :mode
5
+ attr_reader :image, :width, :height, :color
6
+
7
+ def initialize(image_path: nil, x: 0, y: 0, z: 0, width: 0, height: 0, mode: :fill, color: Gosu::Color::WHITE)
8
+ @image_path = image_path
9
+ @image = get_image(image_path) if image_path
10
+
11
+ @x = x
12
+ @y = y
13
+ @z = z
14
+ @width = width
15
+ @height = height
16
+
17
+ @mode = mode
18
+
19
+ @color = color
20
+
21
+ @cached_tiling = nil
22
+ end
23
+
24
+ def image=(image_path)
25
+ @cached_tiling = nil if image_path != @image_path
26
+ @image_path = image_path
27
+ @image = image_path ? get_image(image_path) : image_path
28
+ end
29
+
30
+ def width=(n)
31
+ @cached_tiling = nil if @width != n
32
+ @width = n
33
+ end
34
+
35
+ def height=(n)
36
+ @cached_tiling = nil if @height != n
37
+ @height = n
38
+ end
39
+
40
+ def color=(c)
41
+ @cached_tiling = nil if @color != c
42
+ @color = c
43
+ end
44
+
45
+ def width_scale
46
+ (@width.to_f / @image.width).abs
47
+ end
48
+
49
+ def height_scale
50
+ (@height.to_f / @image.height).abs
51
+ end
52
+
53
+ def draw
54
+ return unless @image
55
+
56
+ Gosu.clip_to(@x, @y, @width, @height) do
57
+ send(:"draw_#{mode}")
58
+ end
59
+ end
60
+
61
+ def draw_stretch
62
+ @image.draw(@x, @y, @z, width_scale, height_scale, @color)
63
+ end
64
+
65
+ def draw_tiled
66
+ @cached_tiling ||= Gosu.record(@width, @height) do
67
+ height_scale.ceil.times do |y|
68
+ width_scale.ceil.times do |x|
69
+ @image.draw(x * @image.width, y * @image.height, @z, 1, 1, @color)
70
+ end
71
+ end
72
+ end
73
+
74
+ @cached_tiling.draw(@x, @y, @z)
75
+ end
76
+
77
+ def draw_fill
78
+ if @width * width_scale > height * height_scale
79
+ draw_fill_width
80
+ else
81
+ draw_fill_height
82
+ end
83
+ end
84
+
85
+ def draw_fill_width
86
+ @image.draw(@x, @y, @z, width_scale, width_scale, @color)
87
+ end
88
+
89
+ def draw_fill_height
90
+ @image.draw(@x, @y, @z, height_scale, height_scale, @color)
91
+ end
92
+ end
93
+ end
@@ -95,7 +95,7 @@ module CyberarmEngine
95
95
  end
96
96
 
97
97
  def window
98
- $window
98
+ CyberarmEngine::Window.instance
99
99
  end
100
100
 
101
101
  def control_down?
@@ -7,7 +7,7 @@ module CyberarmEngine
7
7
  attr_reader :alpha
8
8
 
9
9
  def initialize(options = {})
10
- $window.current_state.add_game_object(self) if options[:auto_manage] || options[:auto_manage].nil?
10
+ window.current_state.add_game_object(self) if options[:auto_manage] || options[:auto_manage].nil?
11
11
 
12
12
  @options = options
13
13
  @image = options[:image] ? image(options[:image]) : nil
@@ -55,9 +55,9 @@ module CyberarmEngine
55
55
 
56
56
  if $debug
57
57
  show_debug_heading
58
- $window.draw_circle(@position.x, @position.y, radius, 9999, @debug_color)
58
+ Gosu.draw_circle(@position.x, @position.y, radius, 9999, @debug_color)
59
59
  if @debug_text.text != ""
60
- $window.draw_rect(@debug_text.x - 10, (@debug_text.y - 10), @debug_text.width + 20, @debug_text.height + 20,
60
+ Gosu.draw_rect(@debug_text.x - 10, (@debug_text.y - 10), @debug_text.width + 20, @debug_text.height + 20,
61
61
  Gosu::Color.rgba(0, 0, 0, 200), 9999)
62
62
  @debug_text.draw
63
63
  end
@@ -102,13 +102,13 @@ module CyberarmEngine
102
102
  end
103
103
 
104
104
  def _x_visible
105
- x.between?(($window.width / 2) - @world_center_point.x, ($window.width / 2) + @world_center_point.x) ||
106
- x.between?((@world_center_point.x - $window.width / 2), ($window.width / 2) + @world_center_point.x)
105
+ x.between?((window.width / 2) - @world_center_point.x, (window.width / 2) + @world_center_point.x) ||
106
+ x.between?((@world_center_point.x - window.width / 2), (window.width / 2) + @world_center_point.x)
107
107
  end
108
108
 
109
109
  def _y_visible
110
- y.between?(($window.height / 2) - @world_center_point.y, ($window.height / 2) + @world_center_point.y) ||
111
- y.between?(@world_center_point.y - ($window.height / 2), ($window.height / 2) + @world_center_point.y)
110
+ y.between?((window.height / 2) - @world_center_point.y, (window.height / 2) + @world_center_point.y) ||
111
+ y.between?(@world_center_point.y - (window.height / 2), (window.height / 2) + @world_center_point.y)
112
112
  end
113
113
 
114
114
  def heading(ahead_by = 100, _object = nil, angle_only = false)
@@ -153,10 +153,6 @@ module CyberarmEngine
153
153
  @color = Gosu::Color.rgba(@color.red, @color.green, @color.blue, int)
154
154
  end
155
155
 
156
- def draw_rect(x, y, width, height, color, z = 0)
157
- $window.draw_rect(x, y, width, height, color, z)
158
- end
159
-
160
156
  def button_up(id)
161
157
  end
162
158
 
@@ -190,12 +186,12 @@ module CyberarmEngine
190
186
  # Duplication... so DRY.
191
187
  def each_circle_collision(object, _resolve_with = :width, &block)
192
188
  if object.class != Class && object.instance_of?(object.class)
193
- $window.current_state.game_objects.select { |i| i.instance_of?(object.class) }.each do |o|
189
+ window.current_state.game_objects.select { |i| i.instance_of?(object.class) }.each do |o|
194
190
  distance = Gosu.distance(x, y, object.x, object.y)
195
191
  block.call(o, object) if distance <= radius + object.radius && block
196
192
  end
197
193
  else
198
- list = $window.current_state.game_objects.select { |i| i.instance_of?(object) }
194
+ list = window.current_state.game_objects.select { |i| i.instance_of?(object) }
199
195
  list.each do |o|
200
196
  next if self == o
201
197
 
@@ -206,9 +202,9 @@ module CyberarmEngine
206
202
  end
207
203
 
208
204
  def destroy
209
- if $window.current_state
210
- $window.current_state.game_objects.each do |o|
211
- $window.current_state.game_objects.delete(o) if o.is_a?(self.class) && o == self
205
+ if window.current_state
206
+ window.current_state.game_objects.each do |o|
207
+ window.current_state.game_objects.delete(o) if o.is_a?(self.class) && o == self
212
208
  end
213
209
  end
214
210
  end
@@ -220,13 +216,13 @@ module CyberarmEngine
220
216
 
221
217
  def self.each_circle_collision(object, _resolve_with = :width, &block)
222
218
  if object.class != Class && object.instance_of?(object.class)
223
- $window.current_state.game_objects.select { |i| i.instance_of?(self) }.each do |o|
219
+ window.current_state.game_objects.select { |i| i.instance_of?(self) }.each do |o|
224
220
  distance = Gosu.distance(o.x, o.y, object.x, object.y)
225
221
  block.call(o, object) if distance <= o.radius + object.radius && block
226
222
  end
227
223
  else
228
- lista = $window.current_state.game_objects.select { |i| i.instance_of?(self) }
229
- listb = $window.current_state.game_objects.select { |i| i.instance_of?(object) }
224
+ lista = window.current_state.game_objects.select { |i| i.instance_of?(self) }
225
+ listb = window.current_state.game_objects.select { |i| i.instance_of?(object) }
230
226
  lista.product(listb).each do |o, o2|
231
227
  next if o == o2
232
228
 
@@ -238,9 +234,9 @@ module CyberarmEngine
238
234
 
239
235
  def self.destroy_all
240
236
  INSTANCES.clear
241
- if $window.current_state
242
- $window.current_state.game_objects.each do |o|
243
- $window.current_state.game_objects.delete(o) if o.is_a?(self.class)
237
+ if window.current_state
238
+ window.current_state.game_objects.each do |o|
239
+ window.current_state.game_objects.delete(o) if o.is_a?(self.class)
244
240
  end
245
241
  end
246
242
  end
@@ -9,7 +9,7 @@ module CyberarmEngine
9
9
  @options = options
10
10
  @game_objects = []
11
11
  @global_pause = false
12
- $window.text_input = nil unless options[:preserve_text_input]
12
+ window.text_input = nil unless options[:preserve_text_input]
13
13
 
14
14
  @down_keys = {}
15
15
  end
@@ -30,6 +30,45 @@ module CyberarmEngine
30
30
  @game_objects.each(&:update)
31
31
  end
32
32
 
33
+ def needs_redraw?
34
+ true
35
+ end
36
+
37
+ def drop(filename)
38
+ end
39
+
40
+ def gamepad_connected(index)
41
+ end
42
+
43
+ def gamepad_disconnected(index)
44
+ end
45
+
46
+ def gain_focus
47
+ end
48
+
49
+ def lose_focus
50
+ end
51
+
52
+ def button_down(id)
53
+ @down_keys[id] = true
54
+
55
+ @game_objects.each do |o|
56
+ o.button_down(id)
57
+ end
58
+ end
59
+
60
+ def button_up(id)
61
+ @down_keys.delete(id)
62
+
63
+ @game_objects.each do |o|
64
+ o.button_up(id)
65
+ end
66
+ end
67
+
68
+ def close
69
+ window.close!
70
+ end
71
+
33
72
  def draw_bounding_box(box)
34
73
  x = box.x
35
74
  y = box.y
@@ -44,25 +83,25 @@ module CyberarmEngine
44
83
  # Gosu.draw_rect(x, y, x.abs+width, y.abs+height, color, Float::INFINITY)
45
84
 
46
85
  # TOP LEFT to BOTTOM LEFT
47
- $window.draw_line(
86
+ Gosu.draw_line(
48
87
  x, y, color,
49
88
  x, max_y, color,
50
89
  Float::INFINITY
51
90
  )
52
91
  # BOTTOM LEFT to BOTTOM RIGHT
53
- $window.draw_line(
92
+ Gosu.draw_line(
54
93
  x, max_y, color,
55
94
  max_x, max_y, color,
56
95
  Float::INFINITY
57
96
  )
58
97
  # BOTTOM RIGHT to TOP RIGHT
59
- $window.draw_line(
98
+ Gosu.draw_line(
60
99
  max_x, max_y, color,
61
100
  max_x, y, color,
62
101
  Float::INFINITY
63
102
  )
64
103
  # TOP RIGHT to TOP LEFT
65
- $window.draw_line(
104
+ Gosu.draw_line(
66
105
  max_x, y, color,
67
106
  x, y, color,
68
107
  Float::INFINITY
@@ -74,22 +113,6 @@ module CyberarmEngine
74
113
  @game_objects.clear
75
114
  end
76
115
 
77
- def button_down(id)
78
- @down_keys[id] = true
79
-
80
- @game_objects.each do |o|
81
- o.button_down(id)
82
- end
83
- end
84
-
85
- def button_up(id)
86
- @down_keys.delete(id)
87
-
88
- @game_objects.each do |o|
89
- o.button_up(id)
90
- end
91
- end
92
-
93
116
  def add_game_object(object)
94
117
  @game_objects << object
95
118
  end
@@ -4,7 +4,7 @@ module CyberarmEngine
4
4
 
5
5
  def initialize
6
6
  @bounding_box_renderer = BoundingBoxRenderer.new
7
- @opengl_renderer = OpenGLRenderer.new(width: $window.width, height: $window.height)
7
+ @opengl_renderer = OpenGLRenderer.new(width: CyberarmEngine::Window.instance.width, height: CyberarmEngine::Window.instance.height)
8
8
  end
9
9
 
10
10
  def draw(camera, lights, entities)
@@ -43,9 +43,9 @@ module CyberarmEngine
43
43
  when :left
44
44
  @x = 0 + BUTTON_PADDING
45
45
  when :center
46
- @x = ($window.width / 2) - (@textobject.text_width(@text) / 2)
46
+ @x = (CyberarmEngine::Window.instance.width / 2) - (@textobject.text_width(@text) / 2)
47
47
  when :right
48
- @x = $window.width - BUTTON_PADDING - @textobject.text_width(@text)
48
+ @x = CyberarmEngine::Window.instance.width - BUTTON_PADDING - @textobject.text_width(@text)
49
49
  end
50
50
  end
51
51
  end
@@ -116,7 +116,7 @@ module CyberarmEngine
116
116
  end
117
117
 
118
118
  private def element_parent
119
- $__current_container__
119
+ CyberarmEngine::Element::Container.current_container
120
120
  end
121
121
 
122
122
  private def container(klass, options = {}, &block)
@@ -126,12 +126,12 @@ module CyberarmEngine
126
126
  _container = klass.new(options, block)
127
127
 
128
128
  old_parent = element_parent
129
- $__current_container__ = _container
129
+ CyberarmEngine::Element::Container.current_container = _container
130
130
 
131
131
  _container.build
132
132
  _container.parent.add(_container)
133
133
 
134
- $__current_container__ = old_parent
134
+ CyberarmEngine::Element::Container.current_container = old_parent
135
135
 
136
136
  _container
137
137
  end
@@ -38,6 +38,7 @@ module CyberarmEngine
38
38
 
39
39
  @style.background_canvas = Background.new
40
40
  @style.background_nine_slice_canvas = BackgroundNineSlice.new
41
+ @style.background_image_canvas = BackgroundImage.new
41
42
  @style.border_canvas = BorderCanvas.new(element: self)
42
43
 
43
44
  @style_event = :default
@@ -60,6 +61,7 @@ module CyberarmEngine
60
61
 
61
62
  set_background
62
63
  set_background_nine_slice
64
+ set_background_image
63
65
 
64
66
  set_border_thickness
65
67
  set_border_color
@@ -104,6 +106,14 @@ module CyberarmEngine
104
106
  @style.background_nine_slice_bottom = safe_style_fetch(:background_nine_slice_bottom) || @style.background_nine_slice_from_edge
105
107
  end
106
108
 
109
+ def set_background_image
110
+ @style.background_image = safe_style_fetch(:background_image)
111
+ @style.background_image_mode = safe_style_fetch(:background_image_mode) || :stretch
112
+ @style.background_image_color = safe_style_fetch(:background_image_color) || Gosu::Color::WHITE
113
+ @style.background_image_canvas.mode = @style.background_image_mode
114
+ @style.background_image_canvas.color = @style.background_image_color
115
+ end
116
+
107
117
  def set_border_thickness
108
118
  @style.border_thickness = safe_style_fetch(:border_thickness)
109
119
 
@@ -288,6 +298,7 @@ module CyberarmEngine
288
298
 
289
299
  @style.background_canvas.draw
290
300
  @style.background_nine_slice_canvas.draw
301
+ @style.background_image_canvas.draw
291
302
  @style.border_canvas.draw
292
303
 
293
304
  render
@@ -429,11 +440,34 @@ module CyberarmEngine
429
440
  def dimensional_size(size, dimension)
430
441
  raise "dimension must be either :width or :height" unless %i[width height].include?(dimension)
431
442
 
432
- if size.is_a?(Numeric) && size.between?(0.0, 1.0)
433
- (@parent.send(:"content_#{dimension}") * size).round - send(:"noncontent_#{dimension}").round
443
+ new_size = if size.is_a?(Numeric) && size.between?(0.0, 1.0)
444
+ (@parent.send(:"content_#{dimension}") * size).floor - send(:"noncontent_#{dimension}").floor
434
445
  else
435
446
  size
436
447
  end
448
+
449
+ if @parent && @style.fill # Handle fill behavior
450
+ fill_siblings = @parent.children.select { |c| c.style.fill }.count.to_f # include self since we're dividing
451
+
452
+ if dimension == :width && @parent.is_a?(Flow)
453
+ space_available_width = ((@parent.content_width - (@parent.children.reject { |c| c.style.fill }).map(&:outer_width).sum) / fill_siblings)
454
+ space_available_width = space_available_width.nan? ? 0 : space_available_width.floor # The parent element might not have its dimensions, yet.
455
+
456
+ return space_available_width - noncontent_width
457
+
458
+ elsif dimension == :height && @parent.is_a?(Stack)
459
+ space_available_height = ((@parent.content_height - (@parent.children.reject { |c| c.style.fill }).map(&:outer_height).sum) / fill_siblings)
460
+ space_available_height = space_available_height.nan? ? 0 : space_available_height.floor # The parent element might not have its dimensions, yet.
461
+
462
+ return space_available_height - noncontent_height
463
+ end
464
+
465
+ else # Handle min_width/height and max_width/height
466
+ return @style.send(:"min_#{dimension}") if @style.send(:"min_#{dimension}") && new_size < @style.send(:"min_#{dimension}")
467
+ return @style.send(:"max_#{dimension}") if @style.send(:"max_#{dimension}") && new_size > @style.send(:"max_#{dimension}")
468
+ end
469
+
470
+ new_size
437
471
  end
438
472
 
439
473
  def background=(_background)
@@ -450,6 +484,7 @@ module CyberarmEngine
450
484
 
451
485
  @style.background_canvas.update
452
486
  update_background_nine_slice
487
+ update_background_image
453
488
  @style.border_canvas.update
454
489
  end
455
490
 
@@ -477,6 +512,24 @@ module CyberarmEngine
477
512
  @style.background_nine_slice_canvas.image = @style.background_nine_slice
478
513
  end
479
514
 
515
+ def background_image=(image_path)
516
+ @style.background_image = image_path.is_a?(Gosu::Image) ? image_path : get_image(image_path)
517
+ update_background_image
518
+ end
519
+
520
+ def update_background_image
521
+ @style.background_image_canvas.x = @x
522
+ @style.background_image_canvas.y = @y
523
+ @style.background_image_canvas.z = @z
524
+ @style.background_image_canvas.width = width
525
+ @style.background_image_canvas.height = height
526
+
527
+ @style.background_image_canvas.mode = @style.background_image_mode
528
+ @style.background_image_canvas.color = @style.background_image_color
529
+
530
+ @style.background_image_canvas.image = @style.background_image
531
+ end
532
+
480
533
  def root
481
534
  return self if is_root?
482
535
 
@@ -64,8 +64,8 @@ module CyberarmEngine
64
64
  @scale_y = 1
65
65
  end
66
66
 
67
- @width = _width || @image.width.round * @scale_x
68
- @height = _height || @image.height.round * @scale_y
67
+ @width = _width || @image.width.floor * @scale_x
68
+ @height = _height || @image.height.floor * @scale_y
69
69
 
70
70
  update_background
71
71
  else
@@ -6,6 +6,16 @@ module CyberarmEngine
6
6
  attr_accessor :stroke_color, :fill_color
7
7
  attr_reader :children, :gui_state, :scroll_position
8
8
 
9
+ def self.current_container
10
+ @@current_container
11
+ end
12
+
13
+ def self.current_container=(container)
14
+ raise ArgumentError, "Expected container to an an instance of CyberarmEngine::Element::Container, got #{container.class}" unless container.is_a?(CyberarmEngine::Element::Container)
15
+
16
+ @@current_container = container
17
+ end
18
+
9
19
  def initialize(options = {}, block = nil)
10
20
  @gui_state = options.delete(:gui_state)
11
21
  super
@@ -35,23 +45,23 @@ module CyberarmEngine
35
45
  def clear(&block)
36
46
  @children.clear
37
47
 
38
- old_container = $__current_container__
48
+ old_container = CyberarmEngine::Element::Container.current_container
39
49
 
40
- $__current_container__ = self
50
+ CyberarmEngine::Element::Container.current_container = self
41
51
  block.call(self) if block
42
52
 
43
- $__current_container__ = old_container
53
+ CyberarmEngine::Element::Container.current_container = old_container
44
54
 
45
55
  root.gui_state.request_recalculate
46
56
  end
47
57
 
48
58
  def append(&block)
49
- old_container = $__current_container__
59
+ old_container = CyberarmEngine::Element::Container.current_container
50
60
 
51
- $__current_container__ = self
61
+ CyberarmEngine::Element::Container.current_container = self
52
62
  block.call(self) if block
53
63
 
54
- $__current_container__ = old_container
64
+ CyberarmEngine::Element::Container.current_container = old_container
55
65
 
56
66
  root.gui_state.request_recalculate
57
67
  end
@@ -122,8 +132,8 @@ module CyberarmEngine
122
132
  _width = dimensional_size(@style.width, :width)
123
133
  _height = dimensional_size(@style.height, :height)
124
134
 
125
- @width = _width || (@children.map { |c| c.x + c.outer_width }.max || 0).round
126
- @height = _height || (@children.map { |c| c.y + c.outer_height }.max || 0).round
135
+ @width = _width || (@children.map { |c| c.x + c.outer_width }.max || 0).floor
136
+ @height = _height || (@children.map { |c| c.y + c.outer_height }.max || 0).floor
127
137
  end
128
138
 
129
139
  # Move child to parent after positioning
@@ -151,12 +161,14 @@ module CyberarmEngine
151
161
  end
152
162
 
153
163
  def max_width
154
- _width = dimensional_size(@style.width, :width)
155
- if _width
156
- outer_width
157
- else
158
- window.width - (@parent ? @parent.style.margin_right + @style.margin_right : @style.margin_right)
159
- end
164
+ # _width = dimensional_size(@style.width, :width)
165
+ # if _width
166
+ # outer_width
167
+ # else
168
+ # window.width - (@parent ? @parent.style.margin_right + @style.margin_right : @style.margin_right)
169
+ # end
170
+
171
+ outer_width
160
172
  end
161
173
 
162
174
  def fits_on_line?(element) # Flow
@@ -98,7 +98,7 @@ module CyberarmEngine
98
98
  end
99
99
 
100
100
  def row_at(y)
101
- ((y - @text.y) / @text.textobject.height).round
101
+ ((y - @text.y) / @text.textobject.height).floor
102
102
  end
103
103
 
104
104
  def column_at(x, y)
@@ -45,8 +45,8 @@ module CyberarmEngine
45
45
  @scale_y = 1
46
46
  end
47
47
 
48
- @width = _width || @image.width.round * @scale_x
49
- @height = _height || @image.height.round * @scale_y
48
+ @width = _width || @image.width.floor * @scale_x
49
+ @height = _height || @image.height.floor * @scale_y
50
50
 
51
51
  update_background
52
52
  end
@@ -17,6 +17,8 @@ module CyberarmEngine
17
17
  @menu.define_singleton_method(:recalculate_menu) do
18
18
  @x = @__list_box.x
19
19
  @y = @__list_box.y + @__list_box.height
20
+
21
+ @y = @__list_box.y - height if @y + height > window.height
20
22
  end
21
23
  @menu.instance_variable_set(:"@__list_box", self)
22
24
 
@@ -29,6 +31,13 @@ module CyberarmEngine
29
31
  self.choose = @choose
30
32
  end
31
33
 
34
+ def render
35
+ super
36
+
37
+ w = @text.textobject.text_width("▼")
38
+ @text.textobject.draw_text("▼", @x + content_width - w, @y + @style.padding_top, @z, 1, 1, @text.color)
39
+ end
40
+
32
41
  def choose=(item)
33
42
  valid = @items.detect { |i| i == item }
34
43
  raise "Invalid value '#{item}' for choose, valid options were: #{@items.map { |i| "#{i.inspect}" }.join(", ")}" unless valid
@@ -18,7 +18,14 @@ module CyberarmEngine
18
18
  end
19
19
 
20
20
  def render
21
- @text.draw
21
+ # Gosu.clip_to is too expensive to always use so check if we actually need it.
22
+ if @text.width > width || @text.height > height
23
+ Gosu.clip_to(@x, @y, width, height) do
24
+ @text.draw
25
+ end
26
+ else
27
+ @text.draw
28
+ end
22
29
  end
23
30
 
24
31
  def recalculate
@@ -36,8 +43,8 @@ module CyberarmEngine
36
43
 
37
44
  handle_text_wrapping(_width)
38
45
 
39
- @width = _width || @text.width.round
40
- @height = _height || @text.height.round
46
+ @width = _width || @text.width.floor
47
+ @height = _height || @text.height.floor
41
48
 
42
49
  @text.y = @style.border_thickness_top + @style.padding_top + @y
43
50
  @text.z = @z + 3
@@ -12,7 +12,7 @@ module CyberarmEngine
12
12
 
13
13
  @root_container = Element::Stack.new(gui_state: self)
14
14
  @game_objects << @root_container
15
- $__current_container__ = @root_container
15
+ CyberarmEngine::Element::Container.current_container = @root_container
16
16
 
17
17
  @active_width = window.width
18
18
  @active_height = window.height
@@ -90,6 +90,8 @@ module CyberarmEngine
90
90
  @menu&.update
91
91
  super
92
92
 
93
+ return unless window.has_focus?
94
+
93
95
  new_mouse_over = @menu.hit_element?(window.mouse_x, window.mouse_y) if @menu
94
96
  new_mouse_over ||= @root_container.hit_element?(window.mouse_x, window.mouse_y)
95
97
 
@@ -135,10 +137,6 @@ module CyberarmEngine
135
137
  @active_height = window.height
136
138
  end
137
139
 
138
- def tool_tip_delay
139
- 250 # ms
140
- end
141
-
142
140
  def button_down(id)
143
141
  super
144
142
 
@@ -175,6 +173,10 @@ module CyberarmEngine
175
173
  @focus.button_up(id) if @focus.respond_to?(:button_up)
176
174
  end
177
175
 
176
+ def tool_tip_delay
177
+ @tip.style.delay || 250 # ms
178
+ end
179
+
178
180
  def redirect_mouse_button(button)
179
181
  hide_menu unless @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
180
182
 
@@ -154,6 +154,7 @@ module CyberarmEngine
154
154
  },
155
155
 
156
156
  ToolTip: { # < TextBlock
157
+ delay: 100, # ms
157
158
  color: Gosu::Color::WHITE,
158
159
  padding_top: 4,
159
160
  padding_bottom: 4,
@@ -1,4 +1,4 @@
1
1
  module CyberarmEngine
2
2
  NAME = "InDev".freeze
3
- VERSION = "0.20.0".freeze
3
+ VERSION = "0.21.0".freeze
4
4
  end
@@ -8,21 +8,33 @@ module CyberarmEngine
8
8
 
9
9
  attr_accessor :show_cursor
10
10
  attr_writer :exit_on_opengl_error
11
- attr_reader :last_frame_time
11
+ attr_reader :last_frame_time, :states
12
12
 
13
13
  def self.now
14
14
  Gosu.milliseconds
15
15
  end
16
16
 
17
17
  def self.dt
18
- $window.last_frame_time / 1000.0
18
+ instance.last_frame_time / 1000.0
19
+ end
20
+
21
+ def self.instance=(window)
22
+ raise ArgumentError, "Expected window to be a subclass of CyberarmEngine::Window, got: #{window.class}" unless window.is_a?(CyberarmEngine::Window)
23
+
24
+ @@instance = window
25
+ end
26
+
27
+ def self.instance
28
+ @@instance
19
29
  end
20
30
 
21
31
  def initialize(width: 800, height: 600, fullscreen: false, update_interval: 1000.0 / 60, resizable: false, borderless: false)
22
32
  @show_cursor = false
33
+ @has_focus = false
23
34
 
24
35
  super(width, height, fullscreen: fullscreen, update_interval: update_interval, resizable: resizable, borderless: borderless)
25
- $window = self
36
+ Window.instance = self
37
+
26
38
  @last_frame_time = Gosu.milliseconds - 1
27
39
  @current_frame_time = Gosu.milliseconds
28
40
  self.caption = "CyberarmEngine #{CyberarmEngine::VERSION} #{Gosu.language}"
@@ -34,13 +46,14 @@ module CyberarmEngine
34
46
  end
35
47
 
36
48
  def draw
37
- current_state.draw if current_state
49
+ current_state&.draw
38
50
  end
39
51
 
40
52
  def update
41
53
  Stats.clear
42
54
 
43
- current_state.update if current_state
55
+ current_state&.update
56
+
44
57
  @last_frame_time = Gosu.milliseconds - @current_frame_time
45
58
  @current_frame_time = Gosu.milliseconds
46
59
  end
@@ -49,26 +62,58 @@ module CyberarmEngine
49
62
  @show_cursor
50
63
  end
51
64
 
52
- def dt
53
- @last_frame_time / 1000.0
65
+ def needs_redraw?
66
+ current_state ? current_state.needs_redraw? : true
54
67
  end
55
68
 
56
- def aspect_ratio
57
- width / height.to_f
69
+ def drop(filename)
70
+ current_state&.drop(filename)
58
71
  end
59
72
 
60
- def exit_on_opengl_error?
61
- @exit_on_opengl_error
73
+ def gamepad_connected(index)
74
+ current_state&.gamepad_connected(index)
75
+ end
76
+
77
+ def gamepad_disconnected(index)
78
+ current_state&.gamepad_disconnected(index)
79
+ end
80
+
81
+ def gain_focus
82
+ @has_focus = true
83
+
84
+ current_state&.gain_focus
85
+ end
86
+
87
+ def lose_focus
88
+ @has_focus = false
89
+
90
+ current_state&.lose_focus
62
91
  end
63
92
 
64
93
  def button_down(id)
65
94
  super
66
- current_state.button_down(id) if current_state
95
+ current_state&.button_down(id)
67
96
  end
68
97
 
69
98
  def button_up(id)
70
99
  super
71
- current_state.button_up(id) if current_state
100
+ current_state&.button_up(id)
101
+ end
102
+
103
+ def close
104
+ current_state ? current_state.close : super
105
+ end
106
+
107
+ def dt
108
+ @last_frame_time / 1000.0
109
+ end
110
+
111
+ def aspect_ratio
112
+ width / height.to_f
113
+ end
114
+
115
+ def exit_on_opengl_error?
116
+ @exit_on_opengl_error
72
117
  end
73
118
 
74
119
  def push_state(klass, options = {})
@@ -108,6 +153,10 @@ module CyberarmEngine
108
153
  @states.shift
109
154
  end
110
155
 
156
+ def has_focus?
157
+ @has_focus
158
+ end
159
+
111
160
  # Sourced from https://gist.github.com/ippa/662583
112
161
  def draw_circle(cx, cy, r, z = 9999, color = Gosu::Color::GREEN, step = 10)
113
162
  0.step(360, step) do |a1|
@@ -24,6 +24,7 @@ require_relative "cyberarm_engine/transform"
24
24
  require_relative "cyberarm_engine/ray"
25
25
  require_relative "cyberarm_engine/background"
26
26
  require_relative "cyberarm_engine/background_nine_slice"
27
+ require_relative "cyberarm_engine/background_image"
27
28
  require_relative "cyberarm_engine/animator"
28
29
 
29
30
  require_relative "cyberarm_engine/text"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cyberarm_engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.0
4
+ version: 0.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyberarm
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-05 00:00:00.000000000 Z
11
+ date: 2022-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clipboard
@@ -130,6 +130,7 @@ files:
130
130
  - lib/cyberarm_engine.rb
131
131
  - lib/cyberarm_engine/animator.rb
132
132
  - lib/cyberarm_engine/background.rb
133
+ - lib/cyberarm_engine/background_image.rb
133
134
  - lib/cyberarm_engine/background_nine_slice.rb
134
135
  - lib/cyberarm_engine/bounding_box.rb
135
136
  - lib/cyberarm_engine/builtin/intro_state.rb
@@ -210,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
210
211
  - !ruby/object:Gem::Version
211
212
  version: '0'
212
213
  requirements: []
213
- rubygems_version: 3.2.28
214
+ rubygems_version: 3.3.7
214
215
  signing_key:
215
216
  specification_version: 4
216
217
  summary: Make games quickly and easily with gosu