gamebox 0.3.2 → 0.3.3

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/lib/gamebox/stage.rb CHANGED
@@ -94,12 +94,15 @@ class Stage
94
94
 
95
95
  def draw(target)
96
96
  z = 0
97
- @drawables.keys.sort.reverse.each do |parallax_layer|
97
+ # TODO PERF cache this array and invalidate when new layers come in?
98
+ @parallax_layers.each do |parallax_layer|
99
+ # @drawables.keys.sort.reverse.each do |parallax_layer|
98
100
 
99
101
  drawables_on_parallax_layer = @drawables[parallax_layer]
100
102
 
101
- unless drawables_on_parallax_layer.nil?
102
- drawables_on_parallax_layer.keys.sort.each do |layer|
103
+ if drawables_on_parallax_layer
104
+ @layer_orders[parallax_layer].each do |layer|
105
+ # drawables_on_parallax_layer.keys.sort.each do |layer|
103
106
 
104
107
  trans_x = @viewport.x_offset parallax_layer
105
108
  trans_y = @viewport.y_offset parallax_layer
@@ -125,13 +128,20 @@ class Stage
125
128
 
126
129
  def clear_drawables
127
130
  @drawables = {}
131
+ @layer_orders = {}
128
132
  end
129
133
 
130
134
  def register_drawable(drawable)
131
135
  layer = drawable.layer
132
136
  parallax = drawable.parallax
133
- @drawables[parallax] ||= {}
134
- @drawables[parallax][layer] ||= []
137
+ unless @drawables[parallax]
138
+ @drawables[parallax] = {}
139
+ @parallax_layers = @drawables.keys.sort.reverse
140
+ end
141
+ unless @drawables[parallax][layer]
142
+ @drawables[parallax][layer] = []
143
+ @layer_orders[parallax] = @drawables[parallax].keys.sort
144
+ end
135
145
  @drawables[parallax][layer] << drawable
136
146
  end
137
147
 
@@ -140,6 +150,7 @@ class Stage
140
150
  def move_layer(from_parallax, from_layer, to_parallax, to_layer)
141
151
  drawable_list = @drawables[from_parallax].delete from_layer
142
152
 
153
+
143
154
  if drawable_list
144
155
  prev_drawable_list = @drawables[to_parallax].delete to_layer
145
156
  @drawables[to_parallax][to_layer] = drawable_list
@@ -2,7 +2,7 @@ module Gamebox
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 3
5
- TINY = 2
5
+ TINY = 3
6
6
 
7
7
  ARRAY = [MAJOR, MINOR, TINY]
8
8
  STRING = ARRAY.join('.')
@@ -14,9 +14,9 @@ class GraphicalActorView < ActorView
14
14
  alpha = actor.respond_to?(:alpha) ? actor.alpha : 0xFF
15
15
  color = Color.new(alpha,0xFF,0xFF,0xFF)
16
16
 
17
- x_scale = actor.x_scale
18
- y_scale = actor.y_scale
19
17
 
18
+ x_scale = actor.respond_to?(:x_scale) ? actor.x_scale : 1
19
+ y_scale = actor.respond_to?(:y_scale) ? actor.y_scale : 1
20
20
  if actor.is? :physical
21
21
  img_w = img.width
22
22
  img_h = img.height
@@ -103,6 +103,7 @@ class WrappedScreen
103
103
  end
104
104
 
105
105
  def convert_color(color)
106
+ return color if color.is_a? Gosu::Color
106
107
  @colors ||= {}
107
108
  c = @colors[color]
108
109
  if c.nil?
@@ -0,0 +1,72 @@
1
+ require 'benchmark'
2
+ $: << File.dirname(__FILE__)+"/../lib/gamebox"
3
+ require 'gamebox'
4
+
5
+
6
+ NUM_RUNS = 800
7
+ PROFILE = true
8
+
9
+ def run
10
+ config = {
11
+ screen_resolution: [800,600]
12
+ }
13
+
14
+ af = ActorFactory.new input_manager: :input_manager, wrapped_screen: :wrapped_screen
15
+ af.director = FakeUpdate.new
16
+ stage = Stage.new :input_manager, af, :resource_manager, :sound_manager, config, :backstage, {}
17
+
18
+ things = []
19
+ 20.times do |i|
20
+ 5.times do |j|
21
+ things << stage.spawn(:thinger, x: i*40, y: j*40)
22
+ end
23
+ end
24
+
25
+ Benchmark.bm(60) do |b|
26
+ b.report("update loop") do
27
+
28
+ runs = NUM_RUNS
29
+ if PROFILE
30
+ # runs = 100
31
+ require 'perftools'
32
+ PerfTools::CpuProfiler.start("/tmp/gamebox_perf.txt")
33
+ end
34
+
35
+ runs.times do
36
+ things[0].x = things[0].x + 1
37
+ things[2].x = things[0].x + 1
38
+ things[0].x = things[2].x - 1
39
+ things[2].x = things[2].x - 1
40
+ things[0].y = things[0].y + 1
41
+ things[2].y = things[0].y + 1
42
+ things[0].y = things[2].y - 1
43
+ things[2].y = things[2].y - 1
44
+ stage.update(20)
45
+ #
46
+ # puts "\nGARBAGE COLLECTION"
47
+ # # Not even close to exact, but gives a rough idea of what's being collected
48
+ # old_objects = ObjectSpace.count_objects.dup
49
+ # ObjectSpace.garbage_collect
50
+ # new_objects = ObjectSpace.count_objects
51
+ #
52
+ # old_objects.each do |k,v|
53
+ # diff = v - new_objects[k]
54
+ # puts "#{k} #{diff} diff" if diff != 0
55
+ # end
56
+ #
57
+ #
58
+ end
59
+ PerfTools::CpuProfiler.stop if PROFILE
60
+
61
+ end
62
+ end
63
+ end
64
+ class FakeUpdate
65
+ def update(dt);end
66
+ end
67
+
68
+ class Thinger < Actor
69
+ has_behavior :collidable => {:shape => :circle, :radius => 34}
70
+ end
71
+
72
+ run
@@ -0,0 +1,51 @@
1
+ require 'benchmark'
2
+ $: << File.dirname(__FILE__)+"/../lib/gamebox"
3
+ require 'gamebox'
4
+
5
+
6
+ NUM_LAYERS = 12
7
+ NUM_P_LAYERS = 3
8
+ NUM_RUNS = 200_000
9
+ PROFILE = true
10
+
11
+ def run
12
+ config = {
13
+ screen_resolution: [800,600]
14
+ }
15
+
16
+ af = Struct.new(:director).new
17
+ stage = Stage.new :input_manager, af, :resource_manager, :sound_manager, config, :backstage, {}
18
+ NUM_P_LAYERS.times do |pl|
19
+ NUM_LAYERS.times do |l|
20
+ stage.register_drawable FakeDrawable.new(l+1, pl+1)
21
+ end
22
+ end
23
+
24
+
25
+ Benchmark.bm(60) do |b|
26
+ b.report("drawing loop") do
27
+
28
+ if PROFILE
29
+ require 'perftools'
30
+ PerfTools::CpuProfiler.start("/tmp/gamebox_perf.txt")
31
+ end
32
+
33
+ NUM_RUNS.times do
34
+ stage.draw :target
35
+ end
36
+ PerfTools::CpuProfiler.stop if PROFILE
37
+
38
+ end
39
+ end
40
+ end
41
+
42
+ class FakeDrawable
43
+ def initialize(l, pl)
44
+ @layer = l
45
+ @parallax = pl
46
+ end
47
+ def draw(target,xoff,yoff,z);end
48
+ attr_accessor :layer, :parallax
49
+ end
50
+
51
+ run
@@ -1,134 +1,137 @@
1
1
  require File.join(File.dirname(__FILE__),'helper')
2
2
 
3
- class CircleActor < Actor
4
- has_behaviors :physical => {:shape => :circle,
5
- :mass => 500,
6
- :radius => 10}
7
- end
3
+ # Only run these if the user has chipmunk installed
4
+ if defined? CP
5
+ class CircleActor < Actor
6
+ has_behaviors :physical => {:shape => :circle,
7
+ :mass => 500,
8
+ :radius => 10}
9
+ end
8
10
 
9
- describe 'A new physical behavior' do
10
- before do
11
- @stage = stub(:load_animation_set => ['1.png_img_obj','2.png_img_obj'],:register_physical_object => true)
11
+ describe 'A new physical behavior' do
12
+ before do
13
+ @stage = stub(:load_animation_set => ['1.png_img_obj','2.png_img_obj'],:register_physical_object => true)
12
14
 
13
- @opts = {:stage=>@stage, :input=>"input", :resources=>"rm"}
14
- @actor = CircleActor.new @opts
15
- @physical = @actor.physical
16
- end
15
+ @opts = {:stage=>@stage, :input=>"input", :resources=>"rm"}
16
+ @actor = CircleActor.new @opts
17
+ @physical = @actor.physical
18
+ end
17
19
 
18
- it 'should add methods to its actor' do
19
- @actor.should.respond_to? :x
20
- pending 'add shared example for relegates'
21
- end
20
+ it 'should add methods to its actor' do
21
+ @actor.should.respond_to? :x
22
+ pending 'add shared example for relegates'
23
+ end
22
24
 
23
- describe "#pivot" do
24
- it 'creates a new PivotJoint and adds it to the space' do
25
- other = CircleActor.new @opts
26
- v1 = vec2(2,3)
27
- v2 = vec2(4,5)
28
- CP::Constraint::PivotJoint.expects(:new).with(@physical.body, other.body, v1, v2).returns(:joint)
29
- @stage.expects(:register_physical_constraint).with(:joint)
25
+ describe "#pivot" do
26
+ it 'creates a new PivotJoint and adds it to the space' do
27
+ other = CircleActor.new @opts
28
+ v1 = vec2(2,3)
29
+ v2 = vec2(4,5)
30
+ CP::Constraint::PivotJoint.expects(:new).with(@physical.body, other.body, v1, v2).returns(:joint)
31
+ @stage.expects(:register_physical_constraint).with(:joint)
30
32
 
31
- @actor.pivot(v1, other, v2).should == :joint
33
+ @actor.pivot(v1, other, v2).should == :joint
34
+ end
32
35
  end
33
- end
34
36
 
35
- describe "#pin" do
36
- it 'creates a new PinJoint and adds it to the space' do
37
- other = CircleActor.new @opts
38
- v1 = vec2(2,3)
39
- v2 = vec2(4,5)
40
- CP::Constraint::PinJoint.expects(:new).with(@physical.body, other.body, v1, v2).returns(:joint)
41
- @stage.expects(:register_physical_constraint).with(:joint)
37
+ describe "#pin" do
38
+ it 'creates a new PinJoint and adds it to the space' do
39
+ other = CircleActor.new @opts
40
+ v1 = vec2(2,3)
41
+ v2 = vec2(4,5)
42
+ CP::Constraint::PinJoint.expects(:new).with(@physical.body, other.body, v1, v2).returns(:joint)
43
+ @stage.expects(:register_physical_constraint).with(:joint)
42
44
 
43
- @actor.pin(v1, other, v2).should == :joint
45
+ @actor.pin(v1, other, v2).should == :joint
46
+ end
44
47
  end
45
- end
46
48
 
47
- describe "#spring" do
48
- it 'creates a new DampedSpring and adds it to the space' do
49
- other = CircleActor.new @opts
50
- v1 = vec2(2,3)
51
- v2 = vec2(4,5)
52
- CP::Constraint::DampedSpring.expects(:new).with(@physical.body, other.body, v1, v2, 1,2,3).returns(:spring)
53
- @stage.expects(:register_physical_constraint).with(:spring)
49
+ describe "#spring" do
50
+ it 'creates a new DampedSpring and adds it to the space' do
51
+ other = CircleActor.new @opts
52
+ v1 = vec2(2,3)
53
+ v2 = vec2(4,5)
54
+ CP::Constraint::DampedSpring.expects(:new).with(@physical.body, other.body, v1, v2, 1,2,3).returns(:spring)
55
+ @stage.expects(:register_physical_constraint).with(:spring)
54
56
 
55
- @actor.spring(v1, other, v2, 1, 2, 3).should == :spring
57
+ @actor.spring(v1, other, v2, 1, 2, 3).should == :spring
58
+ end
56
59
  end
57
- end
58
60
 
59
61
 
60
62
 
61
- describe "#groove" do
62
- it 'creates a new GrooveJoint and adds it to the space' do
63
- other = CircleActor.new @opts
64
- v1 = vec2(2,3)
65
- v2 = vec2(4,5)
66
- v3 = vec2(9,7)
67
- CP::Constraint::GrooveJoint.expects(:new).with(@physical.body, other.body, v1, v2, v3).returns(:groove)
68
- @stage.expects(:register_physical_constraint).with(:groove)
63
+ describe "#groove" do
64
+ it 'creates a new GrooveJoint and adds it to the space' do
65
+ other = CircleActor.new @opts
66
+ v1 = vec2(2,3)
67
+ v2 = vec2(4,5)
68
+ v3 = vec2(9,7)
69
+ CP::Constraint::GrooveJoint.expects(:new).with(@physical.body, other.body, v1, v2, v3).returns(:groove)
70
+ @stage.expects(:register_physical_constraint).with(:groove)
69
71
 
70
- @actor.groove(v1, v2, other, v3).should == :groove
72
+ @actor.groove(v1, v2, other, v3).should == :groove
73
+ end
71
74
  end
72
- end
73
75
 
74
- describe "#rotary_spring" do
75
- it 'creates a new DampedRotarySpring and adds it to the space' do
76
- other = CircleActor.new @opts
77
- CP::Constraint::DampedRotarySpring.expects(:new).with(@physical.body, other.body, 3.14, 10, 50).returns(:rotary_spring)
78
- @stage.expects(:register_physical_constraint).with(:rotary_spring)
79
- @actor.rotary_spring(other, 3.14, 10, 50).should == :rotary_spring
76
+ describe "#rotary_spring" do
77
+ it 'creates a new DampedRotarySpring and adds it to the space' do
78
+ other = CircleActor.new @opts
79
+ CP::Constraint::DampedRotarySpring.expects(:new).with(@physical.body, other.body, 3.14, 10, 50).returns(:rotary_spring)
80
+ @stage.expects(:register_physical_constraint).with(:rotary_spring)
81
+ @actor.rotary_spring(other, 3.14, 10, 50).should == :rotary_spring
82
+ end
80
83
  end
81
- end
82
84
 
83
- describe "#rotary_limit" do
84
- it 'creates a new RotaryLimitJoint and adds it to the space' do
85
- other = CircleActor.new @opts
86
- CP::Constraint::RotaryLimitJoint.expects(:new).with(@physical.body, other.body, 0, 3).returns(:rotary_limit)
87
- @stage.expects(:register_physical_constraint).with(:rotary_limit)
88
- @actor.rotary_limit(other, 0, 3).should == :rotary_limit
85
+ describe "#rotary_limit" do
86
+ it 'creates a new RotaryLimitJoint and adds it to the space' do
87
+ other = CircleActor.new @opts
88
+ CP::Constraint::RotaryLimitJoint.expects(:new).with(@physical.body, other.body, 0, 3).returns(:rotary_limit)
89
+ @stage.expects(:register_physical_constraint).with(:rotary_limit)
90
+ @actor.rotary_limit(other, 0, 3).should == :rotary_limit
91
+ end
89
92
  end
90
- end
91
93
 
92
- describe "#ratchet" do
93
- it 'creates a new RatchetJoint and adds it to the space' do
94
- other = CircleActor.new @opts
95
- CP::Constraint::RatchetJoint.expects(:new).with(@physical.body, other.body, 0, 0.3).returns(:ratchet)
96
- @stage.expects(:register_physical_constraint).with(:ratchet)
97
- @actor.ratchet(other, 0, 0.3).should == :ratchet
94
+ describe "#ratchet" do
95
+ it 'creates a new RatchetJoint and adds it to the space' do
96
+ other = CircleActor.new @opts
97
+ CP::Constraint::RatchetJoint.expects(:new).with(@physical.body, other.body, 0, 0.3).returns(:ratchet)
98
+ @stage.expects(:register_physical_constraint).with(:ratchet)
99
+ @actor.ratchet(other, 0, 0.3).should == :ratchet
100
+ end
98
101
  end
99
- end
100
102
 
101
- describe "#gear" do
102
- it 'creates a new GearJoint and adds it to the space' do
103
- other = CircleActor.new @opts
104
- CP::Constraint::GearJoint.expects(:new).with(@physical.body, other.body, 0, 0.3).returns(:gear)
105
- @stage.expects(:register_physical_constraint).with(:gear)
106
- @actor.gear(other, 0, 0.3).should == :gear
103
+ describe "#gear" do
104
+ it 'creates a new GearJoint and adds it to the space' do
105
+ other = CircleActor.new @opts
106
+ CP::Constraint::GearJoint.expects(:new).with(@physical.body, other.body, 0, 0.3).returns(:gear)
107
+ @stage.expects(:register_physical_constraint).with(:gear)
108
+ @actor.gear(other, 0, 0.3).should == :gear
109
+ end
107
110
  end
108
- end
109
111
 
110
- describe "#motor" do
111
- it 'creates a new SimpleMotor and adds it to the space' do
112
- other = CircleActor.new @opts
113
- CP::Constraint::SimpleMotor.expects(:new).with(@physical.body, other.body, 40).returns(:motor)
114
- @stage.expects(:register_physical_constraint).with(:motor)
115
- @actor.motor(other, 40).should == :motor
112
+ describe "#motor" do
113
+ it 'creates a new SimpleMotor and adds it to the space' do
114
+ other = CircleActor.new @opts
115
+ CP::Constraint::SimpleMotor.expects(:new).with(@physical.body, other.body, 40).returns(:motor)
116
+ @stage.expects(:register_physical_constraint).with(:motor)
117
+ @actor.motor(other, 40).should == :motor
118
+ end
116
119
  end
117
- end
118
120
 
119
- describe "#slide" do
120
- it 'creates the slide joint and adds it to the space' do
121
- other = CircleActor.new @opts
122
- v1 = vec2(2,3)
123
- v2 = vec2(4,5)
124
- min = 2.0
125
- max = 3.0
126
- CP::Constraint::SlideJoint.expects(:new).with(@physical.body, other.body, v1, v2, min, max).returns(:joint)
121
+ describe "#slide" do
122
+ it 'creates the slide joint and adds it to the space' do
123
+ other = CircleActor.new @opts
124
+ v1 = vec2(2,3)
125
+ v2 = vec2(4,5)
126
+ min = 2.0
127
+ max = 3.0
128
+ CP::Constraint::SlideJoint.expects(:new).with(@physical.body, other.body, v1, v2, min, max).returns(:joint)
127
129
 
128
- @stage.expects(:register_physical_constraint).with(:joint)
130
+ @stage.expects(:register_physical_constraint).with(:joint)
129
131
 
130
- @actor.slide(v1, other, v2, min, max).should == :joint
132
+ @actor.slide(v1, other, v2, min, max).should == :joint
133
+ end
131
134
  end
132
- end
133
135
 
136
+ end
134
137
  end
@@ -13,20 +13,20 @@ describe 'a new SpacialHash' do
13
13
  it 'can add a point' do
14
14
  pt = Point.new 2, 3
15
15
  @hash.add pt
16
- @hash.instance_variable_get('@buckets')[0][0].first.should == pt
16
+ @hash.buckets[0][0].first.should == pt
17
17
  end
18
18
 
19
19
  it 'can add a neg point' do
20
20
  pt = Point.new -2, 3
21
21
  @hash.add pt
22
- @hash.instance_variable_get('@buckets')[-1][0].first.should == pt
22
+ @hash.buckets[-1][0].first.should == pt
23
23
  end
24
24
 
25
25
  it 'can add a square' do
26
26
  box = Item.new 2, 3, 12, 13
27
27
  @hash.add box
28
28
 
29
- buckets = @hash.instance_variable_get('@buckets')
29
+ buckets = @hash.buckets
30
30
 
31
31
  buckets[0][0].first.should == box
32
32
  buckets[0][1].first.should == box
@@ -38,33 +38,38 @@ describe 'a new SpacialHash' do
38
38
  box = Item.new 3, 3, 12, 2
39
39
  @hash.add box
40
40
 
41
- buckets = @hash.instance_variable_get('@buckets')
41
+ buckets = @hash.buckets
42
42
  buckets[0][0].first.should == box
43
43
  buckets[1][0].first.should == box
44
44
 
45
- buckets[1][1].should be_nil
46
45
  buckets[0][1].should be_nil
46
+ buckets[1][1].should be_nil
47
47
 
48
48
  end
49
49
 
50
50
  it 'can remove points' do
51
51
  pt = Point.new -2, 3
52
52
  @hash.add pt
53
+ @hash.buckets[-1][0].should_not be_empty
53
54
  @hash.remove pt
54
55
 
55
- @hash.instance_variable_get('@buckets')[-1][0].should be_empty
56
+ @hash.buckets[-1][0].should be_empty
56
57
  end
57
58
 
58
59
  it 'can remove boxes' do
59
60
  box = Item.new 2, 3, 12, 13
60
61
  @hash.add box
62
+ @hash.buckets[0][0].should_not be_empty
63
+ @hash.buckets[0][1].should_not be_empty
64
+ @hash.buckets[1][0].should_not be_empty
65
+ @hash.buckets[1][1].should_not be_empty
61
66
 
62
67
  @hash.remove box
63
68
 
64
- @hash.instance_variable_get('@buckets')[0][0].should be_empty
65
- @hash.instance_variable_get('@buckets')[0][1].should be_empty
66
- @hash.instance_variable_get('@buckets')[1][0].should be_empty
67
- @hash.instance_variable_get('@buckets')[1][1].should be_empty
69
+ @hash.buckets[0][0].should be_empty
70
+ @hash.buckets[0][1].should be_empty
71
+ @hash.buckets[1][0].should be_empty
72
+ @hash.buckets[1][1].should be_empty
68
73
  end
69
74
 
70
75
  it 'can lookup objects for an x,y location' do
@@ -79,7 +84,7 @@ describe 'a new SpacialHash' do
79
84
  @hash.add box
80
85
  @hash.rehash
81
86
 
82
- buckets = @hash.instance_variable_get('@buckets')
87
+ buckets = @hash.buckets
83
88
  buckets[0][0].first.should == box
84
89
  buckets[0][1].first.should == box
85
90
  buckets[1][0].first.should == box