gamebox 0.2.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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