gamebox 0.2.1 → 0.3.2

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 (95) hide show
  1. data/Gemfile +1 -8
  2. data/Rakefile +13 -37
  3. data/TODO.txt +27 -27
  4. data/docs/getting_started.rdoc +2 -2
  5. data/gamebox.gemspec +33 -191
  6. data/lib/gamebox.rb +18 -14
  7. data/lib/gamebox/actor.rb +37 -27
  8. data/lib/gamebox/actor_factory.rb +4 -5
  9. data/lib/gamebox/actor_view.rb +8 -0
  10. data/lib/gamebox/actors/collidable_debugger.rb +2 -2
  11. data/lib/gamebox/actors/curtain.rb +3 -3
  12. data/lib/gamebox/actors/emitter.rb +51 -0
  13. data/lib/gamebox/actors/label.rb +27 -7
  14. data/lib/gamebox/actors/logo.rb +1 -1
  15. data/lib/gamebox/actors/spatial_debugger.rb +25 -10
  16. data/lib/gamebox/arbiter.rb +61 -34
  17. data/lib/gamebox/behavior.rb +3 -3
  18. data/lib/gamebox/behaviors/animated.rb +1 -1
  19. data/lib/gamebox/behaviors/audible.rb +1 -1
  20. data/lib/gamebox/behaviors/collidable.rb +9 -4
  21. data/lib/gamebox/behaviors/collidable/aabb_collidable.rb +26 -1
  22. data/lib/gamebox/behaviors/collidable/circle_collidable.rb +3 -3
  23. data/lib/gamebox/behaviors/collidable/polygon_collidable.rb +1 -1
  24. data/lib/gamebox/behaviors/graphical.rb +30 -4
  25. data/lib/gamebox/behaviors/layered.rb +1 -1
  26. data/lib/gamebox/behaviors/physical.rb +113 -30
  27. data/lib/gamebox/behaviors/timed.rb +33 -0
  28. data/lib/gamebox/behaviors/updatable.rb +1 -1
  29. data/lib/gamebox/class_finder.rb +1 -21
  30. data/lib/gamebox/console_app.rb +33 -31
  31. data/lib/gamebox/constants.rb +481 -0
  32. data/lib/gamebox/data/config/objects.yml +7 -0
  33. data/lib/gamebox/gamebox_application.rb +10 -33
  34. data/lib/gamebox/gamebox_generator.rb +32 -32
  35. data/lib/gamebox/input_manager.rb +73 -32
  36. data/lib/gamebox/lib/inflector.rb +1 -1
  37. data/lib/gamebox/lib/range_ext.rb +5 -0
  38. data/lib/gamebox/lib/rect.rb +548 -548
  39. data/lib/gamebox/lib/sorted_list.rb +1 -1
  40. data/lib/gamebox/lib/symbol_ext.rb +8 -0
  41. data/lib/gamebox/physical_director.rb +1 -1
  42. data/lib/gamebox/physical_stage.rb +3 -3
  43. data/lib/gamebox/physics.rb +0 -3
  44. data/lib/gamebox/resource_manager.rb +22 -17
  45. data/lib/gamebox/sound_manager.rb +3 -2
  46. data/lib/gamebox/spatial_hash.rb +60 -31
  47. data/lib/gamebox/spatial_stagehand.rb +30 -6
  48. data/lib/gamebox/spec/helper.rb +7 -7
  49. data/lib/gamebox/stage.rb +18 -19
  50. data/lib/gamebox/stage_manager.rb +33 -23
  51. data/lib/gamebox/stagehand.rb +3 -0
  52. data/lib/gamebox/svg_document.rb +1 -1
  53. data/lib/gamebox/tasks/gamebox_tasks.rake +133 -0
  54. data/lib/gamebox/templates/actor.erb +0 -2
  55. data/lib/gamebox/templates/actor_view.erb +1 -3
  56. data/lib/gamebox/templates/template_app/Gemfile +3 -2
  57. data/lib/gamebox/templates/template_app/Rakefile +3 -8
  58. data/lib/gamebox/templates/template_app/config/environment.rb +7 -39
  59. data/lib/gamebox/templates/template_app/src/demo_stage.rb +1 -2
  60. data/lib/gamebox/templates/template_app/src/my_actor.rb +0 -3
  61. data/lib/gamebox/version.rb +2 -2
  62. data/lib/gamebox/viewport.rb +44 -8
  63. data/lib/gamebox/views/graphical_actor_view.rb +22 -16
  64. data/lib/gamebox/wrapped_screen.rb +9 -1
  65. data/script/perf_spatial_hash.rb +49 -58
  66. data/script/perf_struct_vs_array.rb +32 -0
  67. data/spec/actor_factory_spec.rb +61 -0
  68. data/spec/actor_spec.rb +24 -18
  69. data/spec/actor_view_spec.rb +51 -6
  70. data/spec/animated_spec.rb +27 -6
  71. data/spec/arbiter_spec.rb +12 -24
  72. data/spec/backstage_spec.rb +1 -1
  73. data/spec/behavior_spec.rb +3 -3
  74. data/spec/class_finder_spec.rb +13 -0
  75. data/spec/collidable_spec.rb +30 -10
  76. data/spec/emitter_spec.rb +20 -0
  77. data/spec/helper.rb +5 -21
  78. data/spec/input_manager_spec.rb +134 -0
  79. data/spec/label_spec.rb +0 -1
  80. data/spec/physical_spec.rb +114 -5
  81. data/spec/resource_manager_spec.rb +1 -2
  82. data/spec/spatial_hash_spec.rb +23 -7
  83. data/spec/spatial_stagehand_spec.rb +97 -0
  84. data/spec/stage_manager_spec.rb +0 -1
  85. data/spec/stage_spec.rb +2 -2
  86. data/spec/viewport_spec.rb +92 -48
  87. metadata +223 -119
  88. data/.gitignore +0 -11
  89. data/History.txt +0 -80
  90. data/VERSION +0 -1
  91. data/lib/gamebox/event_compat.rb +0 -285
  92. data/lib/gamebox/lib/diy.rb +0 -371
  93. data/lib/gamebox/lib/numbers_ext.rb +0 -3
  94. data/lib/gamebox/tasks/gamebox_tasks.rb +0 -61
  95. data/load_paths.rb +0 -20
@@ -1,5 +1,3 @@
1
- require 'inflector'
2
- require 'stage'
3
1
  class StageManager
4
2
 
5
3
  constructor :resource_manager, :actor_factory, :input_manager,
@@ -53,6 +51,10 @@ class StageManager
53
51
  stage_instance.when :restart_stage do |*args|
54
52
  restart_stage *args
55
53
  end
54
+ stage_instance.when :change_stage do |stage_name, *args|
55
+ switch_to_stage stage_name, *args
56
+ end
57
+
56
58
 
57
59
  stage_instance
58
60
  end
@@ -63,10 +65,8 @@ class StageManager
63
65
  puts "last stage, exiting"
64
66
  exit
65
67
  end
66
- stage = @stages.delete @stage_names[index+1]
67
- @input_manager.clear_hooks stage
68
68
 
69
- change_stage_to @stage_names[index+1], *args
69
+ switch_to_stage @stage_names[index+1], *args
70
70
  end
71
71
 
72
72
  def prev_stage(*args)
@@ -75,33 +75,22 @@ class StageManager
75
75
  puts "first stage, exiting"
76
76
  exit
77
77
  end
78
- stage = @stages.delete @stage_names[index-1]
79
- @input_manager.clear_hooks stage
80
- change_stage_to @stage_names[index-1], *args
78
+
79
+ switch_to_stage @stage_names[index-1], *args
81
80
  end
82
81
 
83
82
  def restart_stage(*args)
84
83
  current_stage.curtain_dropping *args
85
84
  index = @stage_names.index @stage
86
85
 
87
- stage = @stages.delete @stage_names[index]
88
- @input_manager.clear_hooks stage
89
-
90
- change_stage_to @stage, *args
86
+ switch_to_stage @stage, *args
91
87
  end
92
88
 
93
- def change_stage_to(stage, *args)
94
- @prev_stage = @stages[@stage]
95
- unless @prev_stage.nil?
96
- @prev_stage.curtain_dropping *args
97
- end
98
- @stage = stage
99
- @stage_args = args
100
- unless @stages[@stage]
101
- @stages[@stage] = create_stage(@stage, @stage_opts[@stage_names.index(@stage)])
102
- end
103
- @stages[@stage].curtain_raising *args
89
+ def switch_to_stage(stage_name, *args)
90
+ shutdown_current_stage *args
91
+ activate_new_stage stage_name, *args
104
92
  end
93
+ alias :change_stage_to :switch_to_stage
105
94
 
106
95
  def current_stage
107
96
  @stages[@stage]
@@ -114,4 +103,25 @@ class StageManager
114
103
  def draw(target)
115
104
  @stages[@stage].draw target unless @stages[@stage].nil?
116
105
  end
106
+
107
+ private
108
+
109
+ def activate_new_stage(stage_name, *args)
110
+ @stage = stage_name
111
+ @stage_args = args
112
+ @stages[@stage] = create_stage(@stage, @stage_opts[@stage_names.index(@stage)])
113
+ @stages[@stage].curtain_raising *args
114
+ end
115
+
116
+ def shutdown_current_stage(*args)
117
+ if @stage and @stages and @stages[@stage]
118
+ current_stage = @stages[@stage]
119
+ current_stage.curtain_dropping *args
120
+ @input_manager.clear_hooks(current_stage)
121
+ @stages.delete @stage
122
+ @stage = nil
123
+ @stage_args = nil
124
+ end
125
+ end
126
+
117
127
  end
@@ -8,4 +8,7 @@ class Stagehand
8
8
 
9
9
  def setup
10
10
  end
11
+
12
+ def update(time)
13
+ end
11
14
  end
@@ -1,6 +1,6 @@
1
1
  require 'rexml/document'
2
2
  require 'strscan'
3
- require 'rect'
3
+
4
4
 
5
5
  class SvgDocument
6
6
 
@@ -0,0 +1,133 @@
1
+ require 'gamebox/lib/platform'
2
+
3
+ desc "Run the game"
4
+ task :run do |t|
5
+ sh "bundle exec ruby src/app.rb"
6
+ end
7
+ task :default => :run
8
+
9
+ desc "Report code statistics (KLOCs, etc) from the application"
10
+ task :stats do
11
+ require 'gamebox/lib/code_statistics'
12
+ CodeStatistics.new(*STATS_DIRECTORIES).to_s
13
+ end
14
+
15
+
16
+ desc "Run the game with debug server"
17
+ task :debug do |t|
18
+ sh "ruby src/app.rb -debug-server"
19
+ end
20
+
21
+ desc "Bundle in all required gems"
22
+ task :bundle do |t|
23
+ sh "bundle package"
24
+ sh "bundle install vendor/bundle --disable-shared-gems"
25
+ end
26
+
27
+ desc "Run specs"
28
+ task :spec do
29
+ begin
30
+ require 'rspec/core/rake_task'
31
+
32
+ RSpec::Core::RakeTask.new(:specz) do |t|
33
+ # t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
34
+ # Put spec opts in a file named .rspec in root
35
+ end
36
+ Rake::Task[:specz].execute
37
+ rescue LoadError
38
+ puts "warning: rspec not installed"
39
+ puts "install with gem install rspec"
40
+ end
41
+ end
42
+
43
+
44
+ namespace :dist do
45
+ desc "Build a .app for your gamebox game"
46
+ task :mac do
47
+ GAME_NAME = "UntitledGame" unless defined?(GAME_NAME)
48
+ # DL template os x app
49
+ remote_file = "gosu-mac-wrapper-#{Gosu::VERSION}.tar.gz"
50
+ mac_build = "build/mac"
51
+ local_file = "#{mac_build}/#{remote_file}"
52
+
53
+ require 'net/http'
54
+ mkdir_p mac_build
55
+ # if false
56
+ Net::HTTP.start("www.libgosu.org") do |http|
57
+ resp = http.get("/downloads/#{remote_file}")
58
+ open(local_file, "wb") { |file| file.write(resp.body) }
59
+ end
60
+ # end
61
+
62
+ # Expand it
63
+ root = pwd
64
+ cd mac_build
65
+ `tar xzf #{remote_file}`
66
+ app_name = "#{GAME_NAME}.app"
67
+ contents = "#{app_name}/Contents"
68
+ resources = "#{contents}/Resources"
69
+ dot_app_lib = "#{resources}/lib"
70
+ gem_vendored = "#{mac_build}/#{resources}/gems"
71
+
72
+ mv 'RubyGosu App.app', app_name
73
+ %w(config data src).each do |src|
74
+ cp_r "../../#{src}", resources
75
+ end
76
+
77
+ # TODO remove chingu / chipmunk / etc
78
+ clean_em_out = %w(chingu chingu.rb).map{|it| "#{dot_app_lib}/#{it}"}
79
+ rm_rf clean_em_out#, :verbose => true, :noop => true
80
+
81
+ cd root
82
+ p `bundle --system package`
83
+ p `bundle package`
84
+ p `bundle --deployment`
85
+ mkdir_p gem_vendored
86
+ rejects = %w(chipmunk gosu)
87
+ Dir["vendor/bundle/ruby/**/gems/**/lib"].each do |gemmy|
88
+ cp_r gemmy, gem_vendored unless rejects.any?{|exclude| gemmy.match exclude}
89
+ end
90
+
91
+ cd mac_build
92
+ File.open "#{resources}/Main.rb", "w+" do |main|
93
+ main.puts <<-EOS
94
+ $: << "\#{File.dirname(__FILE__)}/config"
95
+
96
+ $: << "\#{File.dirname(__FILE__)}/gems/lib"
97
+
98
+ rejects = %w(spec src/app.rb vendor Main.rb)
99
+ ok_dirs = %w(config gems src)
100
+ REQUIRE_ALLS = ok_dirs.map{|dir| Dir.glob("\#{dir}/*.rb").reject{ |f| rejects.any?{|exclude| f.match exclude}}}.flatten
101
+
102
+ require 'environment'
103
+
104
+ GameboxApp.run ARGV, ENV
105
+ EOS
106
+ end
107
+
108
+ # modify plist file
109
+ # UntitledGame
110
+ cd "#{GAME_NAME}.app/Contents"
111
+ plist = File.open("Info.plist").read
112
+ File.open("Info.plist", 'w+') do |f|
113
+ f.puts plist.gsub "UntitledGame", GAME_NAME
114
+ end
115
+ end
116
+
117
+ task :win do
118
+ # create dist dir
119
+ FileUtils.mkdir "dist" unless File.exist? "dist"
120
+ # pull down windows app shell
121
+ # expand into place
122
+ sh 'cd dist; wget http://github.com/downloads/shawn42/gamebox/gamebox_app.zip; unzip gamebox_app.zip; mv gamebox_app/* .; rm gamebox_app.zip; rm -rf gamebox_app'
123
+
124
+ # copy config/src/lib/data into dist/src
125
+ %w{vendor config data }.each do |dir|
126
+ FileUtils.cp_r dir, File.join('dist','src', dir) if File.exist? dir
127
+ end
128
+ FileUtils.cp_r 'src', File.join('dist', 'src')
129
+
130
+ # create zip of dist?
131
+ end
132
+ end
133
+
@@ -1,5 +1,3 @@
1
- require 'actor'
2
-
3
1
  class <%= @actor_name %> < Actor
4
2
  <% if @behaviors %>
5
3
  has_baviors <%= @behaviors.join "," %>
@@ -1,8 +1,6 @@
1
- require 'actor_view'
2
-
3
1
  class <%= @actor_view_name %> < ActorView
4
2
 
5
- def draw(target,x_off,y_off)
3
+ def draw(target,x_off,y_off,z)
6
4
  # put in custom draw code here using @actor as the model
7
5
  end
8
6
  end
@@ -1,5 +1,6 @@
1
1
  source "http://rubygems.org"
2
+ gem 'chipmunk'
3
+ gem 'require_all'
2
4
  gem "gamebox"
3
- gem "publisher"
4
5
  gem "diy"
5
- gem "gosu"
6
+ gem "rspec"
@@ -4,18 +4,13 @@ confdir = File.dirname(__FILE__)+"/config"
4
4
  $: << confdir
5
5
 
6
6
  require 'environment'
7
- require 'gamebox/tasks/gamebox_tasks'
7
+ $: << GAMEBOX_PATH
8
+ load "tasks/gamebox_tasks.rake"
8
9
  STATS_DIRECTORIES = [
9
10
  %w(Source src/),
10
11
  %w(Config config/),
11
12
  %w(Maps maps/),
12
13
  %w(Unit\ tests specs/),
13
14
  %w(Libraries lib/),
14
- ].collect { |name, dir| [ name, "#{dir}" ] }.select { |name, dir| File.directory?(dir) }
15
-
16
- desc "Report code statistics (KLOCs, etc) from the application"
17
- task :stats do
18
- require 'code_statistics'
19
- CodeStatistics.new(*STATS_DIRECTORIES).to_s
20
- end
15
+ ].collect { |name, dir| [ name, "#{APP_ROOT}/#{dir}" ] }.select { |name, dir| File.directory?(dir) }
21
16
 
@@ -1,29 +1,4 @@
1
-
2
- unless ENV['OCRA_EXECUTABLE'].nil?
3
- APP_ROOT = "#{File.join(File.dirname($0),"..")}/"
4
- Dir.chdir(File.join(File.dirname($0),"..",'src'))
5
- else
6
- APP_ROOT = "#{File.join(File.dirname($0),"..")}/"
7
- end
8
-
9
- gems = Dir[APP_ROOT+"vendor/gems/*"]
10
- gems.each do |bundled_gem|
11
- $:.unshift bundled_gem+"/lib"
12
- end
13
-
14
- ADDITIONAL_LOAD_PATHS = []
15
- ADDITIONAL_LOAD_PATHS.concat %w(
16
- src
17
- lib
18
- config
19
- ../../lib
20
- ).map { |dir| File.join(APP_ROOT,dir) }
21
-
22
- ADDITIONAL_LOAD_PATHS.each do |path|
23
- $:.unshift path
24
- end
25
-
26
-
1
+ APP_ROOT = "#{File.join(File.dirname(__FILE__),"..")}/"
27
2
 
28
3
  CONFIG_PATH = APP_ROOT + "config/"
29
4
  DATA_PATH = APP_ROOT + "data/"
@@ -32,24 +7,17 @@ MUSIC_PATH = APP_ROOT + "data/music/"
32
7
  GFX_PATH = APP_ROOT + "data/graphics/"
33
8
  FONTS_PATH = APP_ROOT + "data/fonts/"
34
9
 
35
- require 'rubygems'
10
+ require 'gamebox'
36
11
 
37
- # Set up gems listed in the Gemfile.
38
- gemfile = File.expand_path('../../Gemfile', __FILE__)
39
- begin
40
- ENV['BUNDLE_GEMFILE'] = gemfile
41
- require 'bundler'
42
- Bundler.setup
43
- rescue Bundler::GemNotFound => e
44
- STDERR.puts e.message
45
- STDERR.puts "Try running `bundle install`."
46
- exit!
47
- end if File.exist?(gemfile)
12
+ [GAMEBOX_PATH, APP_ROOT, File.join(APP_ROOT,'src')].each{|path| $: << path }
13
+ require "gamebox_application"
48
14
 
49
- require 'gamebox'
15
+ require_all Dir.glob("**/*.rb").reject{ |f| f.match("spec") || f.match("src/app.rb")}
50
16
 
51
17
  GAMEBOX_DATA_PATH = GAMEBOX_PATH + "data/"
52
18
  GAMEBOX_SOUND_PATH = GAMEBOX_PATH + "data/sounds/"
53
19
  GAMEBOX_MUSIC_PATH = GAMEBOX_PATH + "data/music/"
54
20
  GAMEBOX_GFX_PATH = GAMEBOX_PATH + "data/graphics/"
55
21
  GAMEBOX_FONTS_PATH = GAMEBOX_PATH + "data/fonts/"
22
+
23
+ GAME_NAME = "UntitledGame"
@@ -1,8 +1,7 @@
1
- require 'stage'
2
1
  class DemoStage < Stage
3
2
  def setup
4
3
  super
5
- @my_actor = create_actor :my_actor, :x => 10, :y => 10
4
+ @my_actor = spawn :my_actor, :x => 10, :y => 10
6
5
  end
7
6
 
8
7
  def draw(target)
@@ -1,6 +1,3 @@
1
- require 'actor'
2
- require 'actor_view'
3
-
4
1
  class MyActorView < ActorView
5
2
  def draw(target, x_off, y_off, z)
6
3
  target.draw_box @actor.x,@actor.y, 20, 20, [240,45,45,255], 1
@@ -1,8 +1,8 @@
1
1
  module Gamebox
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 2
5
- TINY = 1
4
+ MINOR = 3
5
+ TINY = 2
6
6
 
7
7
  ARRAY = [MAJOR, MINOR, TINY]
8
8
  STRING = ARRAY.join('.')
@@ -1,6 +1,3 @@
1
- require 'numbers_ext'
2
- require 'publisher'
3
-
4
1
  # Viewport represents the current "camera" location. Essensially it translates from
5
2
  # world to screen coords and from screen coords to world coords.
6
3
  class Viewport
@@ -8,13 +5,16 @@ class Viewport
8
5
  can_fire :scrolled
9
6
 
10
7
  attr_accessor :x_offset, :y_offset, :follow_target, :width,
11
- :height, :x_offset_range, :y_offset_range
8
+ :height, :x_offset_range, :y_offset_range, :boundary
9
+
10
+ attr_reader :speed
12
11
 
13
12
  def debug
14
13
  "xoff:#{@x_offset} yoff:#{@y_offset}"
15
14
  end
16
15
 
17
16
  def initialize(width, height)
17
+ @speed = 1
18
18
  @x_offset = 0
19
19
  @y_offset = 0
20
20
 
@@ -29,6 +29,16 @@ class Viewport
29
29
  fire :scrolled
30
30
  end
31
31
 
32
+ def speed=(new_speed)
33
+ if new_speed > 1
34
+ @speed = 1
35
+ elsif new_speed < 0
36
+ @speed = 0
37
+ else
38
+ @speed = new_speed
39
+ end
40
+ end
41
+
32
42
  def x_offset(layer=1)
33
43
  return 0 if layer == Float::INFINITY
34
44
  return @x_offset if layer == 1
@@ -58,10 +68,11 @@ class Viewport
58
68
  if x_diff.abs > @buffer_x
59
69
  # move screen
60
70
  if x_diff > 0
61
- @x_offset += x_diff - @buffer_x
71
+ @x_offset += (x_diff - @buffer_x) * @speed
62
72
  else
63
- @x_offset += x_diff + @buffer_x
73
+ @x_offset += (x_diff + @buffer_x) * @speed
64
74
  end
75
+
65
76
  scrolled = true
66
77
  end
67
78
 
@@ -70,17 +81,36 @@ class Viewport
70
81
  if y_diff.abs > @buffer_y
71
82
  # move screen
72
83
  if y_diff > 0
73
- @y_offset += y_diff - @buffer_y
84
+ @y_offset += (y_diff - @buffer_y) * @speed
74
85
  else
75
- @y_offset += y_diff + @buffer_y
86
+ @y_offset += (y_diff + @buffer_y) * @speed
76
87
  end
77
88
  scrolled = true
78
89
  end
79
90
 
91
+ # constrain_x_offset
92
+ if @boundary
93
+ if @x_offset > 0 - @boundary[0] # Left-wall bump
94
+ @x_offset = @boundary[0]
95
+ elsif @x_offset < @width - @boundary[2] # right-wall bump
96
+ @x_offset = @width - @boundary[2]
97
+ end
98
+ end
99
+
100
+ # constrain_y_offset
101
+ if @boundary
102
+ if @y_offset > 0 - @boundary[1]
103
+ @y_offset = @boundary[1]
104
+ elsif @y_offset < @height - @boundary[3]
105
+ @y_offset = @height - @boundary[3]
106
+ end
107
+ end
108
+
80
109
  fire :scrolled if scrolled
81
110
  end
82
111
  end
83
112
 
113
+
84
114
  def follow(target, off=[0,0], buff=[0,0])
85
115
  @follow_target = target
86
116
  @follow_offset_x = off[0]
@@ -94,4 +124,10 @@ class Viewport
94
124
  fire :scrolled
95
125
  end
96
126
 
127
+ def bounds
128
+ left = -@x_offset
129
+ top = -@y_offset
130
+ [left, top, left + @width, top + @height]
131
+ end
132
+
97
133
  end