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,28 +1,15 @@
1
- # Stage represent on level of game play. Some games will likely have only one
2
- # stage. Stage is responsible for loading its background, props, and directors.
3
- # PhysicalStage adds a physics space to the Stage
1
+ # PhysicsManager creates and manages chipmunks space.
2
+ class PhysicsManager
3
+ extend Forwardable
4
+ def_delegators :@space, :elastic_iterations=, :damping=, :gravity=
4
5
 
5
-
6
-
7
- class PhysicalStage < Stage
8
-
9
6
  attr_accessor :space
10
-
11
- def setup
12
- super
13
- setup_space
14
- end
15
-
16
- def setup_space
7
+ def configure
17
8
  @space = CP::Space.new
18
9
  @space.iterations = 20
19
10
  @space.elastic_iterations = 5
20
11
  end
21
12
 
22
- def create_director
23
- PhysicalDirector.new
24
- end
25
-
26
13
  PHYSICS_STEP = 25.0
27
14
  def update_physics(time)
28
15
  unless @physics_paused
@@ -45,10 +32,32 @@ class PhysicalStage < Stage
45
32
 
46
33
  def update(time)
47
34
  update_physics time
48
- super
35
+ end
36
+
37
+ # allows for passing arrays of collision types not just single ones
38
+ # add_collision_func([:foo,:bar], [:baz,:yar]) becomes:
39
+ # add_collision_func(:foo, :baz)
40
+ # add_collision_func(:foo, :yar)
41
+ # add_collision_func(:bar, :baz)
42
+ # add_collision_func(:bar, :yar)
43
+ def add_collision_func(first_objs, second_objs, &block)
44
+ firsts = [first_objs].flatten
45
+ seconds = [second_objs].flatten
46
+
47
+ firsts.each do |f|
48
+ seconds.each do |s|
49
+ @space.add_collision_func(f,s) do |a, b|
50
+ block.call a.actor, b.actor
51
+ end
52
+ end
53
+ end
49
54
  end
50
55
 
51
56
  def register_physical_object(obj,static=false)
57
+ obj.when :remove_me do
58
+ unregister_physical_object obj
59
+ end
60
+
52
61
  if static
53
62
  obj.shapes.each do |shape|
54
63
  @space.add_static_shape shape
@@ -72,13 +81,13 @@ class PhysicalStage < Stage
72
81
 
73
82
  def unregister_physical_object(obj,static=false)
74
83
  if static
75
- obj.physical.shapes.each do |shape|
84
+ obj.shapes.each do |shape|
76
85
  @space.remove_static_shape shape
77
86
  end
78
87
  else
79
88
  @space.remove_body(obj.body)
80
89
 
81
- obj.physical.shapes.each do |shape|
90
+ obj.shapes.each do |shape|
82
91
  @space.remove_shape shape
83
92
  end
84
93
  end
@@ -90,21 +99,18 @@ class PhysicalStage < Stage
90
99
  # later in the future.
91
100
  #
92
101
  # This block is called on each actor found
93
- def pick(x, y, &block)
94
- @space.shape_point_query(vec2(x, y)) do |found|
95
- actor = @director.find_physical_obj(found)
96
- block.call(actor)
97
- end
98
- end
102
+ # def pick(x, y, &block)
103
+ # @space.shape_point_query(vec2(x, y)) do |found|
104
+ # actor = @director.find_physical_obj(found)
105
+ # block.call(actor)
106
+ # end
107
+ # end
99
108
 
100
109
  def pause
101
110
  pause_physics
102
- super
103
111
  end
104
112
 
105
113
  def unpause
106
- super
107
114
  restart_physics
108
115
  end
109
-
110
116
  end
@@ -3,24 +3,23 @@ require "fileutils"
3
3
 
4
4
  class ResourceManager
5
5
 
6
- constructor :wrapped_screen
6
+ construct_with :wrapped_screen
7
7
 
8
- def setup
8
+ def initialize
9
9
  @loaded_images = {}
10
10
  @loaded_fonts = {}
11
11
  @loaded_svgs = {}
12
- @window = @wrapped_screen.screen
12
+ @window = wrapped_screen.screen
13
13
  end
14
14
 
15
15
  def load_actor_image(actor)
16
16
  # use pngs only for now
17
- actor_name = Inflector.underscore(actor.class)
18
- return load_image("#{actor_name}.png")
17
+ # actor_name = Inflector.underscore(actor.class)
18
+ return load_image("#{actor.actor_type}.png")
19
19
  end
20
20
 
21
21
  def load_animation_set(actor, action)
22
- actor_dir = Inflector.underscore(actor.class)
23
- using_tileset = File.exist?("#{GFX_PATH}#{actor_dir}/#{action}.png")
22
+ using_tileset = File.exist?("#{Gamebox.configuration.gfx_path}#{actor.actor_type}/#{action}.png")
24
23
  if using_tileset
25
24
  load_tile_set(actor, action)
26
25
  else
@@ -53,11 +52,11 @@ class ResourceManager
53
52
  if h > w
54
53
  # down
55
54
  num_frames = h/w
56
- action_imgs = Image.load_tiles @window, GFX_PATH+tileset_name, -1, -num_frames, true
55
+ action_imgs = Image.load_tiles @window, Gamebox.configuration.gfx_path+tileset_name, -1, -num_frames, true
57
56
  else
58
57
  # right
59
58
  num_frames = w/h
60
- action_imgs = Image.load_tiles @window, GFX_PATH+tileset_name, -num_frames, -1, true
59
+ action_imgs = Image.load_tiles @window, Gamebox.configuration.gfx_path+tileset_name, -num_frames, -1, true
61
60
  end
62
61
 
63
62
  action_imgs
@@ -65,14 +64,13 @@ class ResourceManager
65
64
 
66
65
  def load_frame_set(actor, action)
67
66
  # use pngs only for now
68
- actor_dir = Inflector.underscore(actor.class)
69
- frames = Dir.glob("#{GFX_PATH}#{actor_dir}/#{action}/*.png")
67
+ frames = Dir.glob("#{Gamebox.configuration.gfx_path}#{actor.actor_type}/#{action}/*.png")
70
68
  action_imgs = []
71
69
 
72
70
  frames = frames.sort_by {|f| File.basename(f).to_i }
73
71
 
74
72
  for frame in frames
75
- rel_path = frame.slice(GFX_PATH.size,frame.size)
73
+ rel_path = frame.slice(Gamebox.configuration.gfx_path.size,frame.size)
76
74
  action_imgs << load_image(rel_path)
77
75
  end
78
76
  action_imgs
@@ -82,10 +80,10 @@ class ResourceManager
82
80
  cached_img = @loaded_images[file_name]
83
81
  if cached_img.nil?
84
82
  begin
85
- full_name = GFX_PATH + file_name
83
+ full_name = Gamebox.configuration.gfx_path + file_name
86
84
  if ! File.exist? full_name
87
85
  #check global gamebox location
88
- full_name = GAMEBOX_GFX_PATH + file_name
86
+ full_name = Gamebox.configuration.gb_gfx_path + file_name
89
87
  end
90
88
  cached_img = Image.new(@window, full_name)
91
89
  rescue Exception => ex
@@ -116,6 +114,9 @@ class ResourceManager
116
114
 
117
115
  # loads fonts from the fonts dir and caches them for later
118
116
  def load_font(name, size)
117
+ config = Gamebox.configuration
118
+ fonts_path = config.fonts_path
119
+ gb_fonts_path = config.gb_fonts_path
119
120
  @loaded_fonts[name] ||= {}
120
121
  return @loaded_fonts[name][size] if @loaded_fonts[name][size]
121
122
  begin
@@ -123,19 +124,19 @@ class ResourceManager
123
124
  font = Font.new(@window, name, size)
124
125
  @loaded_fonts[name][size] = font
125
126
  else
126
- full_name = FONTS_PATH + name
127
+ full_name = fonts_path + name
127
128
  if File.exist? full_name
128
129
  font = Font.new(@window, full_name, size)
129
130
  @loaded_fonts[name][size] = font
130
131
  else
131
- full_name = GAMEBOX_FONTS_PATH + name
132
+ full_name = gb_fonts_path + name
132
133
  font = Font.new(@window, full_name, size)
133
134
  @loaded_fonts[name][size] = font
134
135
  end
135
136
  end
136
137
  return font
137
138
  rescue Exception => ex
138
- debug "Cannot load font #{full_name}:#{ex}"
139
+ log "Cannot load font #{full_name}:#{ex}"
139
140
  end
140
141
  return nil
141
142
  end
@@ -152,7 +153,7 @@ class ResourceManager
152
153
  end
153
154
 
154
155
  def load_tiles(filename, tile_width, tile_height)
155
- Image.load_tiles @window, GFX_PATH+filename, tile_width, tile_height, true
156
+ Image.load_tiles @window, Gamebox.configuration.gfx_path+filename, tile_width, tile_height, true
156
157
  end
157
158
 
158
159
 
@@ -4,39 +4,41 @@
4
4
  class SoundManager
5
5
  attr_accessor :sounds, :music
6
6
 
7
- constructor :resource_manager, :config_manager
7
+ construct_with :resource_manager, :config_manager
8
8
  SUPPORTED_AUDIO_EXTS = %w(wav ogg mp3 au aiff caf)
9
9
 
10
10
  # checks to see if sdl_mixer is availalbe and preloads the sounds and music directories.
11
- def setup
11
+ def initialize
12
12
 
13
13
  puts 'CHANGE TO LOG:Warning, sound disabled' unless
14
- @enabled = (@config_manager.settings[:sound].nil? or @config_manager.settings[:sound] == true)
14
+ @enabled = (config_manager.settings[:sound].nil? or config_manager.settings[:sound] == true)
15
15
 
16
16
  if @enabled
17
17
  @music = {}
18
- files = Dir.glob "#{MUSIC_PATH}**.{#{SUPPORTED_AUDIO_EXTS.join(',')}}"
18
+ music_path = Gamebox.configuration.music_path
19
+ files = Dir.glob "#{music_path}**.{#{SUPPORTED_AUDIO_EXTS.join(',')}}"
19
20
  for f in files
20
21
  name = File.basename(f)
21
22
  begin
22
23
  sym = name.gsub(" ","_").split(".")[0..-2].join(".").to_sym
23
24
  ext = name.gsub(" ","_").split(".").last
24
25
  unless ext == "txt"
25
- @music[sym] = @resource_manager.load_music(f)
26
+ @music[sym] = resource_manager.load_music(f)
26
27
  end
27
28
  rescue;end
28
29
  end if files
29
30
 
30
31
  @sounds = {}
31
32
  @playing_sounds = {}
32
- files = Dir.glob "#{SOUND_PATH}**.{#{SUPPORTED_AUDIO_EXTS.join(',')}}"
33
+ sound_path = Gamebox.configuration.sound_path
34
+ files = Dir.glob "#{sound_path}**.{#{SUPPORTED_AUDIO_EXTS.join(',')}}"
33
35
  for f in files
34
36
  name = File.basename(f)
35
37
  begin
36
38
  sym = name.gsub(" ","_").split(".")[0..-2].join(".").to_sym
37
39
  ext = name.gsub(" ","_").split(".").last
38
40
  unless ext == "txt"
39
- @sounds[sym] = @resource_manager.load_sound(f)
41
+ @sounds[sym] = resource_manager.load_sound(f)
40
42
  end
41
43
  rescue;end
42
44
  end if files
@@ -5,40 +5,34 @@ class Stage
5
5
  extend Publisher
6
6
  can_fire_anything
7
7
 
8
- attr_accessor :drawables, :resource_manager, :sound_manager,
9
- :director, :opts, :viewport, :input_manager, :backstage
8
+ construct_with :input_manager, :actor_factory, :resource_manager,
9
+ :sound_manager, :config_manager, :director, :timer_manager,
10
+ :this_object_context
10
11
 
11
- def initialize(input_manager, actor_factory, resource_manager, sound_manager, config_manager, backstage, opts)
12
- @input_manager = input_manager
12
+ def self.inherited(kid)
13
+ kid.construct_with *self.object_definition.component_names
14
+ end
13
15
 
14
- @resource_manager = resource_manager
15
- @sound_manager = sound_manager
16
+ attr_accessor :drawables, :opts, :viewport, :backstage
16
17
 
17
- @config_manager = config_manager
18
- res = @config_manager[:screen_resolution]
18
+ def configure(backstage, opts)
19
+ res = config_manager[:screen_resolution]
19
20
  @viewport = Viewport.new res[0], res[1]
20
-
21
- @actor_factory = actor_factory
22
- @director = create_director
23
- @actor_factory.director = @director
24
- @backstage = backstage
21
+ this_object_context[:viewport] = @viewport
25
22
 
26
23
  @stagehands = {}
24
+ @backstage = backstage
27
25
  @opts = opts
28
26
 
29
27
  setup
30
28
  end
31
29
 
32
- def create_director
33
- Director.new
34
- end
35
-
36
30
  def setup
37
31
  clear_drawables
38
32
  end
39
33
 
40
34
  def create_actor(type, args={})
41
- @actor_factory.build type, self, args
35
+ actor_factory.build type, args
42
36
  end
43
37
  alias :spawn :create_actor
44
38
 
@@ -69,13 +63,13 @@ class Stage
69
63
  end
70
64
 
71
65
  def update(time)
72
- @director.update time
66
+ director.update time
73
67
  @viewport.update time
74
68
  @stagehands.each do |name, stagehand|
75
69
  stagehand.update time
76
70
  end
77
71
  find_collisions
78
- update_timers time
72
+ timer_manager.update time
79
73
  end
80
74
 
81
75
  def curtain_raising(*args)
@@ -94,28 +88,18 @@ class Stage
94
88
 
95
89
  def draw(target)
96
90
  z = 0
97
- # TODO PERF cache this array and invalidate when new layers come in?
98
91
  @parallax_layers.each do |parallax_layer|
99
- # @drawables.keys.sort.reverse.each do |parallax_layer|
100
-
101
92
  drawables_on_parallax_layer = @drawables[parallax_layer]
102
93
 
103
94
  if drawables_on_parallax_layer
104
95
  @layer_orders[parallax_layer].each do |layer|
105
- # drawables_on_parallax_layer.keys.sort.each do |layer|
106
96
 
107
97
  trans_x = @viewport.x_offset parallax_layer
108
98
  trans_y = @viewport.y_offset parallax_layer
109
99
 
110
100
  z += 1
111
101
  drawables_on_parallax_layer[layer].each do |drawable|
112
- begin
113
- drawable.draw target, trans_x, trans_y, z
114
- rescue Exception => ex
115
- p drawable.class
116
- p ex
117
- p ex.backtrace
118
- end
102
+ drawable.draw target, trans_x, trans_y, z
119
103
  end
120
104
  end
121
105
  end
@@ -129,6 +113,7 @@ class Stage
129
113
  def clear_drawables
130
114
  @drawables = {}
131
115
  @layer_orders = {}
116
+ @parallax_layers = []
132
117
  end
133
118
 
134
119
  def register_drawable(drawable)
@@ -163,42 +148,6 @@ class Stage
163
148
 
164
149
  end
165
150
 
166
- def remove_timer(name)
167
- @timers ||= {}
168
- @timers.delete name
169
- end
170
-
171
- def timer(name)
172
- @timers ||= {}
173
- @timers[name]
174
- end
175
-
176
- # add block to be executed every interval_ms millis
177
- # TODO make this hash based on object => name => block
178
- # to clean up the timed behavior
179
- def add_timer(name, interval_ms, &block)
180
- @new_timers ||= {}
181
- @new_timers[name] = {:count => 0,
182
- :interval_ms => interval_ms, :callback => block}
183
- end
184
-
185
- # update each timers counts, call any blocks that are over their interval
186
- def update_timers(time_delta)
187
- # TODO handle overwriting the same timer name...
188
- @timers ||= {}
189
- if @new_timers
190
- @timers.merge!(@new_timers)
191
- @new_timers = nil
192
- end
193
- @timers.each do |name, timer_hash|
194
- timer_hash[:count] += time_delta
195
- if timer_hash[:count] > timer_hash[:interval_ms]
196
- timer_hash[:count] -= timer_hash[:interval_ms]
197
- timer_hash[:callback].call
198
- end
199
- end
200
- end
201
-
202
151
  def on_pause(&block)
203
152
  @pause_listeners ||= []
204
153
  @pause_listeners << block if block_given?
@@ -216,10 +165,9 @@ class Stage
216
165
  def pause
217
166
  @pause_listeners ||= []
218
167
  @paused = true
219
- @director.pause
220
- @input_manager.pause
221
- @paused_timers = @timers
222
- @timers = nil
168
+ director.pause
169
+ timer_manager.pause
170
+ input_manager.pause
223
171
  @pause_listeners.each do |listener|
224
172
  listener.call
225
173
  end
@@ -227,10 +175,9 @@ class Stage
227
175
 
228
176
  def unpause
229
177
  @unpause_listeners ||= []
230
- @director.unpause
231
- @input_manager.unpause
232
- @timers = @paused_timers
233
- @paused_timers = nil
178
+ director.unpause
179
+ input_manager.unpause
180
+ timer_manager.unpause
234
181
  @unpause_listeners.each do |listener|
235
182
  listener.call
236
183
  end
@@ -241,15 +188,30 @@ class Stage
241
188
  @stagehands[stagehand_sym] ||= create_stagehand(stagehand_sym, opts)
242
189
  end
243
190
 
191
+ # pauses the current stage, creates an actor using args, unpauses on actor death
192
+ #
193
+ # Example:
194
+ # modal_actor :dialog, x: 40, y: 50, message: "WOW"
195
+ def modal_actor(*args)
196
+ on_pause do
197
+ pause_actor = spawn *args
198
+ pause_actor.when :remove_me do
199
+ @pause_listeners = nil
200
+ unpause
201
+ yield if block_given?
202
+ end
203
+ end
204
+ pause
205
+
206
+ end
207
+
208
+ private
244
209
  def create_stagehand(name, opts)
245
210
  underscored_class = "#{name}_stagehand"
246
- begin
247
- require underscored_class
248
- rescue LoadError
249
- # TODO log this?
250
- end
251
211
  klass = ClassFinder.find underscored_class
252
212
  klass.new self, opts
253
213
  end
214
+
215
+
254
216
  end
255
217