gamebox 0.0.1
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.
- data/History.txt +18 -0
- data/Manifest.txt +85 -0
- data/README.txt +33 -0
- data/Rakefile +42 -0
- data/TODO.txt +29 -0
- data/bin/gamebox +49 -0
- data/docs/gamebox04_big.png +0 -0
- data/docs/getting_started.rdoc +99 -0
- data/docs/logo.png +0 -0
- data/lib/gamebox.rb +6 -0
- data/lib/gamebox/actor.rb +143 -0
- data/lib/gamebox/actor_factory.rb +64 -0
- data/lib/gamebox/actor_view.rb +35 -0
- data/lib/gamebox/ai/line_of_site.rb +61 -0
- data/lib/gamebox/ai/polaris.rb +107 -0
- data/lib/gamebox/ai/two_d_grid_location.rb +21 -0
- data/lib/gamebox/ai/two_d_grid_map.rb +77 -0
- data/lib/gamebox/aliasing.rb +16 -0
- data/lib/gamebox/animated.rb +84 -0
- data/lib/gamebox/behavior.rb +16 -0
- data/lib/gamebox/config_manager.rb +22 -0
- data/lib/gamebox/console_app.rb +39 -0
- data/lib/gamebox/data/fonts/Asimov.ttf +0 -0
- data/lib/gamebox/data/fonts/GAMEBOX_FONTS_GO_HERE +0 -0
- data/lib/gamebox/data/graphics/GAMEBOX_GRAPHICS_GO_HERE +0 -0
- data/lib/gamebox/data/graphics/logo.png +0 -0
- data/lib/gamebox/data/music/GAMEBOX_MUSIC_GOES_HERE +0 -0
- data/lib/gamebox/data/sounds/GAMEBOX_SOUND_FX_GO_HERE +0 -0
- data/lib/gamebox/director.rb +47 -0
- data/lib/gamebox/gamebox_application.rb +77 -0
- data/lib/gamebox/graphical.rb +24 -0
- data/lib/gamebox/graphical_actor_view.rb +31 -0
- data/lib/gamebox/inflections.rb +52 -0
- data/lib/gamebox/inflector.rb +278 -0
- data/lib/gamebox/input_manager.rb +104 -0
- data/lib/gamebox/layered.rb +34 -0
- data/lib/gamebox/level.rb +64 -0
- data/lib/gamebox/linked_list.rb +137 -0
- data/lib/gamebox/logo.rb +11 -0
- data/lib/gamebox/metaclass.rb +6 -0
- data/lib/gamebox/mode.rb +123 -0
- data/lib/gamebox/mode_manager.rb +80 -0
- data/lib/gamebox/numbers_ext.rb +3 -0
- data/lib/gamebox/physical.rb +139 -0
- data/lib/gamebox/physical_director.rb +17 -0
- data/lib/gamebox/physical_level.rb +89 -0
- data/lib/gamebox/physics.rb +27 -0
- data/lib/gamebox/publisher_ext.rb +13 -0
- data/lib/gamebox/resource_manager.rb +122 -0
- data/lib/gamebox/score.rb +35 -0
- data/lib/gamebox/sorted_list.rb +59 -0
- data/lib/gamebox/sound_manager.rb +84 -0
- data/lib/gamebox/surface_ext.rb +37 -0
- data/lib/gamebox/svg_actor.rb +55 -0
- data/lib/gamebox/svg_document.rb +160 -0
- data/lib/gamebox/template_app/README +30 -0
- data/lib/gamebox/template_app/Rakefile +20 -0
- data/lib/gamebox/template_app/config/boot.rb +5 -0
- data/lib/gamebox/template_app/config/environment.rb +29 -0
- data/lib/gamebox/template_app/config/game.yml +6 -0
- data/lib/gamebox/template_app/config/mode_level_config.yml +3 -0
- data/lib/gamebox/template_app/config/objects.yml +29 -0
- data/lib/gamebox/template_app/data/fonts/FONTS_GO_HERE +0 -0
- data/lib/gamebox/template_app/data/graphics/GRAPHICS_GO_HERE +0 -0
- data/lib/gamebox/template_app/data/music/MUSIC_GOES_HERE +0 -0
- data/lib/gamebox/template_app/data/sounds/SOUND_FX_GO_HERE +0 -0
- data/lib/gamebox/template_app/doc/README_FOR_APP +1 -0
- data/lib/gamebox/template_app/lib/code_statistics.rb +107 -0
- data/lib/gamebox/template_app/lib/diy.rb +371 -0
- data/lib/gamebox/template_app/lib/platform.rb +16 -0
- data/lib/gamebox/template_app/src/app.rb +8 -0
- data/lib/gamebox/template_app/src/demo_level.rb +20 -0
- data/lib/gamebox/template_app/src/game.rb +22 -0
- data/lib/gamebox/template_app/src/my_actor.rb +17 -0
- data/lib/gamebox/version.rb +10 -0
- data/lib/gamebox/viewport.rb +81 -0
- data/lib/gamebox/wrapped_screen.rb +15 -0
- data/script/perf_polaris.rb +36 -0
- data/test/helper.rb +25 -0
- data/test/test_actor.rb +38 -0
- data/test/test_animated.rb +64 -0
- data/test/test_line_of_site.rb +14 -0
- data/test/test_physical.rb +26 -0
- data/test/test_polaris.rb +193 -0
- data/test/test_viewport.rb +116 -0
- metadata +188 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
# Helper functions for determining platform
|
2
|
+
|
3
|
+
# TODO how do I do this in ruby 1.9, since PLATFORM doesn't exist?
|
4
|
+
class Platform
|
5
|
+
def self.mac?
|
6
|
+
return PLATFORM =~ /darwin/
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.windows?
|
10
|
+
return PLATFORM =~ /mswin/
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.linux?
|
14
|
+
return PLATFORM =~ /linux/
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'level'
|
2
|
+
require 'ftor'
|
3
|
+
class DemoLevel < Level
|
4
|
+
def setup
|
5
|
+
@my_actor = create_actor :my_actor
|
6
|
+
@my_actor.x = 10
|
7
|
+
@my_actor.y = 10
|
8
|
+
|
9
|
+
@stars = []
|
10
|
+
20.times { @stars << Ftor.new(rand(@width),rand(@height)) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def draw(target, x_off, y_off)
|
14
|
+
target.fill [25,25,25,255]
|
15
|
+
for star in @stars
|
16
|
+
target.draw_circle_s([star.x,star.y],1,[255,255,255,255])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Game
|
2
|
+
|
3
|
+
constructor :wrapped_screen, :input_manager, :sound_manager,
|
4
|
+
:mode_manager
|
5
|
+
|
6
|
+
def setup
|
7
|
+
# @sound_manager.play :current_rider
|
8
|
+
|
9
|
+
@mode_manager.change_mode_to :default
|
10
|
+
end
|
11
|
+
|
12
|
+
def update(time)
|
13
|
+
@mode_manager.update time
|
14
|
+
draw
|
15
|
+
end
|
16
|
+
|
17
|
+
def draw
|
18
|
+
@mode_manager.draw @wrapped_screen
|
19
|
+
@wrapped_screen.flip
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'actor'
|
2
|
+
require 'actor_view'
|
3
|
+
|
4
|
+
class MyActorView < ActorView
|
5
|
+
def draw(target, x_off, y_off)
|
6
|
+
target.draw_box [@actor.x,@actor.y], [20,20], [240,45,45,255]
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class MyActor < Actor
|
11
|
+
|
12
|
+
def setup
|
13
|
+
# TODO setup stuff here
|
14
|
+
# subscribe for an event or something?
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'numbers_ext'
|
2
|
+
require 'publisher'
|
3
|
+
|
4
|
+
# Viewport represents the current "camera" location. Essensially it translates from
|
5
|
+
# world to screen coords and from screen coords to world coords.
|
6
|
+
class Viewport
|
7
|
+
extend Publisher
|
8
|
+
can_fire :scrolled
|
9
|
+
|
10
|
+
attr_accessor :x_offset, :y_offset, :follow_target, :width,
|
11
|
+
:height
|
12
|
+
|
13
|
+
def debug
|
14
|
+
"xoff:#{@x_offset} yoff:#{@y_offset}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(width, height)
|
18
|
+
@x_offset = 0
|
19
|
+
@y_offset = 0
|
20
|
+
|
21
|
+
@width = width
|
22
|
+
@height = height
|
23
|
+
end
|
24
|
+
|
25
|
+
def x_offset(layer=1)
|
26
|
+
return 0 if layer == Float::Infinity
|
27
|
+
return @x_offset if layer == 1
|
28
|
+
@x_offset / layer
|
29
|
+
end
|
30
|
+
|
31
|
+
def y_offset(layer=1)
|
32
|
+
return 0 if layer == Float::Infinity
|
33
|
+
return @y_offset if layer == 1
|
34
|
+
@y_offset / layer
|
35
|
+
end
|
36
|
+
|
37
|
+
def update(time)
|
38
|
+
scrolled = false
|
39
|
+
if @follow_target
|
40
|
+
x_diff = @width/2 + @follow_offset_x - @follow_target.x - @x_offset
|
41
|
+
if x_diff.abs > @buffer_x
|
42
|
+
# move screen
|
43
|
+
if x_diff > 0
|
44
|
+
@x_offset += x_diff - @buffer_x
|
45
|
+
scrolled = true
|
46
|
+
else
|
47
|
+
@x_offset += x_diff + @buffer_x
|
48
|
+
scrolled = true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
y_diff = @height/2 + @follow_offset_y - @follow_target.y - @y_offset
|
53
|
+
if y_diff.abs > @buffer_y
|
54
|
+
# move screen
|
55
|
+
if y_diff > 0
|
56
|
+
@y_offset += y_diff - @buffer_y
|
57
|
+
scrolled = true
|
58
|
+
else
|
59
|
+
@y_offset += y_diff + @buffer_y
|
60
|
+
scrolled = true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
fire :scrolled if scrolled
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def follow(target, off=[0,0], buff=[0,0])
|
69
|
+
@follow_target = target
|
70
|
+
@follow_offset_x = off[0]
|
71
|
+
@follow_offset_y = off[1]
|
72
|
+
@buffer_x = buff[0]
|
73
|
+
@buffer_y = buff[1]
|
74
|
+
|
75
|
+
@x_offset = @width/2 - @follow_target.x + @follow_offset_x
|
76
|
+
@y_offset = @height/2 - @follow_target.y + @follow_offset_y
|
77
|
+
|
78
|
+
fire :scrolled
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class WrappedScreen
|
2
|
+
constructor :config_manager
|
3
|
+
attr_accessor :screen
|
4
|
+
def setup
|
5
|
+
w,h = @config_manager[:screen_resolution]
|
6
|
+
flags = []
|
7
|
+
flags << HWSURFACE
|
8
|
+
flags << DOUBLEBUF
|
9
|
+
flags << FULLSCREEN if @config_manager[:fullscreen]
|
10
|
+
@screen = Screen.set_mode [w,h], 0, flags
|
11
|
+
end
|
12
|
+
def method_missing(name,*args)
|
13
|
+
@screen.send name, *args
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
$: << File.dirname(__FILE__)+"/../lib/gamebox"
|
2
|
+
|
3
|
+
require 'ai/polaris'
|
4
|
+
require 'ai/two_d_grid_map'
|
5
|
+
|
6
|
+
@map = TwoDGridMap.new 100, 90
|
7
|
+
|
8
|
+
from = TwoDGridLocation.new 0, 0
|
9
|
+
to = TwoDGridLocation.new 9, 0
|
10
|
+
@pather = Polaris.new @map
|
11
|
+
|
12
|
+
require 'benchmark'
|
13
|
+
Benchmark.bm do|b|
|
14
|
+
|
15
|
+
b.report("warm up") do
|
16
|
+
10.times { path = @pather.guide(from,to) }
|
17
|
+
end
|
18
|
+
|
19
|
+
b.report("shorter path") do
|
20
|
+
10.times { path = @pather.guide(from,to) }
|
21
|
+
end
|
22
|
+
|
23
|
+
to = TwoDGridLocation.new 92, 0
|
24
|
+
b.report("longer path") do
|
25
|
+
10.times { path = @pather.guide(from,to) }
|
26
|
+
end
|
27
|
+
|
28
|
+
# put up a wall
|
29
|
+
@map.h.times do |i|
|
30
|
+
@map.place TwoDGridLocation.new(89, i), "ME"
|
31
|
+
end
|
32
|
+
|
33
|
+
b.report("blocked path") do
|
34
|
+
10.times { path = @pather.guide(from,to) }
|
35
|
+
end
|
36
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'gamebox'))
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
require 'bacon'
|
6
|
+
require 'mocha'
|
7
|
+
require 'aliasing'
|
8
|
+
|
9
|
+
class Bacon::Context
|
10
|
+
include Mocha::Standalone
|
11
|
+
def it_with_mocha description
|
12
|
+
it_without_mocha description do
|
13
|
+
mocha_setup
|
14
|
+
yield
|
15
|
+
mocha_verify
|
16
|
+
mocha_teardown
|
17
|
+
end
|
18
|
+
end
|
19
|
+
alias_method_chain :it, :mocha
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
require 'metaclass'
|
24
|
+
require 'actor'
|
25
|
+
|
data/test/test_actor.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'actor'
|
3
|
+
|
4
|
+
describe 'A new actor' do
|
5
|
+
before do
|
6
|
+
opts = {:level=>"level", :input=>"input", :resources=>"resource"}
|
7
|
+
@actor = Actor.new opts
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should be alive' do
|
11
|
+
@actor.alive?.should.equal true
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should be at (0,0)' do
|
15
|
+
@actor.x.should.equal 0
|
16
|
+
@actor.y.should.equal 0
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should have atts set' do
|
20
|
+
@actor.level.should.equal "level"
|
21
|
+
@actor.input_manager.should.equal "input"
|
22
|
+
@actor.resource_manager.should.equal "resource"
|
23
|
+
@actor.behaviors.size.should.equal 0
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should fire anything' do
|
27
|
+
should.not.raise do
|
28
|
+
@actor.when :foofoo_bar do
|
29
|
+
"blah"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should setup behaviors' do
|
35
|
+
should.flunk 'cannot test easily!'
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'animated'
|
3
|
+
require 'mocha'
|
4
|
+
|
5
|
+
describe 'A new animated behavior' do
|
6
|
+
before do
|
7
|
+
@rm = stub(:load_animation_set => ['1.png_img_obj','2.png_img_obj'])
|
8
|
+
|
9
|
+
opts = {:level=>"level", :input=>"input", :resources=>@rm}
|
10
|
+
@actor = Actor.new opts
|
11
|
+
@animated = Animated.new @actor
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should define methods on actor' do
|
15
|
+
@actor.should.respond_to? :image
|
16
|
+
@actor.should.respond_to? :start_animating
|
17
|
+
@actor.should.respond_to? :stop_animating
|
18
|
+
@actor.should.respond_to? :action=
|
19
|
+
@actor.should.respond_to? :animated
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'shouldn\'t update frame for non-animating' do
|
23
|
+
@animated.stop_animating
|
24
|
+
|
25
|
+
@animated.update Animated::FRAME_UPDATE_TIME+1
|
26
|
+
|
27
|
+
@animated.frame_time.should.equal 0
|
28
|
+
@animated.frame_num.should.equal 0
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should update frame for animating' do
|
32
|
+
time_passed = Animated::FRAME_UPDATE_TIME-1
|
33
|
+
@animated.update time_passed
|
34
|
+
@animated.frame_time.should.equal time_passed
|
35
|
+
@animated.frame_num.should.equal 0
|
36
|
+
|
37
|
+
time_passed_again = 2
|
38
|
+
@animated.update time_passed_again
|
39
|
+
# we rolled over the time
|
40
|
+
@animated.frame_time.should.equal 1
|
41
|
+
@animated.frame_num.should.equal 1
|
42
|
+
|
43
|
+
time_passed_again = Animated::FRAME_UPDATE_TIME
|
44
|
+
@animated.update time_passed_again
|
45
|
+
# we rolled over the time
|
46
|
+
@animated.frame_time.should.equal 1
|
47
|
+
@animated.frame_num.should.equal 0
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should stop animating' do
|
51
|
+
@animated.stop_animating
|
52
|
+
@animated.animating.should.equal false
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should start animating' do
|
56
|
+
@animated.start_animating
|
57
|
+
@animated.animating.should.equal true
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should set the action and animate accordingly' do
|
61
|
+
should.flunk 'finish me'
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require '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' do
|
12
|
+
true.should == true
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'physical'
|
3
|
+
require 'actor'
|
4
|
+
require 'mocha'
|
5
|
+
|
6
|
+
class CircleActor < Actor
|
7
|
+
has_behaviors :physical => {:shape => :circle,
|
8
|
+
:mass => 500,
|
9
|
+
:radius => 10}
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'A new physical behavior' do
|
13
|
+
before do
|
14
|
+
@level = stub(:load_animation_set => ['1.png_img_obj','2.png_img_obj'],:register_physical_object => true)
|
15
|
+
|
16
|
+
opts = {:level=>@level, :input=>"input", :resources=>"rm"}
|
17
|
+
@actor = CircleActor.new opts
|
18
|
+
@physical = @actor.physical
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should add methods to its actor' do
|
22
|
+
@actor.should.respond_to? :x
|
23
|
+
should.flunk 'testing this feels dirty...'
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
require '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 == nil
|
15
|
+
|
16
|
+
to = TwoDGridLocation.new(-1, -1)
|
17
|
+
@pather.guide(from,to).should == 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 == nil
|
24
|
+
|
25
|
+
from = TwoDGridLocation.new -1, -1
|
26
|
+
@pather.guide(from,to).should == 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 != nil
|
35
|
+
path.size.should == 1
|
36
|
+
|
37
|
+
path.first.cost_to.should == TwoDGridMap::TRAVEL_COST_STRAIGHT
|
38
|
+
path.first.dist_from.should == 0
|
39
|
+
path.first.location.x.should == to.x
|
40
|
+
path.first.location.y.should == 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 != nil
|
50
|
+
path.size.should == 2
|
51
|
+
|
52
|
+
path.first.location.x.should == 1
|
53
|
+
path.first.location.y.should == 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 != nil
|
64
|
+
path.size.should == 2
|
65
|
+
|
66
|
+
path.first.location.x.should == 1
|
67
|
+
path.first.location.y.should == 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 != nil
|
79
|
+
path.size.should == 2
|
80
|
+
|
81
|
+
path.first.location.x.should == 1
|
82
|
+
path.first.location.y.should == 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 != nil
|
93
|
+
path.size.should == 2
|
94
|
+
|
95
|
+
path.first.location.x.should == 3
|
96
|
+
path.first.location.y.should == 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 != nil
|
107
|
+
path.size.should == 2
|
108
|
+
|
109
|
+
path.first.location.x.should == 3
|
110
|
+
path.first.location.y.should == 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 != nil
|
121
|
+
path.size.should == 2
|
122
|
+
|
123
|
+
path.first.location.x.should == 1
|
124
|
+
path.first.location.y.should == 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 != nil
|
138
|
+
path.size.should == 2
|
139
|
+
|
140
|
+
path.first.location.x.should == 1
|
141
|
+
path.first.location.y.should == 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 != nil
|
152
|
+
path.size.should == 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).should.include? path_el.location
|
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
|