chingu 0.7.5 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -52,21 +52,23 @@ module Chingu
52
52
  # Creates game objects from a Chingu-spezed game objects file (created with game state 'Edit')
53
53
  #
54
54
  def load_game_objects(options = {})
55
- file = options[:file] || "#{self.class.to_s.downcase}.yml"
55
+ file = options[:file] || self.filename + ".yml"
56
56
  debug = options[:debug]
57
+ except = Array(options[:except]) || []
57
58
 
58
59
  require 'yaml'
59
60
 
60
61
  puts "* Loading game objects from #{file}" if debug
61
62
  if File.exists?(file)
62
- game_objects = YAML.load_file(file)
63
- game_objects.each do |game_object|
64
- game_object.each_pair do |klassname, attributes|
63
+ objects = YAML.load_file(file)
64
+ objects.each do |object|
65
+ object.each_pair do |klassname, attributes|
65
66
  begin
66
67
  klass = Kernel::const_get(klassname)
67
- unless klass.class == "GameObject"
68
+ unless klass.class == "GameObject" && !except.include?(klass)
68
69
  puts "Creating #{klassname.to_s}: #{attributes.to_s}" if debug
69
- klass.create(attributes)
70
+ object = klass.create(attributes)
71
+ object.options[:created_with_editor] = true if object.options
70
72
  end
71
73
  rescue
72
74
  puts "Couldn't create class '#{klassname}'"
@@ -74,6 +76,7 @@ module Chingu
74
76
  end
75
77
  end
76
78
  end
79
+ self.game_objects.sync
77
80
  end
78
81
 
79
82
  #
@@ -91,7 +94,8 @@ module Chingu
91
94
  require 'yaml'
92
95
  objects = []
93
96
  game_objects.each do |game_object|
94
- next if classes and !classes.include?(game_object.class)
97
+ # Only save specified classes, if given.
98
+ next if classes and !classes.empty? and !classes.include?(game_object.class)
95
99
 
96
100
  objects << {game_object.class.to_s =>
97
101
  {
@@ -99,8 +103,10 @@ module Chingu
99
103
  :y => game_object.y,
100
104
  :angle => game_object.angle,
101
105
  :zorder => game_object.zorder,
102
- #:factor_x => game_object.factor_x,
103
- #:factor_y => game_object.factor_y,
106
+ :factor_x => game_object.factor_x,
107
+ :factor_y => game_object.factor_y,
108
+ :color => game_object.color.argb,
109
+ #:color => sprintf("0x%x",game_object.color.argb)
104
110
  #:center_x => game_object.center_x,
105
111
  #:center_y => game_object.center_y,
106
112
  }
@@ -53,10 +53,10 @@ module Chingu
53
53
  KbLeftShift => [:left_shift, :lshift],
54
54
 
55
55
 
56
- KbNumpadAdd => [:"+", :add],
56
+ KbNumpadAdd => [:"+", :add, :plus],
57
57
  KbNumpadDivide => [:"/", :divide],
58
58
  KbNumpadMultiply => [:"*", :multiply],
59
- KbNumpadSubtract => [:"-", :subtract],
59
+ KbNumpadSubtract => [:"-", :subtract, :minus],
60
60
  KbPageDown => [:page_down],
61
61
  KbPageUp => [:page_up],
62
62
  # KbPause => [:pause],
@@ -54,16 +54,17 @@ module Chingu
54
54
  #
55
55
  def load_animations
56
56
  animations = {}
57
- glob = "#{trait_options[:animation][:directory]}/#{self.filename}_*"
57
+ glob = "#{trait_options[:animation][:directory]}/#{self.filename}*"
58
58
  puts "Animations? #{glob}" if trait_options[:animation][:debug]
59
59
  Dir[glob].each do |tile_file|
60
- #state = :default
60
+ puts tile_file if trait_options[:animation][:debug]
61
61
  if tile_file =~ /[a-zA-Z\_+]_*(\d+)x(\d+)_*([a-zA-Z]*)\.(bmp|png)/
62
- #if tile_file =~ /_*([a-zA-Z]*)\.(bmp|png)\Z/
63
- #if tile_file =~ /#{self.filename}\.(bmp|png)/
64
62
  state = $3.length > 0 ? $3 : "default"
65
63
  animations[state.to_sym] = Chingu::Animation.new(trait_options[:animation].merge(:file => tile_file))
64
+ elsif tile_file =~ /[a-zA-Z\_+]\.(bmp|png)/
65
+ animations[:default] = Chingu::Animation.new(trait_options[:animation].merge(:file => tile_file))
66
66
  end
67
+
67
68
  end
68
69
  return animations
69
70
  end
@@ -26,6 +26,8 @@ module Chingu
26
26
  # x, y, factor_x, factor_y and rotation_center
27
27
  #
28
28
  module BoundingBox
29
+ CENTER_TO_FACTOR = { 0 => -1, 0.5 => 0, 1 => 1 }
30
+ attr_accessor :collidable
29
31
 
30
32
  module ClassMethods
31
33
  def initialize_trait(options = {})
@@ -35,6 +37,7 @@ module Chingu
35
37
 
36
38
  def setup_trait(options)
37
39
  @cached_bounding_box = nil
40
+ @collidable = true
38
41
  super
39
42
  end
40
43
 
@@ -60,10 +63,12 @@ module Chingu
60
63
  width = width * trait_options[:bounding_box][:scale]
61
64
  height = height * trait_options[:bounding_box][:scale]
62
65
  end
63
-
64
- x = self.x - (width * self.center_x.abs)
65
- y = self.y - (height * self.center_y.abs)
66
-
66
+
67
+ x = self.x - width * self.center_x
68
+ y = self.y - height * self.center_y
69
+ x += width * CENTER_TO_FACTOR[self.center_x] if self.factor_x < 0
70
+ y += height * CENTER_TO_FACTOR[self.center_y] if self.factor_y < 0
71
+
67
72
  return Rect.new(x, y, width, height)
68
73
  end
69
74
  alias :bb :bounding_box
@@ -28,6 +28,7 @@ module Chingu
28
28
  # ...this usually only makes sense with rotation_center = :center
29
29
  #
30
30
  module BoundingCircle
31
+ attr_accessor :collidable
31
32
 
32
33
  module ClassMethods
33
34
  def initialize_trait(options = {})
@@ -37,6 +38,7 @@ module Chingu
37
38
 
38
39
  def setup_trait(options)
39
40
  @cached_radius = nil
41
+ @collidable = true
40
42
  super
41
43
  end
42
44
 
@@ -33,6 +33,7 @@ module Chingu
33
33
  # radius - a number
34
34
  #
35
35
  module CollisionDetection
36
+ attr_accessor :collidable
36
37
 
37
38
  module ClassMethods
38
39
  def initialize_trait(options = {})
@@ -40,6 +41,11 @@ module Chingu
40
41
  end
41
42
  end
42
43
 
44
+ def setup_trait(options)
45
+ @collidable = true
46
+ super
47
+ end
48
+
43
49
  #
44
50
  # The standard method called when self needs to be checked for a collision with another object
45
51
  # By default it calls bounding_box_collision? which will check for intersectons between the
@@ -61,6 +67,7 @@ module Chingu
61
67
  # Returns true if colliding.
62
68
  #
63
69
  def bounding_box_collision?(object2)
70
+ return false unless self.collidable && object2.collidable
64
71
  self.bounding_box.collide_rect?(object2.bounding_box)
65
72
  end
66
73
 
@@ -69,6 +76,7 @@ module Chingu
69
76
  # Returns true if colliding.
70
77
  #
71
78
  def bounding_circle_collision?(object2)
79
+ return false unless self.collidable && object2.collidable
72
80
  Gosu.distance(self.x, self.y, object2.x, object2.y) < self.radius + object2.radius
73
81
  end
74
82
 
@@ -78,6 +86,8 @@ module Chingu
78
86
  # http://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection
79
87
  #
80
88
  def bounding_box_bounding_circle_collision?(object2)
89
+ return false unless self.collidable && object2.collidable
90
+
81
91
  rect = self.respond_to?(:bounding_box) ? self.bounding_box : object2.bounding_box
82
92
  circle = self.respond_to?(:radius) ? self : object2
83
93
  radius = circle.radius.to_i
@@ -101,7 +111,7 @@ module Chingu
101
111
  #
102
112
  def each_collision(*klasses)
103
113
  Array(klasses).each do |klass|
104
- klass.all.each do |object|
114
+ (klass.respond_to?(:all) ? klass.all : klass).each do |object|
105
115
  yield(self, object) if collides?(object)
106
116
  end
107
117
  end
@@ -109,7 +119,7 @@ module Chingu
109
119
 
110
120
  def first_collision(*klasses)
111
121
  Array(klasses).each do |klass|
112
- klass.all.each do |object|
122
+ (klass.respond_to?(:all) ? klass.all : klass).each do |object|
113
123
  return object if collides?(object)
114
124
  end
115
125
  end
@@ -122,7 +132,8 @@ module Chingu
122
132
  #
123
133
  def each_bounding_circle_collision(*klasses)
124
134
  Array(klasses).each do |klass|
125
- klass.all.each do |object|
135
+ (klass.respond_to?(:all) ? klass.all : klass).each do |object|
136
+ next unless self.collidable && object.collidable
126
137
  yield(self, object) if Gosu.distance(self.x, self.y, object.x, object.y) < self.radius + object.radius
127
138
  end
128
139
  end
@@ -134,7 +145,8 @@ module Chingu
134
145
  #
135
146
  def each_bounding_box_collision(*klasses)
136
147
  Array(klasses).each do |klass|
137
- klass.all.each do |object|
148
+ (klass.respond_to?(:all) ? klass.all : klass).each do |object|
149
+ return false unless self.collidable && object.collidable
138
150
  yield(self, object) if self.bounding_box.collide_rect?(object.bounding_box)
139
151
  end
140
152
  end
@@ -147,12 +159,13 @@ module Chingu
147
159
  #
148
160
  def each_bounding_circle_collision(*klasses)
149
161
  Array(klasses).each do |klass|
150
- object2_list = klass.all
162
+ object2_list = (klass.respond_to?(:all) ? klass.all : klass)
151
163
  #total_radius = object1.radius + object2.radius # possible optimization?
152
164
 
153
165
  self.all.each do |object1|
154
166
  object2_list.each do |object2|
155
167
  next if object1 == object2 # Don't collide objects with themselves
168
+ next unless object1.collidable && object2.collidable
156
169
  yield object1, object2 if Gosu.distance(object1.x, object1.y, object2.x, object2.y) < object1.radius + object2.radius
157
170
  end
158
171
  end
@@ -164,10 +177,11 @@ module Chingu
164
177
  #
165
178
  def each_bounding_box_collision(*klasses)
166
179
  Array(klasses).each do |klass|
167
- object2_list = klass.all
180
+ object2_list = (klass.respond_to?(:all) ? klass.all : klass)
168
181
  self.all.each do |object1|
169
182
  object2_list.each do |object2|
170
183
  next if object1 == object2 # Don't collide objects with themselves
184
+ next unless object1.collidable && object2.collidable
171
185
  yield object1, object2 if object1.bounding_box.collide_rect?(object2.bounding_box)
172
186
  end
173
187
  end
@@ -189,18 +203,20 @@ module Chingu
189
203
  # Make sure klasses is always an array.
190
204
  Array(klasses).each do |klass|
191
205
 
192
- if self.instance_methods.include?(:radius) && klass.instance_methods.include?(:radius)
193
- self.each_bounding_circle_collision(klass) do |o1, o2|
194
- yield o1, o2
206
+ if self.respond_to?(:instance_methods) && klass.respond_to?(:instance_methods)
207
+ if self.instance_methods.include?(:radius) && klass.instance_methods.include?(:radius)
208
+ self.each_bounding_circle_collision(klass) do |o1, o2|
209
+ yield o1, o2
210
+ end
211
+ next
195
212
  end
196
- next
197
- end
198
213
 
199
- if self.instance_methods.include?(:bounding_box) && klass.instance_methods.include?(:bounding_box)
200
- self.each_bounding_box_collision(klass) do |o1, o2|
201
- yield o1, o2
214
+ if self.instance_methods.include?(:bounding_box) && klass.instance_methods.include?(:bounding_box)
215
+ self.each_bounding_box_collision(klass) do |o1, o2|
216
+ yield o1, o2
217
+ end
218
+ next
202
219
  end
203
- next
204
220
  end
205
221
 
206
222
  #
@@ -217,7 +233,7 @@ module Chingu
217
233
  # end
218
234
  # end
219
235
  #end
220
- object2_list = klass.all
236
+ object2_list = (klass.respond_to?(:all) ? klass.all : klass)
221
237
  self.all.each do |object1|
222
238
  object2_list.each do |object2|
223
239
  next if object1 == object2 # Don't collide objects with themselves
@@ -42,40 +42,40 @@ module Chingu
42
42
 
43
43
  @velocity_x = options[:velocity_x] || 0
44
44
  @velocity_y = options[:velocity_y] || 0
45
- self.velocity = options[:velocity] if options[:velocity]
45
+ self.velocity = options[:velocity] if options[:velocity]
46
46
 
47
47
  @acceleration_x = options[:acceleration_x] || 0
48
48
  @acceleration_y = options[:acceleration_y] || 0
49
- self.acceleration = options[:acceleration] if options[:acceleration]
49
+ self.acceleration = options[:acceleration] if options[:acceleration]
50
50
 
51
51
  @max_velocity = options[:max_velocity] || 1000
52
52
  super
53
53
  end
54
54
 
55
- #
56
- # Sets X and Y velocity with one single call. Takes an Array-argument with 2 values.
57
- #
58
- def velocity=(velocity)
59
- @velocity_x, @velocity_y = velocity
60
- end
55
+ #
56
+ # Sets X and Y velocity with one single call. Takes an Array-argument with 2 values.
57
+ #
58
+ def velocity=(velocity)
59
+ @velocity_x, @velocity_y = velocity
60
+ end
61
61
 
62
- def velocity; [@velocity_x, @velocity_y]; end
62
+ def velocity; [@velocity_x, @velocity_y]; end
63
63
 
64
- #
65
- # Sets X and Y acceleration with one single call. Takes an Array-argument with 2 values.
66
- #
67
- def acceleration=(acceleration)
68
- @acceleration_x, @acceleration_y = acceleration
69
- end
64
+ #
65
+ # Sets X and Y acceleration with one single call. Takes an Array-argument with 2 values.
66
+ #
67
+ def acceleration=(acceleration)
68
+ @acceleration_x, @acceleration_y = acceleration
69
+ end
70
70
 
71
- def acceleration; [@acceleration_x, @acceleration_y]; end
71
+ def acceleration; [@acceleration_x, @acceleration_y]; end
72
72
 
73
73
  #
74
74
  # Modifies X & Y of parent
75
75
  #
76
76
  def update_trait
77
- @velocity_y += @acceleration_y if (@velocity_y + @acceleration_y).abs < @max_velocity
78
- @velocity_x += @acceleration_x if (@velocity_x + @acceleration_x).abs < @max_velocity
77
+ @velocity_y += @acceleration_y if (@velocity_y + @acceleration_y).abs < @max_velocity
78
+ @velocity_x += @acceleration_x if (@velocity_x + @acceleration_x).abs < @max_velocity
79
79
 
80
80
  @previous_y = @y
81
81
  @previous_x = @x
@@ -91,11 +91,29 @@ module Chingu
91
91
  super
92
92
  end
93
93
 
94
+ #
95
+ # Setts velocity_x and velocity_y to 0, stopping the game object
96
+ # Note it doesn't reset the acceleration!
97
+ #
94
98
  def stop
95
99
  # @acceleration_y = @acceleration_x = 0
96
100
  @velocity_x = 0
97
101
  @velocity_y = 0
98
- end
102
+ end
103
+
104
+ #
105
+ # Returns true if both velocity_x and velocity_y is 0
106
+ #
107
+ def stopped?
108
+ @velocity_x == 0 && @velocity_y == 0
109
+ end
110
+
111
+ #
112
+ # Did game object move last tick
113
+ #
114
+ def moved?
115
+ @x != @previous_x || @y != @previous_y
116
+ end
99
117
  end
100
118
  end
101
119
  end
@@ -70,6 +70,7 @@ module Chingu
70
70
  #
71
71
  def draw
72
72
  self.game_objects.draw_relative(-@viewport.x, -@viewport.y)
73
+ #@viewport.apply { super }
73
74
  end
74
75
  end
75
76
  end
@@ -82,14 +82,15 @@ module Chingu
82
82
  # This is a very flawed implementation, it Should take inte account objects
83
83
  # height,width,factor_x,factor_y,center_x,center_y as well...
84
84
  #
85
- def inside?(object)
86
- object.x >= @x && object.x <= (@x + $window.width) &&
87
- object.y >= @y && object.y <= (@y + $window.height)
85
+ def inside?(object, y = nil)
86
+ x, y = y ? [object,y] : [object.x, object.y]
87
+ x >= @x && x <= (@x + $window.width) &&
88
+ y >= @y && y <= (@y + $window.height)
88
89
  end
89
90
 
90
91
  # Returns true object is outside the view port
91
- def outside?(object)
92
- not inside_viewport?(object)
92
+ def outside?(object, y)
93
+ not inside?(object, y)
93
94
  end
94
95
 
95
96
  #
@@ -145,5 +146,9 @@ module Chingu
145
146
  end
146
147
  end
147
148
 
149
+ def apply(&block)
150
+ $window.translate(-@x, -@y, &block)
151
+ end
152
+
148
153
  end
149
154
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chingu
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 7
9
- - 5
10
- version: 0.7.5
9
+ - 6
10
+ version: 0.7.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - ippa
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-06-13 00:00:00 +02:00
18
+ date: 2010-06-17 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -26,12 +26,12 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- hash: 39
29
+ hash: 47
30
30
  segments:
31
31
  - 0
32
32
  - 7
33
- - 18
34
- version: 0.7.18
33
+ - 22
34
+ version: 0.7.22
35
35
  type: :runtime
36
36
  version_requirements: *id001
37
37
  description: OpenGL accelerated 2D game framework for Ruby. Builds on Gosu (Ruby/C++) which provides all the core functionality. Chingu adds simple yet powerful game states, prettier input handling, deployment safe asset-handling, a basic re-usable game object and stackable game logic.
@@ -68,10 +68,12 @@ files:
68
68
  - examples/example16_online_high_scores.rb
69
69
  - examples/example17_gosu_tutorial.rb
70
70
  - examples/example18_animation_trait.rb
71
+ - examples/example19.yml
71
72
  - examples/example19_edit_viewport.rb
72
- - examples/example19_game_objects.yml
73
73
  - examples/example1_basics.rb
74
74
  - examples/example20_trait_inheritence_test.rb
75
+ - examples/example21.yml
76
+ - examples/example21_sidescroller_with_edit.rb
75
77
  - examples/example2_gamestate_basics.rb
76
78
  - examples/example3_parallax.rb
77
79
  - examples/example4_gamestates.rb
@@ -90,11 +92,16 @@ files:
90
92
  - examples/media/Star.png
91
93
  - examples/media/Starfighter.bmp
92
94
  - examples/media/background1.png
95
+ - examples/media/battery.png
96
+ - examples/media/big_star.png
97
+ - examples/media/big_stone_wall.bmp
98
+ - examples/media/black_block.png
93
99
  - examples/media/bullet.png
94
100
  - examples/media/bullet_hit.wav
95
101
  - examples/media/circle.png
96
102
  - examples/media/city1.png
97
103
  - examples/media/city2.png
104
+ - examples/media/cog_wheel.png
98
105
  - examples/media/droid.bmp
99
106
  - examples/media/droid_11x15.bmp
100
107
  - examples/media/droid_11x15.gal
@@ -111,11 +118,13 @@ files:
111
118
  - examples/media/ruby.png
112
119
  - examples/media/saucer.gal
113
120
  - examples/media/saucer.png
121
+ - examples/media/saw.png
114
122
  - examples/media/spaceship.png
115
123
  - examples/media/star_25x25_default.png
116
124
  - examples/media/star_25x25_explode.gal
117
125
  - examples/media/star_25x25_explode.png
118
126
  - examples/media/stone_wall.bmp
127
+ - examples/media/tube.png
119
128
  - examples/media/video_games.png
120
129
  - examples/media/wood.png
121
130
  - lib/chingu.rb
@@ -208,6 +217,7 @@ test_files:
208
217
  - examples/example19_edit_viewport.rb
209
218
  - examples/example1_basics.rb
210
219
  - examples/example20_trait_inheritence_test.rb
220
+ - examples/example21_sidescroller_with_edit.rb
211
221
  - examples/example2_gamestate_basics.rb
212
222
  - examples/example3_parallax.rb
213
223
  - examples/example4_gamestates.rb