gamebox 0.0.8 → 0.0.9

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