gamebox 0.3.4 → 0.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. data/README.rdoc +38 -0
  2. data/Rakefile +1 -10
  3. data/TODO.txt +6 -6
  4. data/app_generators/gamebox_generator.rb +95 -0
  5. data/{lib/gamebox/templates/template_app → app_generators/templates}/.gitignore +0 -0
  6. data/app_generators/templates/Gemfile +7 -0
  7. data/app_generators/templates/NEXT_STEPS.txt +1 -0
  8. data/{lib/gamebox/templates/template_app/README → app_generators/templates/README.rdoc} +0 -0
  9. data/{lib/gamebox/templates/template_app → app_generators/templates}/Rakefile +0 -0
  10. data/{lib/gamebox/templates/template_app → app_generators/templates}/config/boot.rb +0 -0
  11. data/app_generators/templates/config/environment.rb +30 -0
  12. data/{lib/gamebox/templates/template_app → app_generators/templates}/config/game.yml +0 -0
  13. data/{lib/gamebox/templates/template_app → app_generators/templates}/data/fonts/FONTS_GO_HERE +0 -0
  14. data/{lib/gamebox/templates/template_app → app_generators/templates}/data/graphics/GRAPHICS_GO_HERE +0 -0
  15. data/{lib/gamebox/templates/template_app → app_generators/templates}/data/music/MUSIC_GOES_HERE +0 -0
  16. data/{lib/gamebox/templates/template_app → app_generators/templates}/data/sounds/SOUND_FX_GO_HERE +0 -0
  17. data/{lib/gamebox/templates → app_generators/templates/script}/actor.erb +0 -0
  18. data/{lib/gamebox/templates → app_generators/templates/script}/actor_spec.erb +0 -0
  19. data/{lib/gamebox/templates → app_generators/templates/script}/actor_view.erb +0 -0
  20. data/{lib/gamebox/templates → app_generators/templates/script}/actor_view_spec.erb +0 -0
  21. data/app_generators/templates/script/generate +12 -0
  22. data/{lib/gamebox/templates/template_app → app_generators/templates}/spec/helper.rb +0 -0
  23. data/app_generators/templates/src/actors/player.rb +8 -0
  24. data/{lib/gamebox/templates/template_app → app_generators/templates}/src/app.rb +0 -0
  25. data/app_generators/templates/src/demo_stage.rb +7 -0
  26. data/bin/gamebox +8 -70
  27. data/component_generators/actor_generator.rb +17 -0
  28. data/docs/CODE_REVIEW +1 -1
  29. data/docs/REFACTOR_NOTES.txt +25 -0
  30. data/docs/getting_started.rdoc +1 -1
  31. data/gamebox.gemspec +7 -4
  32. data/lib/gamebox.rb +6 -3
  33. data/lib/gamebox/actors/collidable_debugger.rb +13 -15
  34. data/lib/gamebox/actors/curtain.rb +44 -43
  35. data/lib/gamebox/actors/emitter.rb +3 -42
  36. data/lib/gamebox/actors/fps.rb +13 -6
  37. data/lib/gamebox/actors/label.rb +42 -34
  38. data/lib/gamebox/actors/logo.rb +2 -4
  39. data/lib/gamebox/actors/score.rb +37 -27
  40. data/lib/gamebox/actors/svg_actor.rb +45 -32
  41. data/lib/gamebox/behaviors/animated.rb +39 -59
  42. data/lib/gamebox/behaviors/audible.rb +14 -14
  43. data/lib/gamebox/behaviors/collidable.rb +65 -36
  44. data/lib/gamebox/behaviors/collidable/aabb_collidable.rb +2 -3
  45. data/lib/gamebox/behaviors/collidable/collidable_shape.rb +6 -4
  46. data/lib/gamebox/behaviors/collidable/polygon_collidable.rb +1 -1
  47. data/lib/gamebox/behaviors/emitting.rb +48 -0
  48. data/lib/gamebox/behaviors/graphical.rb +22 -56
  49. data/lib/gamebox/behaviors/layered.rb +8 -21
  50. data/lib/gamebox/behaviors/physical.rb +202 -213
  51. data/lib/gamebox/behaviors/positioned.rb +16 -0
  52. data/lib/gamebox/behaviors/projectile.rb +15 -0
  53. data/lib/gamebox/behaviors/visible.rb +16 -0
  54. data/lib/gamebox/core/aabb_helpers.rb +61 -0
  55. data/lib/gamebox/core/aabb_node.rb +118 -0
  56. data/lib/gamebox/core/aabb_tree.rb +137 -0
  57. data/lib/gamebox/core/actor.rb +102 -0
  58. data/lib/gamebox/core/actor_factory.rb +56 -0
  59. data/lib/gamebox/core/actor_view.rb +63 -0
  60. data/lib/gamebox/core/actor_view_factory.rb +40 -0
  61. data/lib/gamebox/{arbiter.rb → core/arbiter.rb} +31 -34
  62. data/lib/gamebox/{backstage.rb → core/backstage.rb} +0 -0
  63. data/lib/gamebox/core/behavior.rb +64 -0
  64. data/lib/gamebox/core/behavior_factory.rb +56 -0
  65. data/lib/gamebox/{class_finder.rb → core/class_finder.rb} +0 -0
  66. data/lib/gamebox/{config_manager.rb → core/config_manager.rb} +1 -1
  67. data/lib/gamebox/core/configuration.rb +39 -0
  68. data/lib/gamebox/core/core.rb +30 -0
  69. data/lib/gamebox/core/deprecated.rb +15 -0
  70. data/lib/gamebox/{director.rb → core/director.rb} +6 -11
  71. data/lib/gamebox/core/font_style.rb +26 -0
  72. data/lib/gamebox/core/font_style_factory.rb +11 -0
  73. data/lib/gamebox/core/game.rb +19 -0
  74. data/lib/gamebox/{hooked_gosu_window.rb → core/hooked_gosu_window.rb} +12 -6
  75. data/lib/gamebox/{input_manager.rb → core/input_manager.rb} +106 -99
  76. data/lib/gamebox/core/physics.rb +22 -0
  77. data/lib/gamebox/{physical_stage.rb → core/physics_manager.rb} +36 -30
  78. data/lib/gamebox/{resource_manager.rb → core/resource_manager.rb} +19 -18
  79. data/lib/gamebox/{sound_manager.rb → core/sound_manager.rb} +9 -7
  80. data/lib/gamebox/{stage.rb → core/stage.rb} +42 -80
  81. data/lib/gamebox/{stage_manager.rb → core/stage_manager.rb} +46 -53
  82. data/lib/gamebox/{stagehand.rb → core/stagehand.rb} +0 -0
  83. data/lib/gamebox/{svg_document.rb → core/svg_document.rb} +0 -0
  84. data/lib/gamebox/core/timer_manager.rb +50 -0
  85. data/lib/gamebox/{viewport.rb → core/viewport.rb} +2 -3
  86. data/lib/gamebox/{wrapped_screen.rb → core/wrapped_screen.rb} +12 -19
  87. data/lib/gamebox/gamebox_application.rb +7 -15
  88. data/lib/gamebox/lib/evented_attributes.rb +51 -0
  89. data/lib/gamebox/{ftor.rb → lib/ftor.rb} +0 -0
  90. data/lib/gamebox/lib/min_max_helpers.rb +10 -0
  91. data/lib/gamebox/lib/rect.rb +112 -54
  92. data/lib/gamebox/lib/yoda.rb +46 -0
  93. data/lib/gamebox/spec/helper.rb +317 -12
  94. data/lib/gamebox/stagehands/spatial_tree_stagehand.rb +61 -0
  95. data/lib/gamebox/version.rb +8 -3
  96. data/lib/gamebox/views/graphical_actor_view.rb +22 -29
  97. data/script/perf_aabb.rb +56 -0
  98. data/script/perf_array_access.rb +16 -0
  99. data/script/perf_collisions.rb +37 -18
  100. data/script/perf_struct_vs_array.rb +7 -7
  101. data/spec/acceptance/animation_spec.rb +65 -0
  102. data/spec/acceptance/basic_actor_lifecycle_spec.rb +92 -0
  103. data/spec/acceptance/built_in_collision_handling_spec.rb +55 -0
  104. data/spec/acceptance/chipmunk_collision_handling_spec.rb +83 -0
  105. data/spec/acceptance/fps_actor_spec.rb +40 -0
  106. data/spec/acceptance/pausing_spec.rb +61 -0
  107. data/spec/acceptance/timer_usage_spec.rb +53 -0
  108. data/spec/actors/emitter_spec.rb +5 -0
  109. data/spec/{label_spec.rb → actors/label_spec.rb} +1 -1
  110. data/spec/behaviors/animated_spec.rb +85 -0
  111. data/spec/behaviors/collidable_spec.rb +134 -0
  112. data/spec/{physical_spec.rb → behaviors/physical_spec.rb} +2 -1
  113. data/spec/behaviors/positioned_spec.rb +6 -0
  114. data/spec/behaviors/projectile_spec.rb +6 -0
  115. data/spec/core/aabb_tree_spec.rb +109 -0
  116. data/spec/core/actor_factory_spec.rb +44 -0
  117. data/spec/core/actor_spec.rb +78 -0
  118. data/spec/core/actor_view_spec.rb +53 -0
  119. data/spec/{arbiter_spec.rb → core/arbiter_spec.rb} +29 -30
  120. data/spec/core/backstage_spec.rb +37 -0
  121. data/spec/core/behavior_factory_spec.rb +50 -0
  122. data/spec/core/behavior_spec.rb +8 -0
  123. data/spec/core/configuration_spec.rb +8 -0
  124. data/spec/core/core_spec.rb +13 -0
  125. data/spec/core/font_style_factory_spec.rb +17 -0
  126. data/spec/core/font_style_spec.rb +41 -0
  127. data/spec/core/hooked_gosu_window_spec.rb +75 -0
  128. data/spec/core/input_manager_spec.rb +285 -0
  129. data/spec/core/physics_manager_spec.rb +11 -0
  130. data/spec/core/resource_manager_spec.rb +12 -0
  131. data/spec/core/stage_manager_spec.rb +140 -0
  132. data/spec/core/stage_spec.rb +73 -0
  133. data/spec/core/timer_manager_spec.rb +89 -0
  134. data/spec/{viewport_spec.rb → core/viewport_spec.rb} +6 -3
  135. data/spec/core/wrapped_screen_spec.rb +26 -0
  136. data/spec/fixtures/game.yml +7 -0
  137. data/spec/fixtures/snelpling/idle/1.png +0 -0
  138. data/spec/fixtures/snelpling/jump/1.png +0 -0
  139. data/spec/fixtures/snelpling/jump/2.png +0 -0
  140. data/spec/fixtures/snelpling/jump/3.png +0 -0
  141. data/spec/helper.rb +8 -0
  142. data/spec/{class_finder_spec.rb → lib/class_finder_spec.rb} +2 -1
  143. data/spec/stagehands/spatial_tree_stagehand_spec.rb +19 -0
  144. data/spec/views/graphical_actor_view_spec.rb +116 -0
  145. metadata +343 -144
  146. data/README.txt +0 -34
  147. data/lib/gamebox/actor.rb +0 -179
  148. data/lib/gamebox/actor_factory.rb +0 -57
  149. data/lib/gamebox/actor_view.rb +0 -44
  150. data/lib/gamebox/actors/spatial_debugger.rb +0 -62
  151. data/lib/gamebox/behavior.rb +0 -70
  152. data/lib/gamebox/behaviors/timed.rb +0 -33
  153. data/lib/gamebox/behaviors/updatable.rb +0 -12
  154. data/lib/gamebox/console_app.rb +0 -41
  155. data/lib/gamebox/gamebox_generator.rb +0 -32
  156. data/lib/gamebox/generators/actor_generator.rb +0 -43
  157. data/lib/gamebox/generators/view_generator.rb +0 -42
  158. data/lib/gamebox/physical_director.rb +0 -17
  159. data/lib/gamebox/physics.rb +0 -32
  160. data/lib/gamebox/spatial_bucket.rb +0 -9
  161. data/lib/gamebox/spatial_hash.rb +0 -194
  162. data/lib/gamebox/spatial_stagehand.rb +0 -80
  163. data/lib/gamebox/templates/template_app/Gemfile +0 -6
  164. data/lib/gamebox/templates/template_app/config/environment.rb +0 -23
  165. data/lib/gamebox/templates/template_app/config/stage_config.yml +0 -2
  166. data/lib/gamebox/templates/template_app/script/generate +0 -7
  167. data/lib/gamebox/templates/template_app/src/demo_stage.rb +0 -11
  168. data/lib/gamebox/templates/template_app/src/game.rb +0 -19
  169. data/lib/gamebox/templates/template_app/src/my_actor.rb +0 -14
  170. data/script/perf_spatial_hash.rb +0 -64
  171. data/spec/actor_factory_spec.rb +0 -61
  172. data/spec/actor_spec.rb +0 -71
  173. data/spec/actor_view_spec.rb +0 -61
  174. data/spec/animated_spec.rb +0 -83
  175. data/spec/backstage_spec.rb +0 -45
  176. data/spec/behavior_spec.rb +0 -28
  177. data/spec/collidable_spec.rb +0 -135
  178. data/spec/emitter_spec.rb +0 -20
  179. data/spec/input_manager_spec.rb +0 -134
  180. data/spec/resource_manager_spec.rb +0 -13
  181. data/spec/spatial_hash_spec.rb +0 -119
  182. data/spec/spatial_stagehand_spec.rb +0 -93
  183. data/spec/stage_manager_spec.rb +0 -25
  184. data/spec/stage_spec.rb +0 -65
@@ -1,33 +0,0 @@
1
- class Timed < Behavior
2
-
3
- def setup
4
- actor.when :remove_me do |actor|
5
- clear_timers
6
- end
7
-
8
- @timers = []
9
- relegates :add_timer, :remove_timer
10
- end
11
-
12
- def add_timer(name, ms, recurring = true, &block)
13
- timer_name = "#{actor.object_id} #{name}"
14
- @timers << timer_name
15
- actor.stage.add_timer timer_name, ms do
16
- block.call
17
- actor.stage.remove_timer timer_name unless recurring
18
- end
19
- end
20
-
21
- def remove_timer(name)
22
- timer_name = "#{actor.object_id} #{name}"
23
- @timers.delete timer_name
24
- actor.stage.remove_timer timer_name
25
- end
26
-
27
- def clear_timers
28
- @timers.each do |timer_name|
29
- actor.stage.remove_timer timer_name
30
- end
31
- end
32
-
33
- end
@@ -1,12 +0,0 @@
1
-
2
-
3
- class Updatable < Behavior
4
-
5
- def setup
6
- @actor.director.add_actor @actor
7
- end
8
-
9
- def removed
10
- @actor.director.remove_actor @actor
11
- end
12
- end
@@ -1,41 +0,0 @@
1
- if $0 == __FILE__
2
- puts "Connecting to game..."
3
- require 'irb'
4
- require 'irb/completion'
5
- module IRB
6
- def IRB.start_session(obj)
7
- unless $irb
8
- IRB.setup nil
9
- ## maybe set some opts here, as in parse_opts in irb/init.rb?
10
- IRB.load_modules
11
- end
12
-
13
- workspace = WorkSpace.new(obj)
14
-
15
- if @CONF[:SCRIPT] ## normally, set by parse_opts
16
- $irb = Irb.new(workspace, @CONF[:SCRIPT])
17
- else
18
- $irb = Irb.new(workspace)
19
- end
20
-
21
- @CONF[:IRB_RC].call($irb.context) if @CONF[:IRB_RC]
22
- @CONF[:MAIN_CONTEXT] = $irb.context
23
-
24
- trap("INT") do
25
- $irb.signal_handle
26
- end
27
-
28
- catch(:IRB_EXIT) do
29
- $irb.eval_input
30
- end
31
- print "\n"
32
-
33
- ## might want to reset your app's interrupt handler here
34
- end
35
- end
36
-
37
- require 'drb'
38
- DRb.start_service
39
- game = DRbObject.new nil, "druby://localhost:7373"
40
- IRB.start_session game
41
- end
@@ -1,32 +0,0 @@
1
- # # This is the generator for gamebox
2
- #
3
- # $: << File.join(File.dirname(__FILE__),'generators')
4
- #
5
- # unless "".respond_to? :end_with?
6
- # class String
7
- # def end_with?(ending)
8
- # self[size-ending.size..-1] == ending
9
- # end
10
- # end
11
- # end
12
- #
13
- # def print_usage
14
- # puts "generate what *opts"
15
- # puts "TODO list all generators here"
16
- # end
17
- # # TODO pull these out into generators/ dir for listing
18
- #
19
- # if ARGV.size < 1
20
- # print_usage
21
- # exit 0
22
- # end
23
- #
24
- # # TODO load generator file based on ARGV[0]
25
- # generator_klass_name =
26
- # Inflector.camelize ARGV[0].downcase+"_generator"
27
- #
28
- # require Inflector.underscore(generator_klass_name)
29
- #
30
- # generator_klass = Object.const_get generator_klass_name
31
- # generator_klass.new.generate(ARGV[1..-1])
32
- #
@@ -1,43 +0,0 @@
1
-
2
- class ActorGenerator
3
- require 'erb'
4
- def generate(*args)
5
-
6
- @actor_name = ARGV[1]
7
- @behaviors = ARGV[2]
8
- @bind = binding
9
-
10
- build_actor
11
- build_test_actor
12
-
13
- # load test_actor and replace
14
- end
15
-
16
- def build_actor
17
- template_file = File.open(File.join(GAMEBOX_PATH,'templates','actor.erb'))
18
- template_contents = template_file.readlines.join
19
- actor_template = ERB.new(template_contents)
20
-
21
- result = actor_template.result @bind
22
-
23
- out_file = File.join(APP_ROOT,'src',Inflector.underscore(@actor_name)+".rb")
24
- raise "File exists [#{out_file}]" if File.exists? out_file
25
- File.open(out_file,"w+") do |f|
26
- f.write result
27
- end
28
- end
29
-
30
- def build_test_actor
31
- template_file = File.open(File.join(GAMEBOX_PATH,'templates','actor_spec.erb'))
32
- template_contents = template_file.readlines.join
33
- actor_template = ERB.new(template_contents)
34
-
35
- result = actor_template.result @bind
36
-
37
- out_file = File.join(APP_ROOT,'spec',Inflector.underscore(@actor_name)+"_spec.rb")
38
- raise "File exists [#{out_file}]" if File.exists? out_file
39
- File.open(out_file,"w+") do |f|
40
- f.write result
41
- end
42
- end
43
- end
@@ -1,42 +0,0 @@
1
-
2
- class ViewGenerator
3
- require 'erb'
4
- def generate(*args)
5
-
6
- @actor_view_name = ARGV[1]
7
- @actor_view_name += "View" unless @actor_view_name.end_with? "View"
8
- @behaviors = ARGV[2]
9
- @bind = binding
10
-
11
- build_actor_view
12
- build_test_actor_view
13
- end
14
-
15
- def build_actor_view
16
- template_file = File.open(File.join(GAMEBOX_PATH,'templates','actor_view.erb'))
17
- template_contents = template_file.readlines.join
18
- actor_view_template = ERB.new(template_contents)
19
-
20
- result = actor_view_template.result @bind
21
-
22
- out_file = File.join(APP_ROOT,'src',Inflector.underscore(@actor_view_name)+".rb")
23
- raise "File exists [#{out_file}]" if File.exists? out_file
24
- File.open(out_file,"w+") do |f|
25
- f.write result
26
- end
27
- end
28
-
29
- def build_test_actor_view
30
- template_file = File.open(File.join(GAMEBOX_PATH,'templates','actor_view_spec.erb'))
31
- template_contents = template_file.readlines.join
32
- actor_view_template = ERB.new(template_contents)
33
-
34
- result = actor_view_template.result @bind
35
-
36
- out_file = File.join(APP_ROOT,'spec',Inflector.underscore(@actor_view_name)+"_spec.rb")
37
- raise "File exists [#{out_file}]" if File.exists? out_file
38
- File.open(out_file,"w+") do |f|
39
- f.write result
40
- end
41
- end
42
- end
@@ -1,17 +0,0 @@
1
-
2
-
3
- class PhysicalDirector < Director
4
- def find_physical_obj(shape)
5
- @actors.select{|a|a.respond_to?(:shape) && a.shape==shape}.first
6
- end
7
-
8
- def remove_physical_obj(shape)
9
- act = find_physical_obj shape
10
- act.remove_self
11
- act
12
- end
13
-
14
- def actor_removed(act)
15
- act.stage.unregister_physical_object act if act.is? :physical
16
- end
17
- end
@@ -1,32 +0,0 @@
1
- if defined? CP
2
- ZERO_VEC_2 = vec2(0,0)
3
- def vec2(*args)
4
- CP::Vec2.new *args
5
- end
6
-
7
- class CP::Space
8
- alias :add_collision_func_old :add_collision_func
9
-
10
- # allows for passing arrays of collision types not just single ones
11
- # add_collision_func([:foo,:bar], [:baz,:yar]) becomes:
12
- # add_collision_func(:foo, :baz)
13
- # add_collision_func(:foo, :yar)
14
- # add_collision_func(:bar, :baz)
15
- # add_collision_func(:bar, :yar)
16
- def add_collision_func(first_objs, second_objs, &block)
17
- firsts = [first_objs].flatten
18
- seconds = [second_objs].flatten
19
-
20
- firsts.each do |f|
21
- seconds.each do |s|
22
- add_collision_func_old(f,s,&block)
23
- end
24
- end
25
- end
26
- end
27
- else
28
- ZERO_VEC_2 = Ftor.new(0,0)
29
- def vec2(*args)
30
- Ftor.new *args
31
- end
32
- end
@@ -1,9 +0,0 @@
1
- class SpatialBucket < Array
2
- attr_accessor :x, :y
3
- def initialize(x,y)
4
- @x = x
5
- @y = y
6
- super()
7
- end
8
- end
9
-
@@ -1,194 +0,0 @@
1
- class SpatialHash
2
-
3
- attr_reader :cell_size, :buckets, :items, :moved_items
4
- attr_accessor :auto_resize
5
-
6
- def initialize(cell_size, resize = false)
7
- @cell_size = cell_size.to_i
8
- @items = {}
9
- @auto_resize = resize
10
-
11
- # TODO auto resize is broken atm
12
- if @auto_resize
13
- @total_w = 0
14
- @total_h = 0
15
- end
16
- @items = {}
17
- @buckets = {}
18
- rehash
19
- end
20
-
21
- def cell_size=(new_size)
22
- @cell_size = new_size.to_i
23
- rehash
24
- end
25
-
26
- def rehash
27
- @moved_items = {}
28
- # TODO WTF?
29
- return
30
- items = @items
31
-
32
- if @auto_resize
33
- # recommeded cell size == 2 x avg obj size
34
- if @total_w > 0 && items.size > 0
35
- avg_w = @total_w / items.size
36
- avg_h = @total_h / items.size
37
-
38
- @cell_size = (avg_w+avg_h).to_i
39
- end
40
-
41
- @total_w = 0
42
- @total_h = 0
43
- end
44
-
45
- @items = {}
46
- @buckets = {}
47
- items.values.each do |item|
48
- add item
49
- end
50
- end
51
-
52
- # does not remove or add event handlers
53
- def move(item)
54
- @moved_items[item] = item
55
- _remove item
56
- _add item
57
- end
58
-
59
- def add(item)
60
- _add item
61
- end
62
-
63
- def _add(item)
64
- buckets = lookup item
65
- @items[item] = buckets
66
-
67
- buckets.each do |bucket|
68
- bucket << item
69
-
70
- if @auto_resize
71
- w = item.width if item.respond_to? :width
72
- h = item.height if item.respond_to? :height
73
- w ||= 1
74
- h ||= 1
75
- @total_w += w
76
- @total_h += h
77
- end
78
- end
79
- end
80
-
81
- def remove(item)
82
- @moved_items.delete item
83
- _remove item
84
- end
85
-
86
- def _remove(item)
87
- buckets = @items.delete item
88
- if buckets
89
- buckets.each do |bucket|
90
- bucket.delete item
91
- end
92
- end
93
- end
94
-
95
- def lookup(item)
96
- w = item.width if item.respond_to? :width
97
- h = item.height if item.respond_to? :height
98
-
99
- w ||= 1
100
- h ||= 1
101
-
102
- x = item.x
103
- y = item.y
104
- min_x = bucket_cell_for x
105
- min_y = bucket_cell_for y
106
- if w == 1 && h == 1
107
- max_x = min_x
108
- max_y = min_y
109
- else
110
- max_x = bucket_cell_for x+w-1
111
- max_y = bucket_cell_for y+h-1
112
- end
113
-
114
- buckets = []
115
- bucket_x = min_x
116
- while bucket_x < max_x + 1 do
117
- bucket_y = min_y
118
- while bucket_y < max_y + 1 do
119
- @buckets[bucket_x] ||= {}
120
- @buckets[bucket_x][bucket_y] ||= SpatialBucket.new(bucket_x, bucket_y)
121
- buckets << @buckets[bucket_x][bucket_y]
122
- bucket_y += 1
123
- end
124
- bucket_x += 1
125
- end
126
-
127
- buckets
128
- end
129
-
130
- def bucket_cell_for(location)
131
- (location.to_i / cell_size).to_i
132
- end
133
-
134
- def items_at(x,y)
135
- bucket_x = bucket_cell_for x
136
- bucket_y = bucket_cell_for y
137
- if @buckets[bucket_x].nil? || @buckets[bucket_x][bucket_y].nil?
138
- return []
139
- else
140
- @buckets[bucket_x][bucket_y]
141
- end
142
- end
143
-
144
- def items_in(x,y,w,h)
145
- return items_at x, y if ((w.nil? || w == 1) && (h.nil? || w == 1))
146
-
147
- min_x = bucket_cell_for x
148
- min_y = bucket_cell_for y
149
- if w == 1 && h == 1
150
- max_x = min_x
151
- max_y = min_y
152
- else
153
- max_x = bucket_cell_for x+w-1
154
- max_y = bucket_cell_for y+w-1
155
- end
156
-
157
- items_in_bucket_range min_x, min_y, max_x, max_y
158
- end
159
-
160
- def items_in_bucket_range(min_x,min_y,max_x,max_y)
161
- items = {}
162
- (min_x+1..(max_x+1)).each do |bucket_x|
163
- x_bucket = @buckets[bucket_x]
164
-
165
- if x_bucket
166
- (min_y+1..(max_y+1)).each do |bucket_y|
167
- objects = x_bucket[bucket_y]
168
- if objects
169
- objects.each do |item|
170
- items[item] = item
171
- end
172
- end
173
- end
174
- end
175
- end
176
- items.values
177
- end
178
-
179
- # will look dist number of cells around all the cells
180
- # occupied by the item
181
- def neighbors_of(item, dist=1)
182
- buckets = lookup(item)
183
-
184
- min_bucket_x = buckets.min_by{ |bucket| bucket.x }.x - dist
185
- min_bucket_y = buckets.min_by{ |bucket| bucket.y }.y - dist
186
- max_bucket_x = buckets.max_by{ |bucket| bucket.x }.x + dist
187
- max_bucket_y = buckets.max_by{ |bucket| bucket.y }.y + dist
188
-
189
- items = items_in_bucket_range min_bucket_x, min_bucket_y, max_bucket_x, max_bucket_y
190
- items-[item]
191
- end
192
-
193
- end
194
-