gamebox 0.2.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +1 -8
- data/Rakefile +13 -37
- data/TODO.txt +27 -27
- data/docs/getting_started.rdoc +2 -2
- data/gamebox.gemspec +33 -191
- data/lib/gamebox.rb +18 -14
- data/lib/gamebox/actor.rb +37 -27
- data/lib/gamebox/actor_factory.rb +4 -5
- data/lib/gamebox/actor_view.rb +8 -0
- data/lib/gamebox/actors/collidable_debugger.rb +2 -2
- data/lib/gamebox/actors/curtain.rb +3 -3
- data/lib/gamebox/actors/emitter.rb +51 -0
- data/lib/gamebox/actors/label.rb +27 -7
- data/lib/gamebox/actors/logo.rb +1 -1
- data/lib/gamebox/actors/spatial_debugger.rb +25 -10
- data/lib/gamebox/arbiter.rb +61 -34
- data/lib/gamebox/behavior.rb +3 -3
- data/lib/gamebox/behaviors/animated.rb +1 -1
- data/lib/gamebox/behaviors/audible.rb +1 -1
- data/lib/gamebox/behaviors/collidable.rb +9 -4
- data/lib/gamebox/behaviors/collidable/aabb_collidable.rb +26 -1
- data/lib/gamebox/behaviors/collidable/circle_collidable.rb +3 -3
- data/lib/gamebox/behaviors/collidable/polygon_collidable.rb +1 -1
- data/lib/gamebox/behaviors/graphical.rb +30 -4
- data/lib/gamebox/behaviors/layered.rb +1 -1
- data/lib/gamebox/behaviors/physical.rb +113 -30
- data/lib/gamebox/behaviors/timed.rb +33 -0
- data/lib/gamebox/behaviors/updatable.rb +1 -1
- data/lib/gamebox/class_finder.rb +1 -21
- data/lib/gamebox/console_app.rb +33 -31
- data/lib/gamebox/constants.rb +481 -0
- data/lib/gamebox/data/config/objects.yml +7 -0
- data/lib/gamebox/gamebox_application.rb +10 -33
- data/lib/gamebox/gamebox_generator.rb +32 -32
- data/lib/gamebox/input_manager.rb +73 -32
- data/lib/gamebox/lib/inflector.rb +1 -1
- data/lib/gamebox/lib/range_ext.rb +5 -0
- data/lib/gamebox/lib/rect.rb +548 -548
- data/lib/gamebox/lib/sorted_list.rb +1 -1
- data/lib/gamebox/lib/symbol_ext.rb +8 -0
- data/lib/gamebox/physical_director.rb +1 -1
- data/lib/gamebox/physical_stage.rb +3 -3
- data/lib/gamebox/physics.rb +0 -3
- data/lib/gamebox/resource_manager.rb +22 -17
- data/lib/gamebox/sound_manager.rb +3 -2
- data/lib/gamebox/spatial_hash.rb +60 -31
- data/lib/gamebox/spatial_stagehand.rb +30 -6
- data/lib/gamebox/spec/helper.rb +7 -7
- data/lib/gamebox/stage.rb +18 -19
- data/lib/gamebox/stage_manager.rb +33 -23
- data/lib/gamebox/stagehand.rb +3 -0
- data/lib/gamebox/svg_document.rb +1 -1
- data/lib/gamebox/tasks/gamebox_tasks.rake +133 -0
- data/lib/gamebox/templates/actor.erb +0 -2
- data/lib/gamebox/templates/actor_view.erb +1 -3
- data/lib/gamebox/templates/template_app/Gemfile +3 -2
- data/lib/gamebox/templates/template_app/Rakefile +3 -8
- data/lib/gamebox/templates/template_app/config/environment.rb +7 -39
- data/lib/gamebox/templates/template_app/src/demo_stage.rb +1 -2
- data/lib/gamebox/templates/template_app/src/my_actor.rb +0 -3
- data/lib/gamebox/version.rb +2 -2
- data/lib/gamebox/viewport.rb +44 -8
- data/lib/gamebox/views/graphical_actor_view.rb +22 -16
- data/lib/gamebox/wrapped_screen.rb +9 -1
- data/script/perf_spatial_hash.rb +49 -58
- data/script/perf_struct_vs_array.rb +32 -0
- data/spec/actor_factory_spec.rb +61 -0
- data/spec/actor_spec.rb +24 -18
- data/spec/actor_view_spec.rb +51 -6
- data/spec/animated_spec.rb +27 -6
- data/spec/arbiter_spec.rb +12 -24
- data/spec/backstage_spec.rb +1 -1
- data/spec/behavior_spec.rb +3 -3
- data/spec/class_finder_spec.rb +13 -0
- data/spec/collidable_spec.rb +30 -10
- data/spec/emitter_spec.rb +20 -0
- data/spec/helper.rb +5 -21
- data/spec/input_manager_spec.rb +134 -0
- data/spec/label_spec.rb +0 -1
- data/spec/physical_spec.rb +114 -5
- data/spec/resource_manager_spec.rb +1 -2
- data/spec/spatial_hash_spec.rb +23 -7
- data/spec/spatial_stagehand_spec.rb +97 -0
- data/spec/stage_manager_spec.rb +0 -1
- data/spec/stage_spec.rb +2 -2
- data/spec/viewport_spec.rb +92 -48
- metadata +223 -119
- data/.gitignore +0 -11
- data/History.txt +0 -80
- data/VERSION +0 -1
- data/lib/gamebox/event_compat.rb +0 -285
- data/lib/gamebox/lib/diy.rb +0 -371
- data/lib/gamebox/lib/numbers_ext.rb +0 -3
- data/lib/gamebox/tasks/gamebox_tasks.rb +0 -61
- data/load_paths.rb +0 -20
@@ -1,43 +1,49 @@
|
|
1
|
-
|
1
|
+
|
2
2
|
|
3
3
|
class GraphicalActorView < ActorView
|
4
4
|
def draw(target, x_off, y_off, z)
|
5
|
-
x =
|
6
|
-
y =
|
5
|
+
x = actor.x
|
6
|
+
y = actor.y
|
7
7
|
|
8
8
|
offset_x = x+x_off
|
9
9
|
offset_y = y+y_off
|
10
10
|
|
11
|
-
img =
|
11
|
+
img = actor.image
|
12
12
|
return if img.nil?
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
alpha = actor.respond_to?(:alpha) ? actor.alpha : 0xFF
|
15
|
+
color = Color.new(alpha,0xFF,0xFF,0xFF)
|
16
|
+
|
17
|
+
x_scale = actor.x_scale
|
18
|
+
y_scale = actor.y_scale
|
19
|
+
|
20
|
+
if actor.is? :physical
|
16
21
|
img_w = img.width
|
17
22
|
img_h = img.height
|
18
23
|
|
19
|
-
offset_x
|
20
|
-
offset_y = y-img_h/2 + y_off
|
21
|
-
img.draw_rot offset_x, offset_y, z, @actor.rotation
|
24
|
+
img.draw_rot offset_x, offset_y, z, actor.rotation, 0.5, 0.5, x_scale, y_scale
|
22
25
|
else
|
23
|
-
graphical_behavior =
|
26
|
+
graphical_behavior = actor.graphical if actor.is? :graphical
|
24
27
|
if graphical_behavior && graphical_behavior.tiled?
|
25
28
|
x_tiles = graphical_behavior.num_x_tiles
|
26
29
|
y_tiles = graphical_behavior.num_y_tiles
|
27
|
-
# img_w, img_h = *img.size
|
28
30
|
img_w = img.width
|
29
31
|
img_h = img.height
|
30
32
|
x_tiles.times do |col|
|
31
33
|
y_tiles.times do |row|
|
32
|
-
#
|
33
|
-
img.
|
34
|
+
# TODO why is there a nasty black line between these that jitters?
|
35
|
+
img.draw_rot offset_x+col*img_w, offset_y+row*img_h, z, actor.rotation, x_scale, y_scale
|
34
36
|
end
|
35
37
|
end
|
36
38
|
else
|
37
|
-
|
38
|
-
|
39
|
+
if actor.respond_to? :rotation
|
40
|
+
rot = actor.rotation || 0.0
|
41
|
+
img.draw_rot offset_x, offset_y, z, rot, 0.5, 0.5, x_scale, y_scale, color
|
42
|
+
else
|
43
|
+
img.draw offset_x, offset_y, z, x_scale, y_scale, color
|
44
|
+
end
|
39
45
|
end
|
40
46
|
end
|
41
|
-
target.draw_line(offset_x,offset_y,offset_x+1,offset_y+1,[255,10,10],z)
|
42
47
|
end
|
48
|
+
|
43
49
|
end
|
@@ -12,6 +12,14 @@ class WrappedScreen
|
|
12
12
|
@screen.send name, *args
|
13
13
|
end
|
14
14
|
|
15
|
+
def width
|
16
|
+
@screen.fullscreen? ? screen_width : @screen.width
|
17
|
+
end
|
18
|
+
|
19
|
+
def height
|
20
|
+
@screen.fullscreen? ? screen_height : @screen.height
|
21
|
+
end
|
22
|
+
|
15
23
|
def draw_box(x1,y1,x2,y2,color, z)
|
16
24
|
c = convert_color(color)
|
17
25
|
@screen.draw_line x1, y1, c, x2, y1, c, z
|
@@ -28,7 +36,7 @@ class WrappedScreen
|
|
28
36
|
CIRCLE_STEP = 10
|
29
37
|
# is very expensive
|
30
38
|
# cache it if you can somehow
|
31
|
-
def draw_circle(cx,cy,r,color, z)
|
39
|
+
def draw_circle(cx,cy,r,color, z, step=CIRCLE_STEP)
|
32
40
|
c_color = convert_color(color)
|
33
41
|
|
34
42
|
x1, y1 = 0, -r
|
data/script/perf_spatial_hash.rb
CHANGED
@@ -1,73 +1,64 @@
|
|
1
|
-
|
1
|
+
require 'bundler'
|
2
|
+
Bundler.setup
|
2
3
|
|
3
|
-
require '
|
4
|
-
require '
|
4
|
+
require 'constructor'
|
5
|
+
require 'publisher'
|
6
|
+
require 'gamebox'
|
5
7
|
require 'benchmark'
|
6
8
|
|
7
|
-
|
9
|
+
class Arb
|
10
|
+
include Arbiter
|
11
|
+
extend Publisher
|
12
|
+
can_fire_anything
|
8
13
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
14
|
+
def initialize(spatial)
|
15
|
+
@spatial = spatial
|
16
|
+
on_collision_of :otherthingy, :thingy do |f,b|
|
17
|
+
puts "collide"
|
18
|
+
end
|
12
19
|
end
|
13
|
-
|
14
|
-
|
15
|
-
hash.items_at i, i
|
20
|
+
def stagehand(name)
|
21
|
+
@spatial
|
16
22
|
end
|
17
23
|
|
18
|
-
|
19
|
-
hash.rehash
|
20
|
-
hash.rehash
|
21
|
-
hash.rehash
|
24
|
+
end
|
22
25
|
|
23
|
-
|
24
|
-
|
26
|
+
class Shape
|
27
|
+
extend Publisher
|
28
|
+
can_fire_anything
|
29
|
+
attr_accessor :x,:y,:width,:height,:collidable_shape,:radius
|
30
|
+
def initialize(*args)
|
31
|
+
@x,@y,@width,@height,@collidable_shape,@radius = *args
|
25
32
|
end
|
33
|
+
|
34
|
+
def center_x;self.x;end
|
35
|
+
def center_y;self.y;end
|
36
|
+
def actor_type;:thingy;end
|
26
37
|
end
|
27
38
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
@lots = 1_000
|
33
|
-
@small_grid = 5
|
34
|
-
@medium_grid = 80
|
35
|
-
|
36
|
-
@small_object = 2
|
37
|
-
@medium_object = 20
|
38
|
-
@large_object = 100
|
39
|
-
|
40
|
-
impls = %w{old new}
|
41
|
-
impls.each do |impl|
|
42
|
-
klass = ObjectSpace.const_get "#{impl.capitalize}SpatialHash"
|
43
|
-
b.report("#{impl} w/ lots of small objects in small size grid") do
|
44
|
-
hash = klass.new @small_grid, true
|
45
|
-
do_it(hash,@lots, @small_object)
|
46
|
-
end
|
47
|
-
|
48
|
-
b.report("#{impl} w/ lots of medium objects in small size grid") do
|
49
|
-
hash = klass.new @small_grid, true
|
50
|
-
do_it(hash,@lots, @medium_object)
|
51
|
-
end
|
52
|
-
|
53
|
-
b.report("#{impl} w/ lots of small objects in medium size grid") do
|
54
|
-
hash = klass.new @medium_grid, true
|
55
|
-
do_it(hash,@lots, @small_object)
|
56
|
-
end
|
39
|
+
actor_count = 100
|
40
|
+
loop_count = 100
|
41
|
+
obj_size = 40
|
42
|
+
cell_size = 80
|
57
43
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
44
|
+
hash = SpatialHash.new cell_size#, true
|
45
|
+
arb = Arb.new hash
|
46
|
+
actor_count.times do |i|
|
47
|
+
shape = Shape.new(i*20, i*20, obj_size,obj_size,:circle,obj_size)
|
48
|
+
arb.register_collidable shape
|
49
|
+
end
|
62
50
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
51
|
+
Benchmark.bm(60) do|b|
|
52
|
+
#30.times do |i|
|
53
|
+
hash_cell_size = cell_size #+ 5*i
|
54
|
+
hash.cell_size = hash_cell_size
|
55
|
+
b.report("#{actor_count} actors w/ size #{obj_size} cell size #{hash_cell_size} for #{loop_count} update loops") do
|
56
|
+
loop_count.times do
|
57
|
+
hash.rehash
|
58
|
+
arb.find_collisions
|
70
59
|
end
|
71
|
-
|
60
|
+
end
|
61
|
+
end
|
62
|
+
#end
|
72
63
|
|
73
|
-
|
64
|
+
puts "hash auto-size:#{hash.cell_size}"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
|
3
|
+
# Point = Struct.new :x, :y
|
4
|
+
class Point
|
5
|
+
attr_accessor :x, :y
|
6
|
+
def initialize(x,y)
|
7
|
+
@x = x
|
8
|
+
@y = y
|
9
|
+
end
|
10
|
+
end
|
11
|
+
NUM = 10_000_000
|
12
|
+
Benchmark.bm(60) do |b|
|
13
|
+
b.report("array") do
|
14
|
+
NUM.times do
|
15
|
+
it = [4,6]
|
16
|
+
it[0] = 1
|
17
|
+
it[1] = 3
|
18
|
+
it[0]
|
19
|
+
it[1]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
b.report("struct") do
|
23
|
+
NUM.times do
|
24
|
+
it = Point.new 4, 6
|
25
|
+
it.x = 1
|
26
|
+
it.y = 3
|
27
|
+
it.x
|
28
|
+
it.y
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'helper')
|
2
|
+
describe ActorFactory do
|
3
|
+
before do
|
4
|
+
@input_manager = mock
|
5
|
+
@screen = mock
|
6
|
+
@stage = mock
|
7
|
+
@resource_manager = mock
|
8
|
+
@stage = mock
|
9
|
+
@stage.stubs(:resource_manager).returns(@resource_manager)
|
10
|
+
@director = mock
|
11
|
+
params = {:input_manager => @input_manager, :wrapped_screen => @screen}
|
12
|
+
@target = ActorFactory.new params
|
13
|
+
@target.director = @director
|
14
|
+
@opts = Actor::DEFAULT_PARAMS.merge({:foo => :bar})
|
15
|
+
@basic_opts = {
|
16
|
+
:stage => @stage,
|
17
|
+
:input => @input_manager,
|
18
|
+
:director => @director,
|
19
|
+
:resources => @resource_manager,
|
20
|
+
:wrapped_screen => @screen,
|
21
|
+
}
|
22
|
+
@merged_opts = @basic_opts.merge(@opts)
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#build" do
|
27
|
+
it "creates an Actor instance and registers the view" do
|
28
|
+
|
29
|
+
view_actor = nil
|
30
|
+
@stage.expects(:register_drawable).with() do |view|
|
31
|
+
view.class.should == ActorView
|
32
|
+
view.stage.should == @stage
|
33
|
+
view.wrapped_screen.should == @screen
|
34
|
+
view.actor.class.should == Actor
|
35
|
+
view_actor = view.actor
|
36
|
+
end
|
37
|
+
@merged_opts[:actor_type] = :actor
|
38
|
+
|
39
|
+
act = @target.build :actor, @stage, @opts
|
40
|
+
act.opts.should == @merged_opts
|
41
|
+
act.class.should == Actor
|
42
|
+
act.should == view_actor
|
43
|
+
end
|
44
|
+
|
45
|
+
it "creates an Actor instance with no view" do
|
46
|
+
@merged_opts[:actor_type] = :no_view_actor
|
47
|
+
|
48
|
+
act = @target.build :no_view_actor, @stage, @opts
|
49
|
+
act.opts.should == @merged_opts
|
50
|
+
act.class.should == NoViewActor
|
51
|
+
end
|
52
|
+
|
53
|
+
it "nil on actor not found" do
|
54
|
+
lambda{ @target.build :no_actor, @stage, @opts }.should raise_error("no_actor not found")
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
class NoViewActor < Actor
|
60
|
+
end
|
61
|
+
end
|
data/spec/actor_spec.rb
CHANGED
@@ -1,42 +1,40 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__),'helper')
|
2
|
-
require 'actor'
|
3
|
-
require 'behavior'
|
4
|
-
|
5
2
|
describe 'A new actor' do
|
6
|
-
|
7
|
-
|
3
|
+
let(:stage) { mock }
|
4
|
+
subject {
|
5
|
+
opts = {:stage=>stage, :input=>"input",
|
8
6
|
:resources=>"resource", :actor_type => :actor}
|
9
|
-
|
10
|
-
|
7
|
+
Actor.new opts
|
8
|
+
}
|
11
9
|
|
12
10
|
it 'should be alive' do
|
13
|
-
|
11
|
+
subject.alive?.should be_true
|
14
12
|
end
|
15
13
|
|
16
14
|
it 'should be the correct type' do
|
17
|
-
|
15
|
+
subject.actor_type.should == :actor
|
18
16
|
end
|
19
17
|
|
20
18
|
it 'should be at (0,0)' do
|
21
|
-
|
22
|
-
|
19
|
+
subject.x.should equal(0)
|
20
|
+
subject.y.should equal(0)
|
23
21
|
end
|
24
22
|
|
25
23
|
it 'should have access to backstage' do
|
26
|
-
|
27
|
-
|
24
|
+
subject.stage = mock(:backstage => :stuff)
|
25
|
+
subject.backstage.should == :stuff
|
28
26
|
end
|
29
27
|
|
30
28
|
it 'should have atts set' do
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
subject.stage.should == stage
|
30
|
+
subject.input_manager.should == "input"
|
31
|
+
subject.resource_manager.should == "resource"
|
32
|
+
subject.behaviors.size.should equal(0)
|
35
33
|
end
|
36
34
|
|
37
35
|
it 'should fire anything' do
|
38
36
|
Proc.new {
|
39
|
-
|
37
|
+
subject.when :foofoo_bar do
|
40
38
|
"blah"
|
41
39
|
end
|
42
40
|
}.should_not raise_error
|
@@ -52,6 +50,14 @@ describe 'A new actor' do
|
|
52
50
|
@james.is?(:smart).should be_true
|
53
51
|
@james.instance_variable_get('@behaviors')[:smart].instance_variable_get('@opts').should == {:really=>true}
|
54
52
|
end
|
53
|
+
|
54
|
+
describe '#viewport' do
|
55
|
+
it 'should return the stages viewport' do
|
56
|
+
stage.stubs(:viewport).returns(:da_viewport)
|
57
|
+
subject.viewport.should == :da_viewport
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
55
61
|
end
|
56
62
|
|
57
63
|
class Cool < Behavior; end
|
data/spec/actor_view_spec.rb
CHANGED
@@ -1,16 +1,61 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__),'helper')
|
2
|
-
|
2
|
+
|
3
3
|
|
4
4
|
describe 'A new actor view' do
|
5
|
+
before do
|
6
|
+
@actor = mock
|
7
|
+
@stage = mock
|
8
|
+
@actor.stubs :when
|
9
|
+
end
|
5
10
|
|
6
11
|
it 'should be layered 0/1 by default' do
|
7
|
-
@
|
12
|
+
@actor.expects(:is?).with(:layered).returns(false)
|
13
|
+
@test_me = ActorView.new @stage, @actor, :wrapped_screen
|
8
14
|
@test_me.layer.should == 0
|
9
15
|
@test_me.parallax.should == 1
|
10
16
|
end
|
11
17
|
|
12
|
-
it 'should call setup on creation
|
13
|
-
|
14
|
-
|
15
|
-
|
18
|
+
it 'should call setup on creation' do
|
19
|
+
ActorView.any_instance.expects :setup
|
20
|
+
@actor.expects(:is?).with(:layered).returns(false)
|
21
|
+
@test_me = ActorView.new @stage, @actor, :wrapped_screen
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should accept layered behavior params from actor' do
|
25
|
+
@actor.stubs(:layer => 6, :parallax => 3)
|
26
|
+
@actor.expects(:is?).with(:layered).returns(true)
|
27
|
+
@test_me = ActorView.new @stage, @actor, :wrapped_screen
|
28
|
+
|
29
|
+
@test_me.layer.should == 6
|
30
|
+
@test_me.parallax.should == 3
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should register for show events' do
|
34
|
+
@actor = Actor.new({})
|
35
|
+
|
36
|
+
@test_me = ActorView.new @stage, @actor, :wrapped_screen
|
37
|
+
@stage.expects(:register_drawable).with(@test_me)
|
38
|
+
|
39
|
+
@actor.send :fire, :show_me
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should register for hide events' do
|
43
|
+
@actor = Actor.new({})
|
44
|
+
|
45
|
+
@test_me = ActorView.new @stage, @actor, :wrapped_screen
|
46
|
+
@stage.expects(:unregister_drawable).with(@test_me)
|
47
|
+
|
48
|
+
@actor.send :fire, :hide_me
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should register for remove events' do
|
52
|
+
@actor = Actor.new({})
|
53
|
+
|
54
|
+
@test_me = ActorView.new @stage, @actor, :wrapped_screen
|
55
|
+
@stage.expects(:unregister_drawable).with(@test_me)
|
56
|
+
|
57
|
+
@actor.send :fire, :remove_me
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should manage a cached surface for drawing (possibly use record{})'
|
16
61
|
end
|