cyberarm_engine 0.25.0 → 0.30.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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -8
  3. data/.rubocop.yml +7 -7
  4. data/.travis.yml +5 -5
  5. data/Gemfile +6 -6
  6. data/Gemfile.lock +37 -25
  7. data/LICENSE.txt +21 -21
  8. data/README.md +74 -74
  9. data/Rakefile +10 -10
  10. data/assets/shaders/fragment/g_buffer.glsl +30 -30
  11. data/assets/shaders/fragment/lighting.glsl +115 -115
  12. data/assets/shaders/include/light_struct.glsl +11 -11
  13. data/assets/shaders/include/material_struct.glsl +16 -16
  14. data/assets/shaders/vertex/g_buffer.glsl +28 -28
  15. data/assets/shaders/vertex/lighting.glsl +24 -24
  16. data/assets/textures/ui/circle.png +0 -0
  17. data/assets/textures/ui/circle_small.png +0 -0
  18. data/assets/textures/ui/rounded.png +0 -0
  19. data/assets/textures/ui/rounded_bottom.png +0 -0
  20. data/assets/textures/ui/rounded_left.png +0 -0
  21. data/assets/textures/ui/rounded_left_bottom.png +0 -0
  22. data/assets/textures/ui/rounded_left_top.png +0 -0
  23. data/assets/textures/ui/rounded_right.png +0 -0
  24. data/assets/textures/ui/rounded_right_bottom.png +0 -0
  25. data/assets/textures/ui/rounded_right_top.png +0 -0
  26. data/assets/textures/ui/rounded_small.png +0 -0
  27. data/assets/textures/ui/rounded_tiny.png +0 -0
  28. data/assets/textures/ui/rounded_top.png +0 -0
  29. data/assets/textures/ui/square.png +0 -0
  30. data/bin/console +14 -14
  31. data/bin/setup +8 -8
  32. data/cyberarm_engine.gemspec +35 -36
  33. data/lib/cyberarm_engine/animator.rb +219 -219
  34. data/lib/cyberarm_engine/background.rb +156 -158
  35. data/lib/cyberarm_engine/background_image.rb +93 -93
  36. data/lib/cyberarm_engine/background_nine_slice.rb +182 -142
  37. data/lib/cyberarm_engine/bounding_box.rb +150 -150
  38. data/lib/cyberarm_engine/builtin/intro_state.rb +130 -130
  39. data/lib/cyberarm_engine/cache/download_manager.rb +123 -123
  40. data/lib/cyberarm_engine/cache.rb +4 -4
  41. data/lib/cyberarm_engine/common.rb +133 -131
  42. data/lib/cyberarm_engine/config_file.rb +46 -46
  43. data/lib/cyberarm_engine/console/command.rb +157 -157
  44. data/lib/cyberarm_engine/console/commands/help_command.rb +43 -43
  45. data/lib/cyberarm_engine/console/subcommand.rb +99 -99
  46. data/lib/cyberarm_engine/console.rb +248 -248
  47. data/lib/cyberarm_engine/event_bus.rb +39 -0
  48. data/lib/cyberarm_engine/game_object.rb +244 -244
  49. data/lib/cyberarm_engine/game_state.rb +134 -124
  50. data/lib/cyberarm_engine/gosu_ext/draw_arc.rb +111 -111
  51. data/lib/cyberarm_engine/gosu_ext/draw_circle.rb +30 -30
  52. data/lib/cyberarm_engine/gosu_ext/draw_path.rb +17 -17
  53. data/lib/cyberarm_engine/model/material.rb +21 -21
  54. data/lib/cyberarm_engine/model/mesh.rb +131 -131
  55. data/lib/cyberarm_engine/model/parser.rb +74 -74
  56. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -138
  57. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -154
  58. data/lib/cyberarm_engine/model.rb +216 -216
  59. data/lib/cyberarm_engine/model_cache.rb +31 -31
  60. data/lib/cyberarm_engine/notification.rb +82 -82
  61. data/lib/cyberarm_engine/notification_manager.rb +241 -241
  62. data/lib/cyberarm_engine/opengl/light.rb +52 -52
  63. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -46
  64. data/lib/cyberarm_engine/opengl/perspective_camera.rb +41 -41
  65. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -249
  66. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +167 -167
  67. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +307 -307
  68. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +33 -33
  69. data/lib/cyberarm_engine/opengl/shader.rb +408 -408
  70. data/lib/cyberarm_engine/opengl/texture.rb +69 -69
  71. data/lib/cyberarm_engine/opengl.rb +53 -53
  72. data/lib/cyberarm_engine/pathfinding/graph.rb +64 -0
  73. data/lib/cyberarm_engine/pathfinding/graph_search.rb +6 -0
  74. data/lib/cyberarm_engine/pathfinding/graph_searches/astar_search.rb +6 -0
  75. data/lib/cyberarm_engine/pathfinding/graph_searches/breadth_first_search.rb +27 -0
  76. data/lib/cyberarm_engine/pathfinding/graph_searches/dijkstra_search.rb +6 -0
  77. data/lib/cyberarm_engine/pathfinding/graphs/grid.rb +52 -0
  78. data/lib/cyberarm_engine/ray.rb +56 -56
  79. data/lib/cyberarm_engine/result.rb +19 -0
  80. data/lib/cyberarm_engine/stats.rb +200 -200
  81. data/lib/cyberarm_engine/text.rb +288 -260
  82. data/lib/cyberarm_engine/timer.rb +27 -23
  83. data/lib/cyberarm_engine/transform.rb +296 -296
  84. data/lib/cyberarm_engine/trees/aabb_node.rb +126 -126
  85. data/lib/cyberarm_engine/trees/aabb_tree.rb +55 -55
  86. data/lib/cyberarm_engine/trees/aabb_tree_debug.rb +29 -29
  87. data/lib/cyberarm_engine/ui/border_canvas.rb +102 -102
  88. data/lib/cyberarm_engine/ui/dialog.rb +24 -0
  89. data/lib/cyberarm_engine/ui/dsl.rb +170 -142
  90. data/lib/cyberarm_engine/ui/element.rb +664 -662
  91. data/lib/cyberarm_engine/ui/elements/button.rb +99 -100
  92. data/lib/cyberarm_engine/ui/elements/check_box.rb +58 -54
  93. data/lib/cyberarm_engine/ui/elements/container.rb +413 -407
  94. data/lib/cyberarm_engine/ui/elements/edit_box.rb +200 -179
  95. data/lib/cyberarm_engine/ui/elements/edit_line.rb +299 -297
  96. data/lib/cyberarm_engine/ui/elements/flow.rb +15 -15
  97. data/lib/cyberarm_engine/ui/elements/image.rb +78 -72
  98. data/lib/cyberarm_engine/ui/elements/list_box.rb +79 -79
  99. data/lib/cyberarm_engine/ui/elements/menu.rb +27 -27
  100. data/lib/cyberarm_engine/ui/elements/menu_item.rb +6 -6
  101. data/lib/cyberarm_engine/ui/elements/progress.rb +95 -93
  102. data/lib/cyberarm_engine/ui/elements/radio.rb +6 -6
  103. data/lib/cyberarm_engine/ui/elements/slider.rb +111 -107
  104. data/lib/cyberarm_engine/ui/elements/stack.rb +11 -11
  105. data/lib/cyberarm_engine/ui/elements/text_block.rb +236 -222
  106. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +71 -67
  107. data/lib/cyberarm_engine/ui/elements/widget.rb +45 -0
  108. data/lib/cyberarm_engine/ui/event.rb +54 -54
  109. data/lib/cyberarm_engine/ui/gui_state.rb +402 -326
  110. data/lib/cyberarm_engine/ui/page.rb +39 -0
  111. data/lib/cyberarm_engine/ui/style.rb +94 -61
  112. data/lib/cyberarm_engine/ui/theme.rb +237 -225
  113. data/lib/cyberarm_engine/vector.rb +312 -312
  114. data/lib/cyberarm_engine/version.rb +4 -4
  115. data/lib/cyberarm_engine/window.rb +234 -195
  116. data/lib/cyberarm_engine.rb +88 -76
  117. data/mrbgem.rake +29 -29
  118. metadata +30 -5
@@ -1,244 +1,244 @@
1
- module CyberarmEngine
2
- class GameObject
3
- include Common
4
-
5
- attr_accessor :image, :angle, :position, :velocity, :center_x, :center_y, :scale_x, :scale_y,
6
- :color, :mode, :options, :paused, :radius, :last_position
7
- attr_reader :alpha
8
-
9
- def initialize(options = {})
10
- window.current_state.add_game_object(self) if options[:auto_manage] || options[:auto_manage].nil?
11
-
12
- @options = options
13
- @image = options[:image] ? image(options[:image]) : nil
14
- x = options[:x] || 0
15
- y = options[:y] || 0
16
- z = options[:z] || 0
17
- @position = Vector.new(x, y, z)
18
- @velocity = Vector.new
19
- @last_position = Vector.new
20
- @angle = options[:angle] || 0
21
-
22
- @center_x = options[:center_x] || 0.5
23
- @center_y = options[:center_y] || 0.5
24
-
25
- @scale_x = options[:scale_x] || 1
26
- @scale_y = options[:scale_y] || 1
27
-
28
- @color = options[:color] || Gosu::Color.argb(0xff_ffffff)
29
- @alpha = options[:alpha] || 255
30
- @mode = options[:mode] || :default
31
-
32
- @paused = false
33
- @speed = 0
34
- @debug_color = Gosu::Color::GREEN
35
- @world_center_point = Vector.new(0, 0)
36
-
37
- setup
38
-
39
- @debug_text = Text.new("", color: @debug_color, y: @position.y - (height * scale), z: 9999)
40
- @debug_text.x = @position.x
41
- if @radius == 0 || @radius.nil?
42
- @radius = if options[:radius]
43
- options[:radius]
44
- else
45
- @image.respond_to?(:width) ? ((@image.width + @image.height) / 4) * scale : 1
46
- end
47
- end
48
- end
49
-
50
- def draw
51
- if @image
52
- @image.draw_rot(@position.x, @position.y, @position.z, @angle, @center_x, @center_y, @scale_x, @scale_y,
53
- @color, @mode)
54
- end
55
-
56
- if $debug
57
- show_debug_heading
58
- Gosu.draw_circle(@position.x, @position.y, radius, 9999, @debug_color)
59
- if @debug_text.text != ""
60
- Gosu.draw_rect(@debug_text.x - 10, (@debug_text.y - 10), @debug_text.width + 20, @debug_text.height + 20,
61
- Gosu::Color.rgba(0, 0, 0, 200), 9999)
62
- @debug_text.draw
63
- end
64
- end
65
- end
66
-
67
- def update
68
- end
69
-
70
- def debug_text(text)
71
- @debug_text.text = text
72
- @debug_text.x = @position.x - (@debug_text.width / 2)
73
- @debug_text.y = @position.y - (@debug_text.height + radius + height)
74
- end
75
-
76
- def scale
77
- if @scale_x == @scale_y
78
- @scale_x
79
- else
80
- false
81
- # maths?
82
- end
83
- end
84
-
85
- def scale=(int)
86
- self.scale_x = int
87
- self.scale_y = int
88
- self.radius = ((@image.width + @image.height) / 4) * scale
89
- end
90
-
91
- def visible
92
- true
93
- # if _x_visible
94
- # if _y_visible
95
- # true
96
- # else
97
- # false
98
- # end
99
- # else
100
- # false
101
- # end
102
- end
103
-
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)
107
- end
108
-
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)
112
- end
113
-
114
- def heading(ahead_by = 100, _object = nil, angle_only = false)
115
- direction = Gosu.angle(@last_position.x, @last_position.x, @position.x, position.y).gosu_to_radians
116
-
117
- _x = @position.x + (ahead_by * Math.cos(direction))
118
- _y = @position.y + (ahead_by * Math.sin(direction))
119
-
120
- return direction if angle_only
121
- return Vector.new(_x, _y) unless angle_only
122
- end
123
-
124
- def show_debug_heading
125
- _heading = heading
126
- Gosu.draw_line(@position.x, @position.y, @debug_color, _heading.x, _heading.y, @debug_color, 9999)
127
- end
128
-
129
- def width
130
- @image ? @image.width * scale : 0
131
- end
132
-
133
- def height
134
- @image ? @image.height * scale : 0
135
- end
136
-
137
- def pause
138
- @paused = true
139
- end
140
-
141
- def unpause
142
- @paused = false
143
- end
144
-
145
- def rotate(int)
146
- self.angle += int
147
- self.angle %= 360
148
- end
149
-
150
- def alpha=(int) # 0-255
151
- @alpha = int
152
- @alpha = 255 if @alpha > 255
153
- @color = Gosu::Color.rgba(@color.red, @color.green, @color.blue, int)
154
- end
155
-
156
- def button_up(id)
157
- end
158
-
159
- def button_down(id)
160
- end
161
-
162
- def find_closest(game_object_class)
163
- best_object = nil
164
- best_distance = 100_000_000_000 # Huge default number
165
-
166
- game_object_class.all.each do |object|
167
- distance = Gosu.distance(x, y, object.x, object.y)
168
- if distance <= best_distance
169
- best_object = object
170
- best_distance = distance
171
- end
172
- end
173
-
174
- best_object
175
- end
176
-
177
- def look_at(object)
178
- # TODO: Implement
179
- end
180
-
181
- def circle_collision?(object)
182
- distance = Gosu.distance(x, y, object.x, object.y)
183
- distance <= radius + object.radius
184
- end
185
-
186
- # Duplication... so DRY.
187
- def each_circle_collision(object, _resolve_with = :width, &block)
188
- if object.class != Class && object.instance_of?(object.class)
189
- window.current_state.game_objects.select { |i| i.instance_of?(object.class) }.each do |o|
190
- distance = Gosu.distance(x, y, object.x, object.y)
191
- block.call(o, object) if distance <= radius + object.radius && block
192
- end
193
- else
194
- list = window.current_state.game_objects.select { |i| i.instance_of?(object) }
195
- list.each do |o|
196
- next if self == o
197
-
198
- distance = Gosu.distance(x, y, o.x, o.y)
199
- block.call(self, o) if distance <= radius + o.radius && block
200
- end
201
- end
202
- end
203
-
204
- def destroy
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
208
- end
209
- end
210
- end
211
-
212
- # NOTE: This could be implemented more reliably
213
- def all
214
- INSTANCES.select { |i| i.instance_of?(self) }
215
- end
216
-
217
- def self.each_circle_collision(object, _resolve_with = :width, &block)
218
- if object.class != Class && object.instance_of?(object.class)
219
- window.current_state.game_objects.select { |i| i.instance_of?(self) }.each do |o|
220
- distance = Gosu.distance(o.x, o.y, object.x, object.y)
221
- block.call(o, object) if distance <= o.radius + object.radius && block
222
- end
223
- else
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) }
226
- lista.product(listb).each do |o, o2|
227
- next if o == o2
228
-
229
- distance = Gosu.distance(o.x, o.y, o2.x, o2.y)
230
- block.call(o, o2) if distance <= o.radius + o2.radius && block
231
- end
232
- end
233
- end
234
-
235
- def self.destroy_all
236
- INSTANCES.clear
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)
240
- end
241
- end
242
- end
243
- end
244
- end
1
+ module CyberarmEngine
2
+ class GameObject
3
+ include Common
4
+
5
+ attr_accessor :image, :angle, :position, :velocity, :center_x, :center_y, :scale_x, :scale_y,
6
+ :color, :mode, :options, :paused, :radius, :last_position
7
+ attr_reader :alpha
8
+
9
+ def initialize(options = {})
10
+ window.current_state.add_game_object(self) if options[:auto_manage] || options[:auto_manage].nil?
11
+
12
+ @options = options
13
+ @image = options[:image] ? image(options[:image]) : nil
14
+ x = options[:x] || 0
15
+ y = options[:y] || 0
16
+ z = options[:z] || 0
17
+ @position = Vector.new(x, y, z)
18
+ @velocity = Vector.new
19
+ @last_position = Vector.new
20
+ @angle = options[:angle] || 0
21
+
22
+ @center_x = options[:center_x] || 0.5
23
+ @center_y = options[:center_y] || 0.5
24
+
25
+ @scale_x = options[:scale_x] || 1
26
+ @scale_y = options[:scale_y] || 1
27
+
28
+ @color = options[:color] || Gosu::Color.argb(0xff_ffffff)
29
+ @alpha = options[:alpha] || 255
30
+ @mode = options[:mode] || :default
31
+
32
+ @paused = false
33
+ @speed = 0
34
+ @debug_color = Gosu::Color::GREEN
35
+ @world_center_point = Vector.new(0, 0)
36
+
37
+ setup
38
+
39
+ @debug_text = Text.new("", color: @debug_color, y: @position.y - (height * scale), z: 9999)
40
+ @debug_text.x = @position.x
41
+ if @radius == 0 || @radius.nil?
42
+ @radius = if options[:radius]
43
+ options[:radius]
44
+ else
45
+ @image.respond_to?(:width) ? ((@image.width + @image.height) / 4) * scale : 1
46
+ end
47
+ end
48
+ end
49
+
50
+ def draw
51
+ if @image
52
+ @image.draw_rot(@position.x, @position.y, @position.z, @angle, @center_x, @center_y, @scale_x, @scale_y,
53
+ @color, @mode)
54
+ end
55
+
56
+ if $debug
57
+ show_debug_heading
58
+ Gosu.draw_circle(@position.x, @position.y, radius, 9999, @debug_color)
59
+ if @debug_text.text != ""
60
+ Gosu.draw_rect(@debug_text.x - 10, (@debug_text.y - 10), @debug_text.width + 20, @debug_text.height + 20,
61
+ Gosu::Color.rgba(0, 0, 0, 200), 9999)
62
+ @debug_text.draw
63
+ end
64
+ end
65
+ end
66
+
67
+ def update
68
+ end
69
+
70
+ def debug_text(text)
71
+ @debug_text.text = text
72
+ @debug_text.x = @position.x - (@debug_text.width / 2)
73
+ @debug_text.y = @position.y - (@debug_text.height + radius + height)
74
+ end
75
+
76
+ def scale
77
+ if @scale_x == @scale_y
78
+ @scale_x
79
+ else
80
+ false
81
+ # maths?
82
+ end
83
+ end
84
+
85
+ def scale=(int)
86
+ self.scale_x = int
87
+ self.scale_y = int
88
+ self.radius = ((@image.width + @image.height) / 4) * scale
89
+ end
90
+
91
+ def visible
92
+ true
93
+ # if _x_visible
94
+ # if _y_visible
95
+ # true
96
+ # else
97
+ # false
98
+ # end
99
+ # else
100
+ # false
101
+ # end
102
+ end
103
+
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)
107
+ end
108
+
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)
112
+ end
113
+
114
+ def heading(ahead_by = 100, _object = nil, angle_only = false)
115
+ direction = Gosu.angle(@last_position.x, @last_position.x, @position.x, position.y).gosu_to_radians
116
+
117
+ _x = @position.x + (ahead_by * Math.cos(direction))
118
+ _y = @position.y + (ahead_by * Math.sin(direction))
119
+
120
+ return direction if angle_only
121
+ return Vector.new(_x, _y) unless angle_only
122
+ end
123
+
124
+ def show_debug_heading
125
+ _heading = heading
126
+ Gosu.draw_line(@position.x, @position.y, @debug_color, _heading.x, _heading.y, @debug_color, 9999)
127
+ end
128
+
129
+ def width
130
+ @image ? @image.width * scale : 0
131
+ end
132
+
133
+ def height
134
+ @image ? @image.height * scale : 0
135
+ end
136
+
137
+ def pause
138
+ @paused = true
139
+ end
140
+
141
+ def unpause
142
+ @paused = false
143
+ end
144
+
145
+ def rotate(int)
146
+ self.angle += int
147
+ self.angle %= 360
148
+ end
149
+
150
+ def alpha=(int) # 0-255
151
+ @alpha = int
152
+ @alpha = 255 if @alpha > 255
153
+ @color = Gosu::Color.rgba(@color.red, @color.green, @color.blue, int)
154
+ end
155
+
156
+ def button_up(id)
157
+ end
158
+
159
+ def button_down(id)
160
+ end
161
+
162
+ def find_closest(game_object_class)
163
+ best_object = nil
164
+ best_distance = 100_000_000_000 # Huge default number
165
+
166
+ game_object_class.all.each do |object|
167
+ distance = Gosu.distance(x, y, object.x, object.y)
168
+ if distance <= best_distance
169
+ best_object = object
170
+ best_distance = distance
171
+ end
172
+ end
173
+
174
+ best_object
175
+ end
176
+
177
+ def look_at(object)
178
+ # TODO: Implement
179
+ end
180
+
181
+ def circle_collision?(object)
182
+ distance = Gosu.distance(x, y, object.x, object.y)
183
+ distance <= radius + object.radius
184
+ end
185
+
186
+ # Duplication... so DRY.
187
+ def each_circle_collision(object, _resolve_with = :width, &block)
188
+ if object.class != Class && object.instance_of?(object.class)
189
+ window.current_state.game_objects.select { |i| i.instance_of?(object.class) }.each do |o|
190
+ distance = Gosu.distance(x, y, object.x, object.y)
191
+ block.call(o, object) if distance <= radius + object.radius && block
192
+ end
193
+ else
194
+ list = window.current_state.game_objects.select { |i| i.instance_of?(object) }
195
+ list.each do |o|
196
+ next if self == o
197
+
198
+ distance = Gosu.distance(x, y, o.x, o.y)
199
+ block.call(self, o) if distance <= radius + o.radius && block
200
+ end
201
+ end
202
+ end
203
+
204
+ def destroy
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
208
+ end
209
+ end
210
+ end
211
+
212
+ # NOTE: This could be implemented more reliably
213
+ def all
214
+ INSTANCES.select { |i| i.instance_of?(self) }
215
+ end
216
+
217
+ def self.each_circle_collision(object, _resolve_with = :width, &block)
218
+ if object.class != Class && object.instance_of?(object.class)
219
+ window.current_state.game_objects.select { |i| i.instance_of?(self) }.each do |o|
220
+ distance = Gosu.distance(o.x, o.y, object.x, object.y)
221
+ block.call(o, object) if distance <= o.radius + object.radius && block
222
+ end
223
+ else
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) }
226
+ lista.product(listb).each do |o, o2|
227
+ next if o == o2
228
+
229
+ distance = Gosu.distance(o.x, o.y, o2.x, o2.y)
230
+ block.call(o, o2) if distance <= o.radius + o2.radius && block
231
+ end
232
+ end
233
+ end
234
+
235
+ def self.destroy_all
236
+ INSTANCES.clear
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)
240
+ end
241
+ end
242
+ end
243
+ end
244
+ end