gamebox 0.0.8 → 0.0.9

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.
@@ -67,3 +67,9 @@
67
67
  * Cleaning up APIs
68
68
  * Adding basic collision detection system
69
69
  * added timers to stage for calling blocks on an interval
70
+
71
+ === 0.0.9 / 2010-02-18
72
+
73
+ * bug fixes for rspec requires
74
+ * cleaning up docs
75
+ * added support for stagehands
data/README.txt CHANGED
@@ -19,7 +19,7 @@
19
19
  * Rubygame (its dependancies, SDL)
20
20
  * constructor gem
21
21
  * publisher gem
22
- * rsepec (for gamebox tests)
22
+ * rspec (for gamebox tests)
23
23
  * algorithms gem (optional for line of site and A*)
24
24
 
25
25
  == INSTALL:
data/Rakefile CHANGED
@@ -34,18 +34,23 @@ task :stats do
34
34
  CodeStatistics.new(*STATS_DIRECTORIES).to_s
35
35
  end
36
36
 
37
- require 'spec/rake/spectask'
38
- desc "Run all rspecs"
39
- Spec::Rake::SpecTask.new(:spec) do |t|
40
- t.spec_files = FileList['spec/*_spec.rb']
41
- end
42
- task :default => :spec
37
+ begin
38
+ require 'spec/rake/spectask'
39
+ desc "Run all rspecs"
40
+ Spec::Rake::SpecTask.new(:spec) do |t|
41
+ t.spec_files = FileList['spec/*_spec.rb']
42
+ end
43
+ task :default => :spec
43
44
 
44
- desc "Run rcov rspecs"
45
- Spec::Rake::SpecTask.new('rcov_rspec') do |t|
46
- t.spec_files = FileList['spec/*_spec.rb']
47
- t.rcov = true
48
- t.rcov_opts = ['--exclude', 'examples']
45
+ desc "Run rcov rspecs"
46
+ Spec::Rake::SpecTask.new('rcov_rspec') do |t|
47
+ t.spec_files = FileList['spec/*_spec.rb']
48
+ t.rcov = true
49
+ t.rcov_opts = ['--exclude', 'examples']
50
+ end
51
+ rescue LoadError
52
+ puts "please install rspec to run tests"
53
+ puts "install with gem install rspec"
49
54
  end
50
55
 
51
56
  # vim: syntax=Ruby
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.8
1
+ 0.0.9
@@ -2,6 +2,7 @@
2
2
 
3
3
  Signal.trap("INT") { puts; exit }
4
4
 
5
+ require 'yaml'
5
6
  require File.dirname(__FILE__) + '/../lib/gamebox/version'
6
7
 
7
8
  def print_version
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{gamebox}
8
- s.version = "0.0.8"
8
+ s.version = "0.0.9"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Shawn Anderson", "Jason Roelofs", "Karlin Fox"]
12
- s.date = %q{2010-02-18}
12
+ s.date = %q{2010-04-10}
13
13
  s.default_executable = %q{gamebox}
14
14
  s.description = %q{Framework for building and distributing games using Rubygame}
15
15
  s.email = %q{shawn42@gmail.com}
@@ -38,10 +38,6 @@ Gem::Specification.new do |s|
38
38
  "lib/gamebox/actors/logo.rb",
39
39
  "lib/gamebox/actors/score.rb",
40
40
  "lib/gamebox/actors/svg_actor.rb",
41
- "lib/gamebox/ai/line_of_site.rb",
42
- "lib/gamebox/ai/polaris.rb",
43
- "lib/gamebox/ai/two_d_grid_location.rb",
44
- "lib/gamebox/ai/two_d_grid_map.rb",
45
41
  "lib/gamebox/arbiter.rb",
46
42
  "lib/gamebox/backstage.rb",
47
43
  "lib/gamebox/behavior.rb",
@@ -86,9 +82,11 @@ Gem::Specification.new do |s|
86
82
  "lib/gamebox/physics.rb",
87
83
  "lib/gamebox/resource_manager.rb",
88
84
  "lib/gamebox/sound_manager.rb",
85
+ "lib/gamebox/spatial_hash.rb",
89
86
  "lib/gamebox/spec/helper.rb",
90
87
  "lib/gamebox/stage.rb",
91
88
  "lib/gamebox/stage_manager.rb",
89
+ "lib/gamebox/stagehand.rb",
92
90
  "lib/gamebox/svg_document.rb",
93
91
  "lib/gamebox/tasks/gamebox_tasks.rb",
94
92
  "lib/gamebox/templates/actor.erb",
@@ -106,7 +104,6 @@ Gem::Specification.new do |s|
106
104
  "lib/gamebox/templates/template_app/data/graphics/GRAPHICS_GO_HERE",
107
105
  "lib/gamebox/templates/template_app/data/music/MUSIC_GOES_HERE",
108
106
  "lib/gamebox/templates/template_app/data/sounds/SOUND_FX_GO_HERE",
109
- "lib/gamebox/templates/template_app/doc/README_FOR_APP",
110
107
  "lib/gamebox/templates/template_app/script/generate",
111
108
  "lib/gamebox/templates/template_app/spec/helper.rb",
112
109
  "lib/gamebox/templates/template_app/src/app.rb",
@@ -126,10 +123,9 @@ Gem::Specification.new do |s|
126
123
  "spec/collidable_spec.rb",
127
124
  "spec/helper.rb",
128
125
  "spec/label_spec.rb",
129
- "spec/line_of_site_spec.rb",
130
126
  "spec/physical_spec.rb",
131
- "spec/polaris_spec.rb",
132
127
  "spec/resource_manager_spec.rb",
128
+ "spec/spatial_hash_spec.rb",
133
129
  "spec/stage_spec.rb",
134
130
  "spec/viewport_spec.rb"
135
131
  ]
@@ -137,7 +133,7 @@ Gem::Specification.new do |s|
137
133
  s.rdoc_options = ["--charset=UTF-8"]
138
134
  s.require_paths = ["lib"]
139
135
  s.rubyforge_project = %q{gamebox}
140
- s.rubygems_version = %q{1.3.5}
136
+ s.rubygems_version = %q{1.3.6}
141
137
  s.summary = %q{Framework for building and distributing games using Rubygame}
142
138
  s.test_files = [
143
139
  "spec/actor_spec.rb",
@@ -148,10 +144,9 @@ Gem::Specification.new do |s|
148
144
  "spec/collidable_spec.rb",
149
145
  "spec/helper.rb",
150
146
  "spec/label_spec.rb",
151
- "spec/line_of_site_spec.rb",
152
147
  "spec/physical_spec.rb",
153
- "spec/polaris_spec.rb",
154
148
  "spec/resource_manager_spec.rb",
149
+ "spec/spatial_hash_spec.rb",
155
150
  "spec/stage_spec.rb",
156
151
  "spec/viewport_spec.rb"
157
152
  ]
@@ -26,28 +26,34 @@ module Arbiter
26
26
  second_objs.each do |sobj|
27
27
  # puts "registering #{fobj} and #{sobj}"
28
28
  @collision_handlers[fobj] ||= {}
29
+ @collision_handlers[sobj] ||= {}
29
30
  @collision_handlers[fobj][sobj] = block
31
+ @collision_handlers[sobj][fobj] = block
30
32
  end
31
33
  end
32
34
  end
33
35
 
34
- # TODO how is this going to get called?, method chaining update?
35
36
  def find_collisions
37
+ @collidable_actors ||= []
36
38
  collisions = []
37
- @collidable_actors.size.times do |i|
38
- first = @collidable_actors[i]
39
- (@collidable_actors.size).times do |j|
40
- second = @collidable_actors[i-j]
39
+ tmp_collidable_actors = @collidable_actors.dup
40
+
41
+ @collidable_actors.each do |first|
42
+
43
+ tmp_collidable_actors.delete first
41
44
 
45
+ tmp_collidable_actors.each do |second|
42
46
  if collide?(first, second)
43
47
  collisions << [first,second]
44
48
  end
45
49
  end
50
+
46
51
  end
47
52
 
48
53
  collisions.each do |collision|
49
54
  first = collision.first
50
55
  second = collision.last
56
+
51
57
  colliders = @collision_handlers[first.actor_type]
52
58
  callback = colliders[second.actor_type] unless colliders.nil?
53
59
  callback.call first, second unless callback.nil?
@@ -5,4 +5,8 @@ class Updatable < Behavior
5
5
  def setup
6
6
  @actor.director.add_actor @actor
7
7
  end
8
+
9
+ def removed
10
+ @actor.director.remove_actor @actor
11
+ end
8
12
  end
@@ -20,6 +20,8 @@ require 'class_finder'
20
20
  require 'actor_factory'
21
21
  require 'input_manager'
22
22
 
23
+ require 'stagehand'
24
+
23
25
  class GameboxApp
24
26
  attr_reader :context, :game
25
27
  def self.run(argv,env)
@@ -2,6 +2,14 @@
2
2
  require 'inflector'
3
3
  $: << File.join(File.dirname(__FILE__),'generators')
4
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
+
5
13
  def print_usage
6
14
  puts "generate what *opts"
7
15
  puts "TODO list all generators here"
@@ -92,8 +92,6 @@ class InputManager
92
92
  case event
93
93
  when KeyPressed
94
94
  case event.key
95
- when :f
96
- puts "Framerate:#{@clock.framerate}"
97
95
  when @auto_quit
98
96
  throw :rubygame_quit
99
97
  end
@@ -156,8 +154,10 @@ class InputManager
156
154
  if event_ids.empty?
157
155
  @non_id_hooks[event_class] << block
158
156
  end
159
- listener.when :remove_me do
160
- unregister_hook event_class, *event_ids, &block
157
+ if listener.respond_to?(:can_fire?) && listener.can_fire?(:remove_me)
158
+ listener.when :remove_me do
159
+ unregister_hook event_class, *event_ids, &block
160
+ end
161
161
  end
162
162
  end
163
163
 
@@ -53,7 +53,7 @@ class SoundManager
53
53
  volume = opts.delete :volume
54
54
  @sound_thread = Thread.new do
55
55
  @sounds[what].volume = volume if volume
56
- @sounds[what].play opts
56
+ @sounds[what].dup.play opts
57
57
  end
58
58
  end
59
59
  end
@@ -0,0 +1,86 @@
1
+ class SpatialHash
2
+
3
+ attr_accessor :cell_size
4
+
5
+ def initialize(cell_size)
6
+ @cell_size = cell_size.to_f
7
+ @buckets = {}
8
+ @items = []
9
+ end
10
+
11
+ def rehash
12
+ items = @items
13
+ @items = []
14
+ @buckets = {}
15
+ items.each do |item|
16
+ add item
17
+ end
18
+ end
19
+
20
+ def add(item)
21
+ buckets = lookup item
22
+ buckets.each do |bucket|
23
+ x,y = *bucket
24
+ @buckets[x] ||= {}
25
+ @buckets[x][y] ||= []
26
+ target_bucket = @buckets[x][y]
27
+ unless target_bucket.include? item
28
+ target_bucket << item
29
+ @items << item
30
+ end
31
+ end
32
+ end
33
+
34
+ def lookup(item)
35
+ w = 1
36
+ h = 1
37
+ w = item.width if item.respond_to? :width
38
+ h = item.height if item.respond_to? :height
39
+ x = item.x
40
+ y = item.y
41
+ min_x, min_y = bucket_for x, y
42
+ if w == 1 && h == 1
43
+ max_x = min_x
44
+ max_y = min_y
45
+ else
46
+ max_x, max_y = bucket_for x+w-1, y+h-1
47
+ end
48
+
49
+ buckets = []
50
+ (max_x-min_x+1).times do |i|
51
+ (max_y-min_y+1).times do |j|
52
+ buckets << [min_x+i,min_y+j]
53
+ end
54
+ end
55
+
56
+ buckets
57
+ end
58
+
59
+ def bucket_for(x,y)
60
+ bucket_x = (x/cell_size).floor
61
+ bucket_y = (y/cell_size).floor
62
+ return [bucket_x, bucket_y]
63
+ end
64
+
65
+ def remove(item)
66
+ buckets = lookup item
67
+ buckets.each do |bucket|
68
+ x,y = *bucket
69
+ return if @buckets[x].nil? || @buckets[x][y].nil?
70
+ @buckets[x][y].delete item
71
+ end
72
+ @items.delete item
73
+ end
74
+
75
+ def items_at(x,y)
76
+ bucket_x = (x/@cell_size).floor
77
+ bucket_y = (y/@cell_size).floor
78
+ if @buckets[bucket_x].nil? || @buckets[bucket_x][bucket_y].nil?
79
+ return []
80
+ else
81
+ @buckets[bucket_x][bucket_y]
82
+ end
83
+ end
84
+
85
+ end
86
+
@@ -30,6 +30,7 @@ class Stage
30
30
  @actor_factory.director = @director
31
31
  @backstage = backstage
32
32
 
33
+ @stagehands = {}
33
34
  @opts = opts
34
35
 
35
36
  setup
@@ -77,6 +78,10 @@ class Stage
77
78
  def update(time)
78
79
  @director.update time
79
80
  @viewport.update time
81
+ @stagehands.each do |name, stagehand|
82
+ stagehand.update time if stagehand.respond_to? :update
83
+ end
84
+ # TODO can we change collisions to be a stagehand
80
85
  find_collisions unless @collidable_actors.nil?
81
86
  update_timers time
82
87
  end
@@ -206,5 +211,20 @@ class Stage
206
211
  listener.call
207
212
  end
208
213
  end
214
+
215
+ def stagehand(stagehand_sym, opts={})
216
+ @stagehands[stagehand_sym] ||= create_stagehand(stagehand_sym, opts)
217
+ end
218
+
219
+ def create_stagehand(name, opts)
220
+ underscored_class = "#{name}_stagehand"
221
+ begin
222
+ require underscored_class
223
+ rescue LoadError
224
+ # TODO log this?
225
+ end
226
+ klass = ClassFinder.find underscored_class
227
+ klass.new self, opts
228
+ end
209
229
  end
210
230
 
@@ -0,0 +1,11 @@
1
+ class Stagehand
2
+ attr_accessor :opts, :stage
3
+ def initialize(stage, opts)
4
+ @stage = stage
5
+ @opts = opts
6
+ setup
7
+ end
8
+
9
+ def setup
10
+ end
11
+ end
@@ -1,5 +1,4 @@
1
1
  require 'gamebox/lib/platform'
2
- require 'spec/rake/spectask'
3
2
 
4
3
  task :default => :run
5
4
  desc "Run the game"
@@ -27,11 +26,16 @@ task :debug do |t|
27
26
  end
28
27
  end
29
28
 
30
- require 'spec/rake/spectask'
31
- desc "Run all specs"
32
- Spec::Rake::SpecTask.new('spec') do |t|
33
- t.spec_opts = ["-r", "./spec/helper"]
34
- t.spec_files = FileList['spec//*_spec.rb']
29
+ begin
30
+ require 'spec/rake/spectask'
31
+ desc "Run all specs"
32
+ Spec::Rake::SpecTask.new('spec') do |t|
33
+ t.spec_opts = ["-r", "./spec/helper"]
34
+ t.spec_files = FileList['spec//*_spec.rb']
35
+ end
36
+ task :rspec => :spec
37
+ task :test => :spec
38
+ rescue LoadError
39
+ puts "warning: rspec not installed"
40
+ puts "install with gem install rspec"
35
41
  end
36
- task :rspec => :spec
37
- task :test => :spec
@@ -3,6 +3,7 @@ $: << libdir
3
3
  confdir = File.dirname(__FILE__)+"/config"
4
4
  $: << confdir
5
5
 
6
+ ENV["RUBYGAME_NOINIT"]="1"
6
7
  require 'environment'
7
8
  require 'gamebox/tasks/gamebox_tasks'
8
9
  STATS_DIRECTORIES = [
@@ -2,7 +2,7 @@ module Gamebox
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 0
5
- TINY = 8
5
+ TINY = 9
6
6
 
7
7
  ARRAY = [MAJOR, MINOR, TINY]
8
8
  STRING = ARRAY.join('.')
@@ -0,0 +1,96 @@
1
+ require 'helper'
2
+ require 'spatial_hash'
3
+
4
+ describe 'a new SpacialHash' do
5
+ before do
6
+ @hash = SpatialHash.new 10
7
+ end
8
+ it 'should be constructable' do
9
+ @hash.cell_size.should == 10
10
+ end
11
+
12
+ it 'can add a point' do
13
+ pt = Point.new 2, 3
14
+ @hash.add pt
15
+ @hash.instance_variable_get('@buckets')[0][0].first.should == pt
16
+ end
17
+
18
+ it 'can add a neg point' do
19
+ pt = Point.new -2, 3
20
+ @hash.add pt
21
+ @hash.instance_variable_get('@buckets')[-1][0].first.should == pt
22
+ end
23
+
24
+ it 'can add a square' do
25
+ box = Item.new 2, 3, 12, 13
26
+ @hash.add box
27
+
28
+ buckets = @hash.instance_variable_get('@buckets')
29
+ buckets[0][0].first.should == box
30
+ buckets[0][1].first.should == box
31
+ buckets[1][0].first.should == box
32
+ buckets[1][1].first.should == box
33
+ end
34
+
35
+ it 'can add a box' do
36
+ box = Item.new 3, 3, 12, 2
37
+ @hash.add box
38
+
39
+ buckets = @hash.instance_variable_get('@buckets')
40
+ buckets[0][0].first.should == box
41
+ buckets[1][0].first.should == box
42
+
43
+ buckets[1][1].should be_nil
44
+ buckets[0][1].should be_nil
45
+ end
46
+
47
+ it 'can remove points' do
48
+ pt = Point.new -2, 3
49
+ @hash.add pt
50
+ @hash.remove pt
51
+
52
+ @hash.instance_variable_get('@buckets')[-1][0].should be_empty
53
+ end
54
+
55
+ it 'can remove boxes' do
56
+ box = Item.new 2, 3, 12, 13
57
+ @hash.add box
58
+
59
+ @hash.remove box
60
+
61
+ @hash.instance_variable_get('@buckets')[0][0].should be_empty
62
+ @hash.instance_variable_get('@buckets')[0][1].should be_empty
63
+ @hash.instance_variable_get('@buckets')[1][0].should be_empty
64
+ @hash.instance_variable_get('@buckets')[1][1].should be_empty
65
+ end
66
+
67
+ it 'can lookup objects for an x,y location' do
68
+ box = Item.new 2, 3, 12, 13
69
+ @hash.add box
70
+
71
+ @hash.items_at(5, 7).include?(box).should be_true
72
+ end
73
+
74
+ it 'can rehash all the items' do
75
+ box = Item.new 2, 3, 12, 13
76
+ @hash.add box
77
+ @hash.rehash
78
+
79
+ buckets = @hash.instance_variable_get('@buckets')
80
+ buckets[0][0].first.should == box
81
+ buckets[0][1].first.should == box
82
+ buckets[1][0].first.should == box
83
+ buckets[1][1].first.should == box
84
+ end
85
+ end
86
+
87
+ class Point
88
+ attr_accessor :x,:y
89
+ def initialize(x,y);@x=x;@y=y;end
90
+ end
91
+
92
+ class Item < Point
93
+ def initialize(x,y,w=1,h=1);@x=x;@y=y;@w=w;@h=h;end
94
+ def width;@w;end
95
+ def height;@h;end
96
+ end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gamebox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 9
9
+ version: 0.0.9
5
10
  platform: ruby
6
11
  authors:
7
12
  - Shawn Anderson
@@ -11,59 +16,69 @@ autorequire:
11
16
  bindir: bin
12
17
  cert_chain: []
13
18
 
14
- date: 2010-02-18 00:00:00 -05:00
19
+ date: 2010-04-10 00:00:00 -04:00
15
20
  default_executable: gamebox
16
21
  dependencies:
17
22
  - !ruby/object:Gem::Dependency
18
23
  name: rspec
19
- type: :development
20
- version_requirement:
21
- version_requirements: !ruby/object:Gem::Requirement
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
22
26
  requirements:
23
27
  - - ">="
24
28
  - !ruby/object:Gem::Version
29
+ segments:
30
+ - 0
25
31
  version: "0"
26
- version:
32
+ type: :development
33
+ version_requirements: *id001
27
34
  - !ruby/object:Gem::Dependency
28
35
  name: jeweler
29
- type: :development
30
- version_requirement:
31
- version_requirements: !ruby/object:Gem::Requirement
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
32
38
  requirements:
33
39
  - - ">="
34
40
  - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
35
43
  version: "0"
36
- version:
44
+ type: :development
45
+ version_requirements: *id002
37
46
  - !ruby/object:Gem::Dependency
38
47
  name: rubygame
39
- type: :runtime
40
- version_requirement:
41
- version_requirements: !ruby/object:Gem::Requirement
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
42
50
  requirements:
43
51
  - - ">="
44
52
  - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
45
55
  version: "0"
46
- version:
56
+ type: :runtime
57
+ version_requirements: *id003
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: constructor
49
- type: :runtime
50
- version_requirement:
51
- version_requirements: !ruby/object:Gem::Requirement
60
+ prerelease: false
61
+ requirement: &id004 !ruby/object:Gem::Requirement
52
62
  requirements:
53
63
  - - ">="
54
64
  - !ruby/object:Gem::Version
65
+ segments:
66
+ - 0
55
67
  version: "0"
56
- version:
68
+ type: :runtime
69
+ version_requirements: *id004
57
70
  - !ruby/object:Gem::Dependency
58
71
  name: publisher
59
- type: :runtime
60
- version_requirement:
61
- version_requirements: !ruby/object:Gem::Requirement
72
+ prerelease: false
73
+ requirement: &id005 !ruby/object:Gem::Requirement
62
74
  requirements:
63
75
  - - ">="
64
76
  - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
65
79
  version: "0"
66
- version:
80
+ type: :runtime
81
+ version_requirements: *id005
67
82
  description: Framework for building and distributing games using Rubygame
68
83
  email: shawn42@gmail.com
69
84
  executables:
@@ -93,10 +108,6 @@ files:
93
108
  - lib/gamebox/actors/logo.rb
94
109
  - lib/gamebox/actors/score.rb
95
110
  - lib/gamebox/actors/svg_actor.rb
96
- - lib/gamebox/ai/line_of_site.rb
97
- - lib/gamebox/ai/polaris.rb
98
- - lib/gamebox/ai/two_d_grid_location.rb
99
- - lib/gamebox/ai/two_d_grid_map.rb
100
111
  - lib/gamebox/arbiter.rb
101
112
  - lib/gamebox/backstage.rb
102
113
  - lib/gamebox/behavior.rb
@@ -141,9 +152,11 @@ files:
141
152
  - lib/gamebox/physics.rb
142
153
  - lib/gamebox/resource_manager.rb
143
154
  - lib/gamebox/sound_manager.rb
155
+ - lib/gamebox/spatial_hash.rb
144
156
  - lib/gamebox/spec/helper.rb
145
157
  - lib/gamebox/stage.rb
146
158
  - lib/gamebox/stage_manager.rb
159
+ - lib/gamebox/stagehand.rb
147
160
  - lib/gamebox/svg_document.rb
148
161
  - lib/gamebox/tasks/gamebox_tasks.rb
149
162
  - lib/gamebox/templates/actor.erb
@@ -161,7 +174,6 @@ files:
161
174
  - lib/gamebox/templates/template_app/data/graphics/GRAPHICS_GO_HERE
162
175
  - lib/gamebox/templates/template_app/data/music/MUSIC_GOES_HERE
163
176
  - lib/gamebox/templates/template_app/data/sounds/SOUND_FX_GO_HERE
164
- - lib/gamebox/templates/template_app/doc/README_FOR_APP
165
177
  - lib/gamebox/templates/template_app/script/generate
166
178
  - lib/gamebox/templates/template_app/spec/helper.rb
167
179
  - lib/gamebox/templates/template_app/src/app.rb
@@ -181,10 +193,9 @@ files:
181
193
  - spec/collidable_spec.rb
182
194
  - spec/helper.rb
183
195
  - spec/label_spec.rb
184
- - spec/line_of_site_spec.rb
185
196
  - spec/physical_spec.rb
186
- - spec/polaris_spec.rb
187
197
  - spec/resource_manager_spec.rb
198
+ - spec/spatial_hash_spec.rb
188
199
  - spec/stage_spec.rb
189
200
  - spec/viewport_spec.rb
190
201
  has_rdoc: true
@@ -200,18 +211,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
200
211
  requirements:
201
212
  - - ">="
202
213
  - !ruby/object:Gem::Version
214
+ segments:
215
+ - 0
203
216
  version: "0"
204
- version:
205
217
  required_rubygems_version: !ruby/object:Gem::Requirement
206
218
  requirements:
207
219
  - - ">="
208
220
  - !ruby/object:Gem::Version
221
+ segments:
222
+ - 0
209
223
  version: "0"
210
- version:
211
224
  requirements: []
212
225
 
213
226
  rubyforge_project: gamebox
214
- rubygems_version: 1.3.5
227
+ rubygems_version: 1.3.6
215
228
  signing_key:
216
229
  specification_version: 3
217
230
  summary: Framework for building and distributing games using Rubygame
@@ -224,9 +237,8 @@ test_files:
224
237
  - spec/collidable_spec.rb
225
238
  - spec/helper.rb
226
239
  - spec/label_spec.rb
227
- - spec/line_of_site_spec.rb
228
240
  - spec/physical_spec.rb
229
- - spec/polaris_spec.rb
230
241
  - spec/resource_manager_spec.rb
242
+ - spec/spatial_hash_spec.rb
231
243
  - spec/stage_spec.rb
232
244
  - spec/viewport_spec.rb
@@ -1,61 +0,0 @@
1
- # LineOfSite is a class for finding neighbors in a map that are visible
2
- class LineOfSite
3
- def initialize(map)
4
- @map = map
5
- end
6
-
7
- def losline(x, y, x2, y2)
8
- brensenham_line(x, y, x2, y2).each do |i|
9
- iterx, itery = *i
10
- occ = @map.occupant(loc2(iterx,itery))
11
- return unless occ
12
- occ.lit = true
13
- occ.seen = true
14
-
15
- return if occ.solid?
16
- end
17
- end
18
-
19
- # Brensenham line algorithm
20
- def brensenham_line(x,y,x2,y2)
21
- steep = false
22
- coords = []
23
- dx = (x2 - x).abs
24
- if (x2 - x) > 0
25
- sx = 1
26
- else
27
- sx = -1
28
- end
29
- dy = (y2 - y).abs
30
- if (y2 - y) > 0
31
- sy = 1
32
- else
33
- sy = -1
34
- end
35
- if dy > dx
36
- steep = true
37
- x,y = y,x
38
- dx,dy = dy,dx
39
- sx,sy = sy,sx
40
- end
41
- d = (2 * dy) - dx
42
-
43
- dx.times do
44
- if steep
45
- coords << [y,x]
46
- else
47
- coords << [x,y]
48
- end
49
- while d >= 0
50
- y = y + sy
51
- d = d - (2 * dx)
52
- end
53
- x = x + sx
54
- d = d + (2 * dy)
55
- end
56
- coords << [x2,y2]
57
-
58
- coords
59
- end
60
-
61
- end
@@ -1,109 +0,0 @@
1
- require 'algorithms'
2
- include Containers
3
-
4
- # Polaris is a star that guides, aka "The North Star". It implements the A* algorithm.
5
- class Polaris
6
- attr_reader :nodes_considered
7
-
8
- def initialize(map)
9
- @map = map
10
- @nodes_considered = 0
11
- end
12
-
13
- # Returns the path without the from location.
14
- # Returns nil if max_depth is hit or if no path exists.
15
- def guide(from, to, unit_type=nil, max_depth=400)
16
- return nil if @map.blocked?(from, unit_type) || @map.blocked?(to, unit_type)
17
- from_element = PathElement.new(from)
18
- from_element.dist_from = @map.distance(from,to)
19
- open = PriorityQueue.new { |x, y| (x <=> y) == -1 }
20
- open.push from_element, from_element.rating
21
- closed = SplayTreeMap.new
22
- step = 0
23
-
24
- until open.empty? || step > max_depth
25
- step += 1
26
-
27
- current_element = open.pop
28
- @nodes_considered += 1
29
-
30
- loc = current_element.location
31
- if @map.cost(loc,to) == 0
32
- path = []
33
- until current_element.parent.nil?
34
- path.unshift current_element
35
- current_element = current_element.parent
36
- end
37
-
38
- return path
39
- else
40
- closed.push current_element.location, current_element
41
- @map.neighbors(loc).each do |next_door|
42
- el = PathElement.new(next_door,current_element)
43
- next if closed.has_key? next_door
44
-
45
- if @map.blocked? next_door, unit_type
46
- #closed.push el.location, el
47
- else
48
- current_rating = current_element.cost_to + @map.cost(loc, next_door)
49
-
50
- # add to open
51
- el.cost_to = current_rating
52
- el.dist_from = @map.distance(next_door,to)
53
-
54
- open.push el, el.rating
55
- end
56
- end
57
- end
58
- end
59
- nil
60
- end
61
- end
62
-
63
- class PathElement
64
- include Comparable
65
-
66
- attr_accessor :location, :parent
67
- attr_reader :cost_to, :dist_from, :rating
68
- def initialize(location=nil,parent=nil)
69
- @location = location
70
- @parent = parent
71
- @cost_to = 0
72
- @dist_from = 0
73
- @rating = 99_999
74
- end
75
-
76
- def cost_to=(new_cost)
77
- @cost_to = new_cost
78
- reset_rating
79
- end
80
-
81
- def dist_from=(new_dist_from)
82
- @dist_from = new_dist_from
83
- reset_rating
84
- end
85
-
86
- def reset_rating
87
- @rating = @cost_to + @dist_from
88
- end
89
-
90
- def to_s
91
- "#{@location} at cost of #{@cost_to} and rating of #{@rating}"
92
- end
93
-
94
- def <=>(b)
95
- a = self
96
- if a.rating < b.rating
97
- return -1
98
- elsif a.rating > b.rating
99
- return 1
100
- else
101
- 0
102
- end
103
- end
104
-
105
- def ==(other)
106
- return false if other.nil?
107
- @location == other.location
108
- end
109
- end
@@ -1,21 +0,0 @@
1
- # TwoDGridLocation exibits an x,y,cost location
2
- class TwoDGridLocation
3
- attr_accessor :x,:y
4
- def initialize(x,y);@x=x;@y=y;end
5
- def ==(other)
6
- @x == other.x and @y == other.y
7
- end
8
-
9
- def <=>(b)
10
- ret = 1
11
- if @x == b.x && @y == b.y
12
- ret = 0
13
- end
14
- ret = -1 if @x <= b.x && @y < b.y
15
- return ret
16
- end
17
-
18
- def to_s
19
- "#{@x},#{@y}"
20
- end
21
- end
@@ -1,81 +0,0 @@
1
- require 'ai/two_d_grid_location'
2
-
3
- # TwoDGridMap exibits the contract that the map requires.
4
- # Works on an X,Y grid that uses Ftors for 2D vectors
5
- class TwoDGridMap
6
- attr_accessor :w, :h
7
- TRAVEL_COST_DIAG = 14
8
- TRAVEL_COST_STRAIGHT = 10
9
-
10
- def initialize(w,h)
11
- @w = w
12
- @h = h
13
- @grid = {}
14
- end
15
-
16
- def size
17
- [@w,@h]
18
- end
19
-
20
- # place thing at location. If thing is nil, location will be placed in the map
21
- def place(location, thing=nil)
22
- thing ||= location
23
- @grid[location.x] ||= {}
24
- @grid[location.x][location.y] = thing
25
- end
26
-
27
- def occupant(location)
28
- @grid[location.x][location.y] if @grid[location.x]
29
- end
30
-
31
- def clear(location)
32
- @grid[location.x] ||= {}
33
- @grid[location.x][location.y] = nil
34
- end
35
-
36
- # is the location available for the specified type
37
- def blocked?(location, type=nil)
38
- return true if type == :blocked
39
- return true if location.x >= @w || location.y >= @h || location.x < 0 || location.y < 0
40
- if @grid[location.x] and @grid[location.x][location.y]
41
- return true
42
- else
43
- return false
44
- end
45
- end
46
-
47
- # returns a list of neighbors and their distance
48
- def neighbors(location)
49
- x = location.x
50
- y = location.y
51
- [
52
- TwoDGridLocation.new(x-1, y-1),
53
- TwoDGridLocation.new(x-1, y+1),
54
- TwoDGridLocation.new(x+1, y-1),
55
- TwoDGridLocation.new(x+1, y+1),
56
- TwoDGridLocation.new(x-1, y),
57
- TwoDGridLocation.new(x+1, y),
58
- TwoDGridLocation.new(x, y-1),
59
- TwoDGridLocation.new(x, y+1)
60
- ]
61
- end
62
-
63
- def distance(from,to)
64
- h_diagonal = [(from.x-to.x).abs, (from.y-to.y).abs].min
65
- h_straight = ((from.x-to.x).abs + (from.y-to.y).abs)
66
- return TRAVEL_COST_DIAG * h_diagonal + TRAVEL_COST_STRAIGHT * (h_straight - 2*h_diagonal)
67
- end
68
-
69
- # return the cost to go from => to (assuming from and to are neighbors)
70
- def cost(from, to)
71
- if from.x == to.x or from.y == to.y
72
- if from.x == to.x and from.y == to.y
73
- 0
74
- else
75
- TRAVEL_COST_STRAIGHT
76
- end
77
- else
78
- TRAVEL_COST_DIAG
79
- end
80
- end
81
- end
@@ -1,12 +0,0 @@
1
- require File.join(File.dirname(__FILE__),'helper')
2
- require 'ai/line_of_site'
3
- require 'ai/two_d_grid_map'
4
-
5
- describe 'A new LineOfSite' do
6
- before do
7
- @map = TwoDGridMap.new 10, 20
8
- @los = LineOfSite.new @map
9
- end
10
-
11
- it 'should be sane'
12
- end
@@ -1,193 +0,0 @@
1
- require File.join(File.dirname(__FILE__),'helper')
2
- require 'ai/polaris'
3
- require 'ai/two_d_grid_map'
4
-
5
- describe 'A new polaris' do
6
- before do
7
- @map = TwoDGridMap.new 10, 20
8
- @pather = Polaris.new @map
9
- end
10
-
11
- it 'should return an empty path if destination is not valid' do
12
- from = TwoDGridLocation.new @map.w-1, @map.h-1
13
- to = TwoDGridLocation.new @map.w, @map.h
14
- @pather.guide(from,to).should be_nil
15
-
16
- to = TwoDGridLocation.new(-1, -1)
17
- @pather.guide(from,to).should be_nil
18
- end
19
-
20
- it 'should return an empty path if start is not valid' do
21
- from = TwoDGridLocation.new @map.w, @map.h
22
- to = TwoDGridLocation.new @map.w-1, @map.h-1
23
- @pather.guide(from,to).should be_nil
24
-
25
- from = TwoDGridLocation.new -1, -1
26
- @pather.guide(from,to).should be_nil
27
- end
28
-
29
- it 'should return the path of "to" for accessible neighbor' do
30
- from = TwoDGridLocation.new 0, 0
31
- to = TwoDGridLocation.new 1, 0
32
-
33
- path = @pather.guide(from,to)
34
- path.should_not be_nil
35
- path.size.should equal(1)
36
-
37
- path.first.cost_to.should equal(TwoDGridMap::TRAVEL_COST_STRAIGHT)
38
- path.first.dist_from.should equal(0)
39
- path.first.location.x.should equal(to.x)
40
- path.first.location.y.should equal(to.y)
41
- end
42
-
43
- it 'should return the right horizontal path of length 2' do
44
- from = TwoDGridLocation.new 0, 0
45
- to = TwoDGridLocation.new 2, 0
46
-
47
- path = @pather.guide(from,to)
48
-
49
- path.should_not be_nil
50
- path.size.should equal(2)
51
-
52
- path.first.location.x.should equal(1)
53
- path.first.location.y.should equal(0)
54
- path.last.location.should == to
55
- end
56
-
57
- it 'should return the left horizontal path of length 2' do
58
- from = TwoDGridLocation.new 2, 0
59
- to = TwoDGridLocation.new 0, 0
60
-
61
- path = @pather.guide(from,to)
62
-
63
- path.should_not be_nil
64
- path.size.should equal(2)
65
-
66
- path.first.location.x.should equal(1)
67
- path.first.location.y.should equal(0)
68
- path.last.location.should == to
69
- end
70
-
71
-
72
- it 'should return the left up diag path of length 2' do
73
- from = TwoDGridLocation.new 2, 2
74
- to = TwoDGridLocation.new 0, 0
75
-
76
- path = @pather.guide(from,to)
77
-
78
- path.should_not be_nil
79
- path.size.should equal(2)
80
-
81
- path.first.location.x.should equal(1)
82
- path.first.location.y.should equal(1)
83
- path.last.location.should == to
84
- end
85
-
86
- it 'should return the right up diag path of length 2' do
87
- from = TwoDGridLocation.new 2, 2
88
- to = TwoDGridLocation.new 4, 0
89
-
90
- path = @pather.guide(from,to)
91
-
92
- path.should_not be_nil
93
- path.size.should equal(2)
94
-
95
- path.first.location.x.should equal(3)
96
- path.first.location.y.should equal(1)
97
- path.last.location.should == to
98
- end
99
-
100
- it 'should return the right down diag path of length 2' do
101
- from = TwoDGridLocation.new 2, 2
102
- to = TwoDGridLocation.new 4, 4
103
-
104
- path = @pather.guide(from,to)
105
-
106
- path.should_not be_nil
107
- path.size.should equal(2)
108
-
109
- path.first.location.x.should equal(3)
110
- path.first.location.y.should equal(3)
111
- path.last.location.should == to
112
- end
113
-
114
- it 'should return the left down diag path of length 2' do
115
- from = TwoDGridLocation.new 2, 2
116
- to = TwoDGridLocation.new 0, 4
117
-
118
- path = @pather.guide(from,to)
119
-
120
- path.should_not be_nil
121
- path.size.should equal(2)
122
-
123
- path.first.location.x.should equal(1)
124
- path.first.location.y.should equal(3)
125
- path.last.location.should == to
126
- end
127
-
128
- it 'should return go around an obstacle' do
129
- from = TwoDGridLocation.new 0, 0
130
- to = TwoDGridLocation.new 2, 0
131
-
132
- in_the_way = TwoDGridLocation.new 1, 0
133
- @map.place in_the_way, "ME"
134
-
135
- path = @pather.guide(from,to)
136
-
137
- path.should_not be_nil
138
- path.size.should equal(2)
139
-
140
- path.first.location.x.should equal(1)
141
- path.first.location.y.should equal(1)
142
- path.last.location.should == to
143
- end
144
-
145
- it 'should return shortest path of horizontal and diag length 5' do
146
- from = TwoDGridLocation.new 0, 0
147
- to = TwoDGridLocation.new 5, 4
148
-
149
- path = @pather.guide(from,to)
150
-
151
- path.should_not be_nil
152
- path.size.should equal(5)
153
-
154
- # make sure that all elements of the path are neighbors
155
- prev_el = PathElement.new from, nil
156
- path.each do |path_el|
157
- @map.neighbors(prev_el.location).include?(path_el.location).should be_true
158
- prev_el = path_el
159
- end
160
-
161
- path.last.location.should == to
162
- end
163
-
164
- it 'should return nil when the shortest path is longer than the max step passed in' do
165
- from = TwoDGridLocation.new 0, 0
166
- to = TwoDGridLocation.new 5, 4
167
-
168
- path = @pather.guide(from,to,nil,4)
169
- path.should == nil
170
- end
171
-
172
- it 'should return nil when the path does not exist for unit type' do
173
- from = TwoDGridLocation.new 0, 0
174
- to = TwoDGridLocation.new 2, 0
175
-
176
- path = @pather.guide(from,to,:blocked)
177
- path.should == nil
178
- end
179
-
180
- it 'should return nil when the path does not exist' do
181
- from = TwoDGridLocation.new 0, 0
182
- to = TwoDGridLocation.new 2, 0
183
-
184
- # put up a wall
185
- @map.h.times do |i|
186
- @map.place TwoDGridLocation.new(1, i), "ME"
187
- end
188
-
189
- path = @pather.guide(from,to)
190
- path.should == nil
191
- @pather.nodes_considered.should == @map.h
192
- end
193
- end