chingu 0.7.6.4 → 0.7.6.5

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.
@@ -49,13 +49,14 @@ class State1 < Chingu::GameState
49
49
  # This is another way of achieving the same thing as the out-commeted draw-code
50
50
  # Since .create is used, it's automatically updated and drawn
51
51
  #
52
- def setup
52
+ def initialize(options = {})
53
+ super
53
54
  Chingu::GameObject.create(:image => "ruby.png", :rotation_center => :top_left)
54
55
  end
55
56
 
56
57
  #def draw
57
58
  # Image["ruby.png"].draw(0,0,0)
58
- #end
59
+ #end
59
60
  end
60
61
 
61
62
  class State2 < Chingu::GameState
@@ -19,40 +19,31 @@ class Game < Chingu::Window
19
19
  end
20
20
 
21
21
  class FireCube < Chingu::GameObject
22
- traits :velocity, :collision_detection
23
- attr_accessor :color, :radius
22
+ traits :velocity, :collision_detection, :bounding_circle
23
+ attr_accessor :color
24
24
 
25
25
  def initialize(options)
26
26
  super
27
27
  @mode = :additive
28
28
 
29
+ @image = Image["circle.png"]
30
+
29
31
  # initialize with a rightwards velocity with some damping to look more realistic
30
- @velocity_x = options[:velocity_x] || 1 + rand(2)
31
- @velocity_y = options[:velocity_y] || 1 + rand(2)
32
+ self.velocity_x = options[:velocity_x] || 1 + rand(2)
33
+ self.velocity_y = options[:velocity_y] || 1 + rand(2)
34
+ self.factor = 2
32
35
 
33
- @box = Rect.new([@x, @y, 10, 10])
34
- @radius = 6
36
+ @color = Color::BLUE
35
37
 
36
- @blue = Color.new(255,100,255,255)
37
- @red = Color.new(255,255,10,10)
38
- @color = @blue
39
- end
40
-
41
- def bounding_box
42
- @box
43
- end
44
-
45
- def draw
46
- $window.fill_rect(@box, @color)
38
+ cache_bounding_circle # This does a lot for performance
47
39
  end
48
40
 
49
41
  def update
50
- @box.x, @box.y = @x, @y
51
- @color = @blue
42
+ @color = Color::BLUE
52
43
  end
53
44
 
54
45
  def die!
55
- @color = @red
46
+ @color = Color::RED
56
47
  end
57
48
 
58
49
  end
@@ -95,8 +86,7 @@ class ParticleState < Chingu::GameState
95
86
  cube1.die!
96
87
  cube2.die!
97
88
  end
98
-
99
- game_objects.destroy_if { |object| object.color.alpha == 0 }
89
+
100
90
  end
101
91
 
102
92
  def draw
data/lib/chingu.rb CHANGED
@@ -33,7 +33,7 @@ require_all "#{CHINGU_ROOT}/chingu/traits"
33
33
  require_all "#{CHINGU_ROOT}/chingu"
34
34
 
35
35
  module Chingu
36
- VERSION = "0.7.6.4"
36
+ VERSION = "0.7.6.5"
37
37
 
38
38
  DEBUG_COLOR = Gosu::Color.new(0xFFFF0000)
39
39
  DEBUG_ZORDER = 9999
data/lib/chingu/assets.rb CHANGED
@@ -33,7 +33,9 @@ module Gosu
33
33
  include Chingu::NamedResource
34
34
 
35
35
  def self.autoload(name)
36
- (path = find_file(name)) ? Gosu::Image.new($window, path, true) : nil
36
+ ret = (path = find_file(name)) ? Gosu::Image.new($window, path, true) : nil
37
+ raise "Can't load image \"#{name}\"" if ret.nil?
38
+ return ret
37
39
  end
38
40
  end
39
41
 
@@ -217,4 +217,4 @@ module Chingu
217
217
  end
218
218
  alias :destroy! :destroy
219
219
  end
220
- end
220
+ end
@@ -1,4 +1,5 @@
1
1
  class Array
2
+
2
3
  def each_collision(*args)
3
4
  list = (self + args).uniq
4
5
  collide_pair = []
@@ -31,7 +31,6 @@ module Chingu
31
31
  @game_objects = options[:game_objects] || []
32
32
  @add_game_objects = []
33
33
  @remove_game_objects = []
34
- #@game_objects_by_class = Hash.new
35
34
  end
36
35
 
37
36
  def to_s
@@ -40,34 +39,24 @@ module Chingu
40
39
 
41
40
  def of_class(klass)
42
41
  @game_objects.select { |game_object| game_object.is_a? klass }
43
- #@game_objects_by_class[klass] || []
44
42
  end
45
43
 
46
44
  def destroy_all
47
45
  @game_objects.clear
48
- #@game_objects_of_class.clear
49
46
  end
50
47
  alias :clear :destroy_all
51
48
  alias :remove_all :destroy_all
52
49
 
53
50
  def add_game_object(object)
54
- #@game_objects.push(object)
55
51
  @add_game_objects.push(object)
56
-
57
-
58
- #(@game_objects_by_class[object.class] ||= []).push(object)
59
52
  end
60
53
 
61
54
  def remove_game_object(object)
62
- #@game_objects.delete(object)
63
55
  @remove_game_objects.push(object)
64
-
65
- #@game_objects_by_class[object.class].delete(object)
66
56
  end
67
57
 
68
58
  def destroy_if
69
59
  @game_objects.reject! { |object| yield(object) }
70
- #@game_objects_by_class.delete_if { |klass, object| yield(object) }
71
60
  end
72
61
 
73
62
  def size
@@ -141,4 +130,4 @@ module Chingu
141
130
  @game_objects.each { |object| object.show! }
142
131
  end
143
132
  end
144
- end
133
+ end
@@ -78,7 +78,7 @@ module Chingu
78
78
  # Include the module, which will add the containing methods as instance methods
79
79
  include mod
80
80
 
81
- # Does sub-module "ClessMethods" exists?
81
+ # Does sub-module "ClassMethods" exists?
82
82
  # (eg: Chingu::Traits::Timer::ClassMethods)
83
83
  if mod.const_defined?("ClassMethods")
84
84
  # Add methods in scope ClassMethods as.. class methods!
@@ -100,6 +100,7 @@ module Chingu
100
100
  # .. and finalize() is called on the game state we're switching _from_.
101
101
  #
102
102
  def switch_game_state(state, options = {})
103
+ puts state.class
103
104
  options = {:setup => true, :finalize => true, :transitional => true}.merge(options)
104
105
 
105
106
  @previous_game_state = current_game_state
@@ -136,10 +136,13 @@ module Chingu
136
136
  if game_object.image
137
137
  game_object.size = [32,32]
138
138
  game_object.cache_bounding_box if game_object.respond_to?(:cache_bounding_box)
139
+ x += 40
140
+ else
141
+ puts "Skipping #{klass} - no image" if @debug
142
+ game_object.destroy
139
143
  end
140
- x += 40
141
144
  rescue
142
- puts "Couldn't use #{klass} in editor."
145
+ puts "Couldn't use #{klass} in editor: #{$!}"
143
146
  end
144
147
  end
145
148
  end
@@ -39,15 +39,13 @@ module Chingu
39
39
  @options = {:speed => 3}.merge(options)
40
40
 
41
41
  @new_game_state = new_game_state
42
- @new_game_state = new_game_state.new if new_game_state.is_a? Class
43
-
44
- #@manager = options[:game_state_manager] || self
45
- #@manager = game_state_manager
42
+ @new_game_state = new_game_state.new if new_game_state.is_a? Class
43
+ @new_game_state.game_objects.sync
46
44
  end
47
45
 
48
46
  def setup
49
47
  @color = Gosu::Color.new(0,0,0,0)
50
- ## if @manager.previous_game_state
48
+
51
49
  if previous_game_state
52
50
  @fading_in = false
53
51
  @alpha = 0.0
@@ -55,7 +53,7 @@ module Chingu
55
53
  @fading_in = true
56
54
  @alpha = 255.0
57
55
  end
58
- # @new_game_state.update # Make sure states game logic is run Once (for a correct draw())
56
+
59
57
  update # Since draw is called before update
60
58
  end
61
59
 
@@ -77,7 +75,6 @@ module Chingu
77
75
  if @fading_in
78
76
  @new_game_state.draw
79
77
  else
80
- ## @manager.previous_game_state.draw
81
78
  previous_game_state.draw
82
79
  end
83
80
 
@@ -88,7 +85,6 @@ module Chingu
88
85
  end
89
86
 
90
87
  if @fading_in && @alpha == 0
91
- ##@manager.switch_game_state(@new_game_state, :transitional => false)
92
88
  switch_game_state(@new_game_state, :transitional => false)
93
89
  end
94
90
 
data/lib/chingu/text.rb CHANGED
@@ -51,7 +51,7 @@ module Chingu
51
51
  #
52
52
  # Takes the standard GameObject-hash-arguments but also:
53
53
  # :text - a string of text
54
- # :font_name|:font - Name of a system font, or a filename to a TTF file (must contain �/�, does not work on Linux).
54
+ # :font_name|:font - Name of a system font, or a filename to a TTF file (must contain ? does not work on Linux).
55
55
  # :height|:size - Height of the font in pixels.
56
56
  # :line_spacing - Spacing between two lines of text in pixels.
57
57
  # :max_width - Width of the bitmap that will be returned. Text will be split into multiple lines to avoid drawing over the right border. When a single word is too long, it will be truncated.
@@ -47,11 +47,8 @@ module Chingu
47
47
  end
48
48
 
49
49
  def radius
50
- return @cached_radius if @cached_radius
51
-
52
- width = self.image.width * self.factor_x.abs
53
- height = self.image.height * self.factor_y.abs
54
- radius = (width + height) / 4
50
+ return @cached_radius if @cached_radius
51
+ radius = (self.width + self.height) / 4
55
52
  radius = radius * trait_options[:bounding_circle][:scale] if trait_options[:bounding_circle][:scale]
56
53
  return radius
57
54
  end
@@ -61,7 +58,6 @@ module Chingu
61
58
  end
62
59
 
63
60
  def cache_bounding_circle
64
- @cached_radius = nil
65
61
  @cached_radius = self.radius
66
62
  end
67
63
 
@@ -111,7 +111,7 @@ module Chingu
111
111
  #
112
112
  def each_collision(*klasses)
113
113
  Array(klasses).each do |klass|
114
- (klass.respond_to?(:all) ? klass.all : klass).each do |object|
114
+ (klass.respond_to?(:all) ? klass.all : Array(klass)).each do |object|
115
115
  yield(self, object) if collides?(object)
116
116
  end
117
117
  end
@@ -119,7 +119,7 @@ module Chingu
119
119
 
120
120
  def first_collision(*klasses)
121
121
  Array(klasses).each do |klass|
122
- (klass.respond_to?(:all) ? klass.all : klass).each do |object|
122
+ (klass.respond_to?(:all) ? klass.all : Array(klass)).each do |object|
123
123
  return object if collides?(object)
124
124
  end
125
125
  end
@@ -132,7 +132,7 @@ module Chingu
132
132
  #
133
133
  def each_bounding_circle_collision(*klasses)
134
134
  Array(klasses).each do |klass|
135
- (klass.respond_to?(:all) ? klass.all : klass).each do |object|
135
+ (klass.respond_to?(:all) ? klass.all : Array(klass)).each do |object|
136
136
  next unless self.collidable && object.collidable
137
137
  yield(self, object) if Gosu.distance(self.x, self.y, object.x, object.y) < self.radius + object.radius
138
138
  end
@@ -145,7 +145,7 @@ module Chingu
145
145
  #
146
146
  def each_bounding_box_collision(*klasses)
147
147
  Array(klasses).each do |klass|
148
- (klass.respond_to?(:all) ? klass.all : klass).each do |object|
148
+ (klass.respond_to?(:all) ? klass.all : Array(klass)).each do |object|
149
149
  return false unless self.collidable && object.collidable
150
150
  yield(self, object) if self.bounding_box.collide_rect?(object.bounding_box)
151
151
  end
@@ -159,7 +159,7 @@ module Chingu
159
159
  #
160
160
  def each_bounding_circle_collision(*klasses)
161
161
  Array(klasses).each do |klass|
162
- object2_list = (klass.respond_to?(:all) ? klass.all : klass)
162
+ object2_list = (klass.respond_to?(:all) ? klass.all : Array(klass))
163
163
  #total_radius = object1.radius + object2.radius # possible optimization?
164
164
 
165
165
  self.all.each do |object1|
@@ -177,7 +177,7 @@ module Chingu
177
177
  #
178
178
  def each_bounding_box_collision(*klasses)
179
179
  Array(klasses).each do |klass|
180
- object2_list = (klass.respond_to?(:all) ? klass.all : klass)
180
+ object2_list = (klass.respond_to?(:all) ? klass.all : Array(klass))
181
181
  self.all.each do |object1|
182
182
  object2_list.each do |object2|
183
183
  next if object1 == object2 # Don't collide objects with themselves
@@ -233,7 +233,7 @@ module Chingu
233
233
  # end
234
234
  # end
235
235
  #end
236
- object2_list = (klass.respond_to?(:all) ? klass.all : klass)
236
+ object2_list = (klass.respond_to?(:all) ? klass.all : Array(klass))
237
237
  self.all.each do |object1|
238
238
  object2_list.each do |object2|
239
239
  next if object1 == object2 # Don't collide objects with themselves
@@ -58,8 +58,9 @@ module Chingu
58
58
  #
59
59
  # Sets X and Y velocity with one single call. Takes an Array-argument with 2 values.
60
60
  #
61
- def velocity=(velocity)
62
- @velocity_x, @velocity_y = velocity
61
+ def velocity=(value)
62
+ @velocity_x, @velocity_y = value && return if value.is_a? Array
63
+ @velocity_x, @velocity_y = value, value
63
64
  end
64
65
 
65
66
  def velocity; [@velocity_x, @velocity_y]; end
@@ -67,8 +68,9 @@ module Chingu
67
68
  #
68
69
  # Sets X and Y acceleration with one single call. Takes an Array-argument with 2 values.
69
70
  #
70
- def acceleration=(acceleration)
71
- @acceleration_x, @acceleration_y = acceleration
71
+ def acceleration=(value)
72
+ @acceleration_x, @acceleration_y = value && return if value.is_a? Array
73
+ @acceleration_x, @acceleration_y = value, value
72
74
  end
73
75
 
74
76
  def acceleration; [@acceleration_x, @acceleration_y]; end
@@ -76,8 +78,9 @@ module Chingu
76
78
  #
77
79
  # Sets X and Y acceleration with one single call. Takes an Array-argument with 2 values.
78
80
  #
79
- def max_velocity=(max_velocity)
80
- @max_velocity_x, @max_velocity_y = max_velocity
81
+ def max_velocity=(value)
82
+ @max_velocity_x, @max_velocity_y = value && return if value.is_a? Array
83
+ @max_velocity_x, @max_velocity_y = value, value
81
84
  end
82
85
 
83
86
  def max_velocity; [@max_velocity_x, @max_velocity_y]; end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ module Chingu
4
+
5
+ describe FPSCounter do
6
+
7
+ it { should respond_to(:fps) }
8
+ it { should respond_to(:milliseconds_since_last_tick) }
9
+ it { should respond_to(:ticks) }
10
+
11
+ describe "#register_tick" do
12
+ before do
13
+ Gosu.stub(:milliseconds).and_return(1000)
14
+ subject { FPSCounter.new }
15
+ end
16
+
17
+ it "increases the tick counter" do
18
+ expect {
19
+ subject.register_tick
20
+ }.to change(subject, :ticks).from(0).to(1)
21
+ end
22
+
23
+ it "keeps track of the fps" do
24
+ expect {
25
+ subject.register_tick
26
+ Gosu.stub(:milliseconds).and_return(1500)
27
+ subject.register_tick
28
+ Gosu.stub(:milliseconds).and_return(2000)
29
+ subject.register_tick
30
+ }.to change(subject, :fps).from(0).to(3) # #register_tick has been called 3 times within 1 second = 3 FPS
31
+ end
32
+
33
+ it "calculates how many milliseconds passed since last game loop iteration and returns that value" do
34
+ Gosu.stub(:milliseconds).and_return(2000)
35
+ subject.register_tick.should equal 1000
36
+ subject.milliseconds_since_last_tick.should eql(1000)
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ module Chingu
4
+
5
+ describe GameObject do
6
+
7
+ before(:all) do
8
+ @game = Chingu::Window.new
9
+ end
10
+
11
+ it { should respond_to(:x) }
12
+ it { should respond_to(:y) }
13
+ it { should respond_to(:angle) }
14
+ it { should respond_to(:center_x) }
15
+ it { should respond_to(:center_y) }
16
+ it { should respond_to(:factor_x) }
17
+ it { should respond_to(:factor_y) }
18
+ it { should respond_to(:zorder) }
19
+ it { should respond_to(:mode) }
20
+ it { should respond_to(:color) }
21
+
22
+ describe "a newly created GameObject" do
23
+ before do
24
+ subject { GameObject.new }
25
+ end
26
+
27
+ it "should have default values" do
28
+ subject.angle.should == 0
29
+ subject.x.should == 0
30
+ subject.y.should == 0
31
+ subject.factor_x.should == 1
32
+ subject.factor_y.should == 1
33
+ subject.center_x.should == 0.5
34
+ subject.center_y.should == 0.5
35
+ subject.mode.should == :default
36
+ subject.image.should == nil
37
+ subject.color.to_s.should == Gosu::Color::WHITE.to_s
38
+ subject.alpha.should == 255
39
+ end
40
+
41
+ it "should wrap angle at 360" do
42
+ subject.angle.should == 0
43
+ subject.angle += 30
44
+ subject.angle.should == 30
45
+ subject.angle += 360
46
+ subject.angle.should == 30
47
+ end
48
+
49
+ it "shouldn't allow alpha below 0" do
50
+ subject.alpha = -10
51
+ subject.alpha.should == 0
52
+ end
53
+
54
+ it "shouldn't allow alpha above 255" do
55
+ subject.alpha = 1000
56
+ subject.alpha.should == 255
57
+ end
58
+
59
+ end
60
+
61
+ describe "GameObject with an image" do
62
+ before do
63
+ p Image.autoload_dirs
64
+ subject { GameObject.new(:image => "rect_20x20.png") }
65
+ end
66
+
67
+ it "should have width,height & size" do
68
+ subject.height.should == 20
69
+ subject.width.should == 20
70
+ subject.size.should == [20,20]
71
+ end
72
+
73
+ it "should adapt width,height & size to scaling" do
74
+ subject.factor = 2
75
+ subject.height.should == 40
76
+ subject.width.should == 40
77
+ subject.size.should == [40,40]
78
+ end
79
+
80
+ it "should adapt factor_x/factor_y to new size" do
81
+ subject.size = [10,40] # half the width, double the height
82
+ subject.height.should == 10
83
+ subject.width.should == 40
84
+ subject.factor_x.should == 0.5
85
+ subject.factor_y.should == 2
86
+ end
87
+
88
+ end
89
+
90
+ after(:all) do
91
+ $window.close
92
+ end
93
+
94
+ end
95
+
96
+ end