gamebox 0.3.2 → 0.3.3

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