gamebox 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/History.txt +14 -0
  2. data/Manifest.txt +40 -37
  3. data/README.txt +2 -2
  4. data/Rakefile +27 -20
  5. data/TODO.txt +8 -8
  6. data/bin/gamebox +7 -1
  7. data/docs/getting_started.rdoc +2 -5
  8. data/docs/logo.png +0 -0
  9. data/lib/gamebox.rb +12 -1
  10. data/lib/gamebox/actor.rb +34 -9
  11. data/lib/gamebox/actor_factory.rb +25 -14
  12. data/lib/gamebox/actor_view.rb +6 -6
  13. data/lib/gamebox/{logo.rb → actors/logo.rb} +0 -0
  14. data/lib/gamebox/{score.rb → actors/score.rb} +2 -1
  15. data/lib/gamebox/{svg_actor.rb → actors/svg_actor.rb} +3 -4
  16. data/lib/gamebox/ai/polaris.rb +2 -0
  17. data/lib/gamebox/behavior.rb +3 -0
  18. data/lib/gamebox/{animated.rb → behaviors/animated.rb} +13 -5
  19. data/lib/gamebox/{graphical.rb → behaviors/graphical.rb} +11 -1
  20. data/lib/gamebox/{layered.rb → behaviors/layered.rb} +14 -0
  21. data/lib/gamebox/{physical.rb → behaviors/physical.rb} +41 -14
  22. data/lib/gamebox/{updatable.rb → behaviors/updatable.rb} +1 -1
  23. data/lib/gamebox/{templates/template_app → data}/config/objects.yml +4 -2
  24. data/lib/gamebox/data/graphics/logo.png +0 -0
  25. data/lib/gamebox/event_compat.rb +285 -0
  26. data/lib/gamebox/ftor.rb +2 -0
  27. data/lib/gamebox/gamebox_application.rb +12 -1
  28. data/lib/gamebox/generators/actor_generator.rb +2 -2
  29. data/lib/gamebox/generators/view_generator.rb +42 -0
  30. data/lib/gamebox/input_manager.rb +88 -21
  31. data/lib/gamebox/{aliasing.rb → lib/aliasing.rb} +0 -0
  32. data/lib/gamebox/{templates/template_app/lib → lib}/diy.rb +0 -0
  33. data/lib/gamebox/{inflections.rb → lib/inflections.rb} +0 -0
  34. data/lib/gamebox/{inflector.rb → lib/inflector.rb} +2 -2
  35. data/lib/gamebox/{linked_list.rb → lib/linked_list.rb} +0 -0
  36. data/lib/gamebox/{metaclass.rb → lib/metaclass.rb} +0 -0
  37. data/lib/gamebox/lib/numbers_ext.rb +3 -0
  38. data/lib/gamebox/{platform.rb → lib/platform.rb} +0 -0
  39. data/lib/gamebox/{publisher_ext.rb → lib/publisher_ext.rb} +0 -0
  40. data/lib/gamebox/{sorted_list.rb → lib/sorted_list.rb} +0 -0
  41. data/lib/gamebox/lib/surface_ext.rb +76 -0
  42. data/lib/gamebox/physical_director.rb +1 -1
  43. data/lib/gamebox/{physical_level.rb → physical_stage.rb} +28 -18
  44. data/lib/gamebox/physics.rb +2 -2
  45. data/lib/gamebox/resource_manager.rb +77 -8
  46. data/lib/gamebox/sound_manager.rb +15 -17
  47. data/lib/gamebox/stage.rb +143 -0
  48. data/lib/gamebox/stage_manager.rb +110 -0
  49. data/lib/gamebox/svg_document.rb +1 -1
  50. data/lib/gamebox/tasks/gamebox_tasks.rb +1 -1
  51. data/lib/gamebox/templates/{test_actor.erb → actor_spec.erb} +2 -2
  52. data/lib/gamebox/templates/actor_view.erb +8 -0
  53. data/lib/gamebox/templates/actor_view_spec.erb +10 -0
  54. data/lib/gamebox/templates/template_app/Rakefile +4 -4
  55. data/lib/gamebox/templates/template_app/config/game.yml +1 -0
  56. data/lib/gamebox/templates/template_app/config/stage_config.yml +2 -0
  57. data/lib/gamebox/templates/template_app/script/generate +2 -1
  58. data/lib/gamebox/templates/template_app/{test → spec}/helper.rb +0 -0
  59. data/lib/gamebox/templates/template_app/src/{demo_level.rb → demo_stage.rb} +5 -3
  60. data/lib/gamebox/templates/template_app/src/game.rb +4 -6
  61. data/lib/gamebox/version.rb +3 -2
  62. data/lib/gamebox/viewport.rb +18 -9
  63. data/lib/gamebox/{graphical_actor_view.rb → views/graphical_actor_view.rb} +13 -1
  64. data/lib/gamebox/wrapped_screen.rb +2 -1
  65. data/spec/actor_spec.rb +57 -0
  66. data/{test/test_animated.rb → spec/animated_spec.rb} +5 -6
  67. data/spec/helper.rb +24 -0
  68. data/{test/test_line_of_site.rb → spec/line_of_site_spec.rb} +1 -1
  69. data/{test/test_physical.rb → spec/physical_spec.rb} +3 -4
  70. data/{test/test_polaris.rb → spec/polaris_spec.rb} +1 -1
  71. data/{test/test_viewport.rb → spec/viewport_spec.rb} +11 -8
  72. metadata +53 -50
  73. data/docs/gamebox04_big.png +0 -0
  74. data/lib/gamebox/level.rb +0 -65
  75. data/lib/gamebox/mode.rb +0 -123
  76. data/lib/gamebox/mode_manager.rb +0 -80
  77. data/lib/gamebox/numbers_ext.rb +0 -3
  78. data/lib/gamebox/surface_ext.rb +0 -37
  79. data/lib/gamebox/templates/template_app/config/mode_level_config.yml +0 -3
  80. data/test/helper.rb +0 -26
  81. data/test/test_actor.rb +0 -36
@@ -1,8 +1,8 @@
1
1
  require 'chipmunk'
2
2
 
3
- require 'numbers_ext'
3
+ #require 'numbers_ext'
4
4
  include CP
5
- ZeroVec2 = vec2(0,0)
5
+ ZERO_VEC_2 = vec2(0,0)
6
6
 
7
7
  class Space
8
8
  alias :add_collision_func_old :add_collision_func
@@ -18,13 +18,77 @@ class ResourceManager
18
18
  end
19
19
 
20
20
  def load_animation_set(actor, action)
21
+ actor_dir = Inflector.underscore(actor.class)
22
+ using_tileset = File.exist?("#{GFX_PATH}#{actor_dir}/#{action}.png")
23
+ if using_tileset
24
+ load_tile_set(actor, action)
25
+ else
26
+ load_frame_set(actor, action)
27
+ end
28
+ end
29
+
30
+ #
31
+ # --------------- image from @path --------------
32
+ # :right | [frame#1][frame#2][frame#3][frame#4][frame#5]|
33
+ # -----------------------------------------------
34
+ #
35
+ # :down ---image----
36
+ # | [frame#1] |
37
+ # | [frame#2] |
38
+ # | [frame#3] |
39
+ # | [frame#4] |
40
+ # | [frame#5] |
41
+ # -------------
42
+ #
43
+ def load_tile_set(actor, action)
44
+ actor_dir = Inflector.underscore(actor.class)
45
+ tileset = load_image "#{actor_dir}/#{action}.png"
46
+
47
+ action_imgs = []
48
+ w,h = *tileset.size
49
+ color = tileset.get_at 0, 0
50
+
51
+ if h > w
52
+ # down
53
+ num_frames = h/w
54
+ clip_from = Rubygame::Rect.new(0, 0, w, w)
55
+ clip_to = Rubygame::Rect.new(0, 0, w, w)
56
+ num_frames.times do
57
+ surface = Rubygame::Surface.new(clip_to.size)
58
+ surface.fill color
59
+ tileset.blit surface, clip_to, clip_from
60
+ surface.set_colorkey color
61
+ surface = surface.to_display_alpha
62
+ action_imgs << surface
63
+ clip_from.y += w
64
+ end
65
+ else
66
+ # right
67
+ num_frames = w/h
68
+ clip_from = Rubygame::Rect.new(0, 0, h, h)
69
+ clip_to = Rubygame::Rect.new(0, 0, h, h)
70
+ num_frames.times do
71
+ surface = Rubygame::Surface.new(clip_to.size)
72
+ surface.fill color
73
+ tileset.blit surface, clip_to, clip_from
74
+ surface.set_colorkey color
75
+ surface = surface.to_display_alpha
76
+ action_imgs << surface
77
+ clip_from.x += h
78
+ end
79
+ end
80
+
81
+ action_imgs
82
+ end
83
+
84
+ def load_frame_set(actor, action)
21
85
  # use pngs only for now
22
86
  actor_dir = Inflector.underscore(actor.class)
23
87
  frames = Dir.glob("#{GFX_PATH}#{actor_dir}/#{action}/*.png")
24
88
  action_imgs = []
25
89
 
26
90
  frames = frames.sort_by {|f| File.basename(f).to_i }
27
-
91
+
28
92
  for frame in frames
29
93
  rel_path = frame.slice(GFX_PATH.size,frame.size)
30
94
  action_imgs << load_image(rel_path)
@@ -36,10 +100,12 @@ class ResourceManager
36
100
  cached_img = @loaded_images[file_name]
37
101
  if cached_img.nil?
38
102
  begin
39
- cached_img = Rubygame::Surface.load(File.expand_path(GFX_PATH + file_name))
103
+ #cached_img = Rubygame::Surface.load(File.expand_path(GFX_PATH + file_name))
104
+ cached_img = Rubygame::Surface.load(GFX_PATH + file_name)
40
105
  rescue Exception => ex
41
106
  #check global gamebox location
42
- cached_img = Rubygame::Surface.load(File.expand_path(GAMEBOX_GFX_PATH + file_name))
107
+ #cached_img = Rubygame::Surface.load(File.expand_path(GAMEBOX_GFX_PATH + file_name))
108
+ cached_img = Rubygame::Surface.load(GAMEBOX_GFX_PATH + file_name)
43
109
  end
44
110
  @loaded_images[file_name] = cached_img
45
111
  end
@@ -73,12 +139,14 @@ class ResourceManager
73
139
  TTF.setup
74
140
  @ttf_loaded = true
75
141
  end
76
- full_name = File.expand_path(FONTS_PATH + name)
142
+ #full_name = File.expand_path(FONTS_PATH + name)
143
+ full_name = FONTS_PATH + name
77
144
  begin
78
145
  font = TTF.new(full_name, size)
79
146
  @loaded_fonts[name][size] = font
80
147
  rescue Exception => ex
81
- full_name = File.expand_path(GAMEBOX_FONTS_PATH + name)
148
+ #full_name = File.expand_path(GAMEBOX_FONTS_PATH + name)
149
+ full_name = GAMEBOX_FONTS_PATH + name
82
150
  font = TTF.new(full_name, size)
83
151
  @loaded_fonts[name][size] = font
84
152
  end
@@ -108,15 +176,16 @@ class ResourceManager
108
176
  f.write settings.to_yaml
109
177
  end
110
178
  end
111
-
179
+
112
180
  def load_svg(file_name)
113
181
  # TODO create LEVEL_PATH in environment
114
182
  cached_svg = @loaded_svgs[file_name]
115
183
  if cached_svg.nil?
116
- cached_svg = SvgDocument.new(File.open(File.expand_path(DATA_PATH + "levels/" + file_name + ".svg")))
184
+ #cached_svg = SvgDocument.new(File.open(File.expand_path(DATA_PATH + "levels/" + file_name + ".svg")))
185
+ cached_svg = SvgDocument.new(File.open(DATA_PATH + "levels/" + file_name + ".svg"))
117
186
  @loaded_svgs[file_name] = cached_svg
118
187
  end
119
188
  cached_svg
120
189
  end
121
-
190
+
122
191
  end
@@ -1,24 +1,13 @@
1
+ # SoundManager auto loads sounds/music from data/sounds and data/music. It makes them accessible via name.
2
+ # The name is a symbol of the filename without extension. This means that foo.wav and foo.ogg in the sound
3
+ # directory will generate indeterminent behavior.
1
4
  class SoundManager
5
+ attr_accessor :sounds, :music
2
6
 
3
7
  constructor :resource_manager, :config_manager
8
+
9
+ # checks to see if sdl_mixer is availalbe and preloads the sounds and music directories.
4
10
  def setup
5
- # Not in the pygame version - for Rubygame, we need to
6
- # explicitly open the audio device.
7
- # Args are:
8
- # Frequency - Sampling frequency in samples per second (Hz).
9
- # 22050 is recommended for most games; 44100 is
10
- # CD audio rate. The larger the value, the more
11
- # processing required.
12
- # Format - Output sample format. This is one of the
13
- # AUDIO_* constants in Rubygame::Mixer
14
- # Channels -output sound channels. Use 2 for stereo,
15
- # 1 for mono. (this option does not affect number
16
- # of mixing channels)
17
- # Samplesize - Bytes per output sample. Specifically, this
18
- # determines the size of the buffer that the
19
- # sounds will be mixed in.
20
- # Rubygame::Mixer::open_audio( 22050, Rubygame::Mixer::AUDIO_U8, 2, 1024 )
21
- Rubygame::Mixer::open_audio( 22050, nil, 2, 1024 )
22
11
 
23
12
  puts 'Warning, sound disabled' unless
24
13
  (@enabled = (Rubygame::VERSIONS[:sdl_mixer] != nil))
@@ -57,6 +46,8 @@ class SoundManager
57
46
  @enabled
58
47
  end
59
48
 
49
+ # plays the sound based on the name with the specified volume level.
50
+ # play_sound :foo # play sound at 100% volume
60
51
  def play_sound(what, volume=nil)
61
52
  if @enabled && @sounds[what]
62
53
  @sound_thread = Thread.new do
@@ -66,6 +57,9 @@ class SoundManager
66
57
  end
67
58
  end
68
59
 
60
+ # plays the music based on the name with the specified volume level.
61
+ # will loop until SoundManager#stop_music is called.
62
+ # play_music :foo, 0.8 # play music at 80% volumne
69
63
  def play_music(what, volume=nil)
70
64
  if @enabled && @music[what]
71
65
  @music_thread = Thread.new do
@@ -75,12 +69,16 @@ class SoundManager
75
69
  end
76
70
  end
77
71
 
72
+ # stops the music file that is passed in.
73
+ # stop_music :foo
78
74
  def stop_music(what)
79
75
  if @enabled
80
76
  @music[what].stop if @music[what]
81
77
  end
82
78
  end
83
79
 
80
+ # stops the sound that is passed in.
81
+ # stop_sound :foo
84
82
  def stop_sound(what)
85
83
  if @enabled
86
84
  @sounds[what].stop if @sounds[what]
@@ -0,0 +1,143 @@
1
+ require 'inflector'
2
+ require 'publisher'
3
+ require 'director'
4
+ require 'viewport'
5
+ # Stage is a state that the game is in. (ie intro stage, multiplayer stage,
6
+ # single player stage).
7
+ class Stage
8
+ extend Publisher
9
+ can_fire_anything
10
+
11
+ attr_accessor :drawables, :resource_manager, :sound_manager,
12
+ :director, :opts, :viewport, :input_manager
13
+
14
+ def initialize(input_manager, actor_factory, resource_manager, sound_manager, config_manager, opts)
15
+ @input_manager = input_manager
16
+
17
+ @resource_manager = resource_manager
18
+ @sound_manager = sound_manager
19
+
20
+ @config_manager = config_manager
21
+ res = @config_manager[:screen_resolution]
22
+ @viewport = Viewport.new res[0], res[1]
23
+
24
+ @actor_factory = actor_factory
25
+ @director = create_director
26
+ @actor_factory.director = @director
27
+
28
+ @opts = opts
29
+
30
+ setup
31
+ end
32
+
33
+ def create_director
34
+ Director.new
35
+ end
36
+
37
+ def setup
38
+ clear_drawables
39
+ end
40
+
41
+ def create_actor(type, args={})
42
+ @actor_factory.build type, self, args
43
+ end
44
+ alias :spawn :create_actor
45
+
46
+ # extract all the params from a node that are needed to construct an actor
47
+ def create_actors_from_svg svg_doc
48
+ float_keys = ["x","y"]
49
+ dynamic_actors ||= {}
50
+ layer = svg_doc.find_group_by_label("actors")
51
+
52
+ unless layer.nil?
53
+ # each image in the layer is an actor
54
+ layer.images.each do |actor_def|
55
+ klass = actor_def.game_class.to_sym
56
+ handle = actor_def.game_handle
57
+ new_opts = {}
58
+ actor_def.node.attributes.each do |k,v|
59
+ v = v.to_f if float_keys.include? k
60
+ new_opts[k.to_sym] = v
61
+ end
62
+
63
+ actor = create_actor klass, new_opts
64
+ dynamic_actors[handle.to_sym] = actor if handle
65
+ end
66
+ end
67
+ alias :spawn_from_svg :create_actors_from_svg
68
+
69
+ dynamic_actors
70
+ end
71
+
72
+ def update(time)
73
+ @director.update time
74
+ @viewport.update time
75
+ end
76
+
77
+ def curtain_raising(*args)
78
+ curtain_up *args
79
+ end
80
+
81
+ def curtain_dropping(*args)
82
+ curtain_down *args
83
+ end
84
+
85
+ def curtain_up(*args)
86
+ end
87
+
88
+ def curtain_down(*args)
89
+ end
90
+
91
+ def draw(target)
92
+ @drawables.keys.sort.reverse.each do |parallax_layer|
93
+
94
+ drawables_on_parallax_layer = @drawables[parallax_layer]
95
+
96
+ unless drawables_on_parallax_layer.nil?
97
+ drawables_on_parallax_layer.keys.sort.each do |layer|
98
+
99
+ trans_x = @viewport.x_offset parallax_layer
100
+ trans_y = @viewport.y_offset parallax_layer
101
+
102
+ drawables_on_parallax_layer[layer].each do |drawable|
103
+ drawable.draw target, trans_x, trans_y
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ def unregister_drawable(drawable)
111
+ @drawables[drawable.parallax][drawable.layer].delete drawable
112
+ end
113
+
114
+ def clear_drawables
115
+ @drawables = {}
116
+ end
117
+
118
+ def register_drawable(drawable)
119
+ layer = drawable.layer
120
+ parallax = drawable.parallax
121
+ @drawables[parallax] ||= {}
122
+ @drawables[parallax][layer] ||= []
123
+ @drawables[parallax][layer] << drawable
124
+ end
125
+
126
+ # move all actors from one layer to another
127
+ # note, this will remove all actors in that layer!
128
+ def move_layer(from_parallax, from_layer, to_parallax, to_layer)
129
+ drawable_list = @drawables[from_parallax].delete from_layer
130
+
131
+ if drawable_list
132
+ prev_drawable_list = @drawables[to_parallax].delete to_layer
133
+ @drawables[to_parallax][to_layer] = drawable_list
134
+ drawable_list.each do |drawable|
135
+ drawable.parallax = to_parallax
136
+ drawable.layer = to_layer
137
+ end
138
+ end
139
+ prev_drawable_list
140
+
141
+ end
142
+ end
143
+
@@ -0,0 +1,110 @@
1
+ require 'inflector'
2
+ require 'stage'
3
+ class StageManager
4
+
5
+ constructor :resource_manager, :actor_factory, :input_manager,
6
+ :sound_manager, :config_manager
7
+
8
+ def setup
9
+ @stages = {}
10
+
11
+ @actor_factory.stage_manager = self
12
+ stages = @resource_manager.load_config('stage_config')[:stages]
13
+
14
+ @stage_names = []
15
+ @stage_opts = []
16
+ stages.each do |stage|
17
+ stage_name = stage.keys.first
18
+ opts = stage.values.first
19
+ @stage_names << stage_name
20
+ opts ||= {}
21
+ @stage_opts << opts
22
+ end
23
+ end
24
+
25
+ def lookup_stage_class(stage_name)
26
+ index = @stage_names.index stage_name
27
+ opts = @stage_opts[index]
28
+
29
+ name = opts[:class]
30
+ name ||= stage_name
31
+ stage_klass_name ||= Inflector.camelize name.to_s+"Stage"
32
+
33
+ begin
34
+ require name.to_s+"_stage"
35
+ rescue LoadError => ex
36
+ STDERR.puts ex
37
+ # TODO hrm.. should this get logged
38
+ # hope it's defined somewhere else
39
+ end
40
+ stage_klass = ObjectSpace.const_get stage_klass_name
41
+ end
42
+
43
+ def create_stage(name, opts)
44
+ stage_instance = lookup_stage_class(name).new(@input_manager, @actor_factory, @resource_manager, @sound_manager, @config_manager, opts)
45
+
46
+ stage_instance.when :next_stage do |*args|
47
+ next_stage *args
48
+ end
49
+ stage_instance.when :prev_stage do |*args|
50
+ prev_stage *args
51
+ end
52
+ stage_instance.when :restart_stage do |*args|
53
+ restart_stage *args
54
+ end
55
+
56
+ stage_instance
57
+ end
58
+
59
+ def next_stage
60
+ index = @stage_names.index @stage
61
+ if index == @stage_names.size-1
62
+ puts "last stage, exiting"
63
+ exit
64
+ end
65
+ @stages.delete @stage_names[index+1]
66
+ change_stage_to @stage_names[index+1]
67
+ end
68
+
69
+ def prev_stage
70
+ index = @stage_names.index @stage
71
+ if index == 0
72
+ puts "first stage, exiting"
73
+ exit
74
+ end
75
+ @stages.delete @stage_names[index-1]
76
+ change_stage_to @stage_names[index-1]
77
+ end
78
+
79
+ def restart_stage(*args)
80
+ current_stage.curtain_dropping *args
81
+ index = @stage_names.index @stage
82
+ @stages.delete @stage_names[index]
83
+ change_stage_to @stage, *args
84
+ end
85
+
86
+ def change_stage_to(stage, *args)
87
+ @prev_stage = @stages[@stage]
88
+ unless @prev_stage.nil?
89
+ @prev_stage.curtain_dropping *args
90
+ end
91
+ @stage = stage
92
+ @stage_args = args
93
+ unless @stages[@stage]
94
+ @stages[@stage] = create_stage(@stage, @stage_opts[@stage_names.index(@stage)])
95
+ end
96
+ @stages[@stage].curtain_raising *args
97
+ end
98
+
99
+ def current_stage
100
+ @stages[@stage]
101
+ end
102
+
103
+ def update(time)
104
+ @stages[@stage].update time unless @stages[@stage].nil?
105
+ end
106
+
107
+ def draw(target)
108
+ @stages[@stage].draw target unless @stages[@stage].nil?
109
+ end
110
+ end