chingu 0.5.9 → 0.5.9.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.tar.gz.sig CHANGED
Binary file
data/Manifest.txt CHANGED
@@ -65,6 +65,7 @@ lib/chingu/game_object_list.rb
65
65
  lib/chingu/game_state.rb
66
66
  lib/chingu/game_state_manager.rb
67
67
  lib/chingu/game_states/debug.rb
68
+ lib/chingu/game_states/edit.rb
68
69
  lib/chingu/game_states/fade_to.rb
69
70
  lib/chingu/game_states/pause.rb
70
71
  lib/chingu/helpers/game_object.rb
data/chingu.gemspec CHANGED
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{chingu}
5
- s.version = "0.5.9"
5
+ s.version = "0.5.9.2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["ippa"]
9
- s.date = %q{2009-10-25}
9
+ s.date = %q{2009-11-09}
10
10
  s.description = %q{OpenGL accelerated 2D game framework for Ruby.
11
11
  Builds on the awesome Gosu (Ruby/C++) which provides all the core functionality.
12
12
  It adds simple yet powerful game states, prettier input handling, deployment safe asset-handling, a basic re-usable game object and automation of common task.}
13
13
  s.email = ["ippa@rubylicio.us"]
14
14
  s.extra_rdoc_files = ["History.txt", "Manifest.txt", "benchmarks/README.txt"]
15
- s.files = ["History.txt", "LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "benchmarks/README.txt", "benchmarks/benchmark.rb", "benchmarks/benchmark3.rb", "benchmarks/benchmark4.rb", "benchmarks/benchmark5.rb", "benchmarks/benchmark6.rb", "benchmarks/meta_benchmark.rb", "benchmarks/meta_benchmark2.rb", "chingu.gemspec", "examples/example1.rb", "examples/example10.rb", "examples/example11.rb", "examples/example12.rb", "examples/example13.rb", "examples/example2.rb", "examples/example3.rb", "examples/example4.rb", "examples/example5.rb", "examples/example6.rb", "examples/example7.rb", "examples/example8.rb", "examples/example9.rb", "examples/game1.rb", "examples/high_score_list.yml", "examples/media/Parallax-scroll-example-layer-0.png", "examples/media/Parallax-scroll-example-layer-1.png", "examples/media/Parallax-scroll-example-layer-2.png", "examples/media/Parallax-scroll-example-layer-3.png", "examples/media/background1.png", "examples/media/bullet.png", "examples/media/bullet_hit.wav", "examples/media/city1.csv", "examples/media/city1.png", "examples/media/city2.png", "examples/media/droid.bmp", "examples/media/enemy_bullet.png", "examples/media/explosion.wav", "examples/media/fire_bullet.png", "examples/media/fireball.png", "examples/media/laser.wav", "examples/media/particle.png", "examples/media/plane.csv", "examples/media/plane.png", "examples/media/ruby.png", "examples/media/saucer.csv", "examples/media/saucer.gal", "examples/media/saucer.png", "examples/media/spaceship.png", "examples/media/stickfigure.bmp", "examples/media/stickfigure.png", "examples/media/video_games.png", "lib/chingu.rb", "lib/chingu/animation.rb", "lib/chingu/assets.rb", "lib/chingu/basic_game_object.rb", "lib/chingu/core_extensions.rb", "lib/chingu/fpscounter.rb", "lib/chingu/game_object.rb", "lib/chingu/game_object_list.rb", "lib/chingu/game_state.rb", "lib/chingu/game_state_manager.rb", "lib/chingu/game_states/debug.rb", "lib/chingu/game_states/fade_to.rb", "lib/chingu/game_states/pause.rb", "lib/chingu/helpers/game_object.rb", "lib/chingu/helpers/game_state.rb", "lib/chingu/helpers/gfx.rb", "lib/chingu/helpers/input_client.rb", "lib/chingu/helpers/input_dispatcher.rb", "lib/chingu/helpers/rotation_center.rb", "lib/chingu/high_score_list.rb", "lib/chingu/inflector.rb", "lib/chingu/input.rb", "lib/chingu/named_resource.rb", "lib/chingu/parallax.rb", "lib/chingu/particle.rb", "lib/chingu/rect.rb", "lib/chingu/require_all.rb", "lib/chingu/text.rb", "lib/chingu/traits/collision_detection.rb", "lib/chingu/traits/effect.rb", "lib/chingu/traits/retrofy.rb", "lib/chingu/traits/timer.rb", "lib/chingu/traits/velocity.rb", "lib/chingu/window.rb"]
15
+ s.files = ["History.txt", "LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "benchmarks/README.txt", "benchmarks/benchmark.rb", "benchmarks/benchmark3.rb", "benchmarks/benchmark4.rb", "benchmarks/benchmark5.rb", "benchmarks/benchmark6.rb", "benchmarks/meta_benchmark.rb", "benchmarks/meta_benchmark2.rb", "chingu.gemspec", "examples/example1.rb", "examples/example10.rb", "examples/example11.rb", "examples/example12.rb", "examples/example13.rb", "examples/example2.rb", "examples/example3.rb", "examples/example4.rb", "examples/example5.rb", "examples/example6.rb", "examples/example7.rb", "examples/example8.rb", "examples/example9.rb", "examples/game1.rb", "examples/high_score_list.yml", "examples/media/Parallax-scroll-example-layer-0.png", "examples/media/Parallax-scroll-example-layer-1.png", "examples/media/Parallax-scroll-example-layer-2.png", "examples/media/Parallax-scroll-example-layer-3.png", "examples/media/background1.png", "examples/media/bullet.png", "examples/media/bullet_hit.wav", "examples/media/city1.csv", "examples/media/city1.png", "examples/media/city2.png", "examples/media/droid.bmp", "examples/media/enemy_bullet.png", "examples/media/explosion.wav", "examples/media/fire_bullet.png", "examples/media/fireball.png", "examples/media/laser.wav", "examples/media/particle.png", "examples/media/plane.csv", "examples/media/plane.png", "examples/media/ruby.png", "examples/media/saucer.csv", "examples/media/saucer.gal", "examples/media/saucer.png", "examples/media/spaceship.png", "examples/media/stickfigure.bmp", "examples/media/stickfigure.png", "examples/media/video_games.png", "lib/chingu.rb", "lib/chingu/animation.rb", "lib/chingu/assets.rb", "lib/chingu/basic_game_object.rb", "lib/chingu/core_extensions.rb", "lib/chingu/fpscounter.rb", "lib/chingu/game_object.rb", "lib/chingu/game_object_list.rb", "lib/chingu/game_state.rb", "lib/chingu/game_state_manager.rb", "lib/chingu/game_states/debug.rb", "lib/chingu/game_states/edit.rb", "lib/chingu/game_states/fade_to.rb", "lib/chingu/game_states/pause.rb", "lib/chingu/helpers/game_object.rb", "lib/chingu/helpers/game_state.rb", "lib/chingu/helpers/gfx.rb", "lib/chingu/helpers/input_client.rb", "lib/chingu/helpers/input_dispatcher.rb", "lib/chingu/helpers/rotation_center.rb", "lib/chingu/high_score_list.rb", "lib/chingu/inflector.rb", "lib/chingu/input.rb", "lib/chingu/named_resource.rb", "lib/chingu/parallax.rb", "lib/chingu/particle.rb", "lib/chingu/rect.rb", "lib/chingu/require_all.rb", "lib/chingu/text.rb", "lib/chingu/traits/collision_detection.rb", "lib/chingu/traits/effect.rb", "lib/chingu/traits/retrofy.rb", "lib/chingu/traits/timer.rb", "lib/chingu/traits/velocity.rb", "lib/chingu/window.rb"]
16
16
  s.homepage = %q{http://github.com/ippa/chingu/tree/master}
17
17
  s.rdoc_options = ["--main", "README.rdoc"]
18
18
  s.require_paths = ["lib"]
data/examples/game1.rb CHANGED
@@ -75,7 +75,8 @@ class Level < Chingu::GameState
75
75
 
76
76
  @parallax = Parallax.create
77
77
  ParallaxLayer.has_trait :retrofy
78
- @parallax << ParallaxLayer.new(:image => Image["city2.png"].retrofy, :center => 0, :damping => 5, :factor => $window.factor)
78
+ #@parallax << ParallaxLayer.new(:image => Image["city3.png"].retrofy, :center => 0, :damping => 4, :factor => $window.factor)
79
+ @parallax << ParallaxLayer.new(:image => Image["city2.png"].retrofy, :center => 0, :damping => 2, :factor => $window.factor)
79
80
  @parallax << ParallaxLayer.new(:image => Image["city1.png"].retrofy, :center => 0, :damping => 1, :factor => $window.factor)
80
81
  @player = Player.create(:x => 10, :y => 100)
81
82
 
@@ -102,10 +103,14 @@ class Level < Chingu::GameState
102
103
  end
103
104
 
104
105
  #
105
- # Our
106
+ # The foremost layer in our parallax scroller is the collidable terrain
106
107
  #
107
108
  def solid_pixel_at?(x, y)
108
- @parallax.layers.last.get_pixel(x, y)[3] != 0
109
+ begin
110
+ @parallax.layers.last.get_pixel(x, y)[3] != 0
111
+ rescue
112
+ puts "Error in get_pixel(#{x}, #{y})"
113
+ end
109
114
  end
110
115
 
111
116
  def update
@@ -114,9 +119,12 @@ class Level < Chingu::GameState
114
119
  # Move the level forward by increasing the parallax-scrollers camera x-coordinate
115
120
  @parallax.camera_x += 1
116
121
 
117
- #
118
- Bullet.all.select { |b| solid_pixel_at?(b.x, b.y)}.each { |b| b.die }
119
-
122
+ # Remove all objects outside screen
123
+ game_objects.destroy_if { |game_object| game_object.respond_to?("outside_window?") && game_object.outside_window? }
124
+
125
+ # Collide bullets with terrain
126
+ Bullet.all.select { |o| solid_pixel_at?(o.x, o.y)}.each { |o| o.die }
127
+
120
128
  # Collide player with terrain
121
129
  push_game_state(GameOver) if solid_pixel_at?(@player.x, @player.y)
122
130
 
@@ -143,7 +151,7 @@ class Level < Chingu::GameState
143
151
 
144
152
  #push_game_state(Done.new(:score => @player.score)) if @game_steps == 1
145
153
 
146
- $window.caption = "City Battle! Score: #{@player.score}"
154
+ $window.caption = "City Battle! Score: #{@player.score} .... FPS: #{$window.fps} ... game objects: #{game_objects.size}"
147
155
  end
148
156
 
149
157
  def draw
@@ -156,7 +164,7 @@ end
156
164
  # OUR PLAYER
157
165
  #
158
166
  class Player < GameObject
159
- has_trait :velocity, :collision_detection, :retrofy
167
+ has_trait :velocity, :collision_detection, :retrofy, :timer
160
168
  attr_accessor :score
161
169
 
162
170
  def initialize(options = {})
@@ -169,11 +177,12 @@ class Player < GameObject
169
177
  :holding_right => :right,
170
178
  :holding_up => :up,
171
179
  :holding_down => :down,
172
- :space => :fire }
180
+ :holding_space => :fire }
173
181
 
174
182
  @max_velocity = 1
175
183
  @radius = 10
176
184
  @score = 0
185
+ @cooling_down = false
177
186
  end
178
187
 
179
188
  def up
@@ -190,8 +199,12 @@ class Player < GameObject
190
199
  end
191
200
 
192
201
  def fire
202
+ return if @cooling_down
203
+ @cooling_down = true
204
+ after(100) { @cooling_down = false}
205
+
193
206
  Bullet.create(:x => self.x, :y => self.y)
194
- Sound["laser.wav"].play
207
+ Sound["laser.wav"].play(0.1)
195
208
  end
196
209
 
197
210
  def update
@@ -223,7 +236,7 @@ class Bullet < GameObject
223
236
 
224
237
  def die
225
238
  return if @status == :dying
226
- Sound["bullet_hit.wav"].play
239
+ Sound["bullet_hit.wav"].play(0.2)
227
240
  @status = :dying
228
241
  during(50) { @factor_x += 1; @factor_y += 1; @x -= 1; }.then { self.destroy }
229
242
  end
@@ -245,11 +258,74 @@ class EnemyBullet < Bullet
245
258
  end
246
259
  end
247
260
 
261
+ class Explosion < GameObject
262
+ has_trait :timer,:retrofy
263
+
264
+ def initialize(options)
265
+ super
266
+
267
+ unless defined?(@@image)
268
+ @@image = TexPlay::create_blank_image($window, 100, 100)
269
+ @@image.paint { circle 50,50,49, :fill => true, :color => [1,1,1,1] }
270
+ end
271
+
272
+ @image = @@image.dup if @image.nil?
273
+
274
+
275
+ self.rotation_center(:center)
276
+ self.factor = options[:factor] ? options[:factor] : $window.factor
277
+ during(100) { self.alpha -= 30}.then { destroy }
278
+ end
279
+
280
+ def self.create_image_for(object)
281
+ width = height = (object.image.width + object.image.height) / 2
282
+ explosion_image = TexPlay::create_blank_image($window, 100, 100)
283
+ explosion_image.paint { circle 50,50,49, :fill => true, :color => [1,1,1,1] }
284
+ return explosion_image
285
+ end
286
+
287
+ end
288
+
289
+ class Shrapnel < GameObject
290
+ has_trait :retrofy, :timer, :effect, :velocity
291
+
292
+ def initialize(options)
293
+ super
294
+
295
+ self.rotation_rate = 1 + rand(10)
296
+ self.velocity_x = 4 - rand(8)
297
+ self.velocity_y = 4 - rand(10)
298
+ self.acceleration_y = 0.2 # gravity = downards acceleration
299
+
300
+ rotation_center(:center)
301
+ self.factor = $window.factor
302
+ @status = :default
303
+ end
304
+
305
+ def self.create_image_for(object)
306
+ image = object.image
307
+ width = image.width / 5
308
+ height = image.width / 5
309
+
310
+ shrapnel_image = TexPlay::create_blank_image($window, width, height)
311
+ x1 = rand(image.width/width)
312
+ y1 = rand(image.height/height)
313
+ shrapnel_image.paint { splice image,0,0, :crop => [x1, y1, x1+width, y1+height] }
314
+
315
+ return shrapnel_image
316
+ end
317
+
318
+ def die
319
+ destroy
320
+ end
321
+
322
+ end
323
+
248
324
  #
249
325
  # OUR ENEMY SAUCER
250
326
  #
251
327
  class Enemy < GameObject
252
- has_trait :collision_detection, :retrofy, :timer
328
+ has_trait :collision_detection, :retrofy, :timer
253
329
 
254
330
  def initialize(options)
255
331
  super
@@ -259,17 +335,28 @@ class Enemy < GameObject
259
335
  @anim = Animation.new(:file => "media/saucer.png", :size => [32,13], :delay => 100)
260
336
  @anim.retrofy
261
337
  @image = @anim.first
262
-
338
+
263
339
  self.factor = $window.factor
264
340
  @radius = 5
265
341
  @black = Color.new(0xFF000000)
266
342
  @status == :default
343
+
344
+ #
345
+ # Cache explosion and shrapnel images (created with texplay, not recomended doing over and over each time)
346
+ #
347
+ @@shrapnel_image ||= Shrapnel.create_image_for(self)
348
+ @@explosion_image ||= Explosion.create_image_for(self)
267
349
  end
268
350
 
269
351
  def hit_by(object)
270
352
  return if @status == :dying
271
353
 
354
+ #
355
+ # During 20 millisecons, use Gosus :additive draw-mode, which here results in a white sprite
356
+ # Classic "hit by a bullet"-effect
357
+ #
272
358
  during(20) { @mode = :additive; }.then { @mode = :default }
359
+
273
360
  @health -= 20
274
361
 
275
362
  if @health <= 0
@@ -285,9 +372,24 @@ class Enemy < GameObject
285
372
  end
286
373
 
287
374
  def die
375
+ #
376
+ # Make sure die() is only called once
377
+ #
288
378
  return if @status == :dying
289
- Sound["explosion.wav"].play
290
379
  @status = :dying
380
+
381
+ #
382
+ # Play our explosion-sound file
383
+ # Create an explosion-object
384
+ # Create some shrapnel-objects
385
+ #
386
+ Sound["explosion.wav"].play(0.3)
387
+ Explosion.create(:x => @x, :y => @y, :image => @@explosion_image )
388
+ 5.times { Shrapnel.create(:x => @x, :y => @y, :image => @@shrapnel_image)}
389
+
390
+ #
391
+ # During 200 ms, fade and scale image, then destroy it
392
+ #
291
393
  @color = @black
292
394
  @color.alpha = 50
293
395
  during(200) { @factor_x += 0.5; @factor_y += 0.5; @x -= 1; @color.alpha -= 1}.then { self.destroy }
@@ -296,7 +398,7 @@ class Enemy < GameObject
296
398
  def update
297
399
  return if @status == :dying
298
400
 
299
- @image = @anim.next!
401
+ @image = @anim.next
300
402
  @x -= @velocity
301
403
  end
302
404
  end
data/lib/chingu.rb CHANGED
@@ -28,5 +28,5 @@ require File.join(CHINGU_ROOT,"chingu","require_all") # Thanks to http://github.
28
28
  require_all "#{CHINGU_ROOT}/chingu"
29
29
 
30
30
  module Chingu
31
- VERSION = "0.5.9"
31
+ VERSION = "0.5.9.2"
32
32
  end
@@ -10,7 +10,7 @@ module Chingu
10
10
  # Is autodetection of width / height possible?
11
11
  #
12
12
  class Animation
13
- attr_accessor :frames, :delay, :step
13
+ attr_accessor :frames, :delay, :step, :loop, :bounce, :step
14
14
 
15
15
  #
16
16
  # Create a new Animation.
@@ -59,7 +59,7 @@ module Chingu
59
59
  # Returns last frame (GOSU::Image) from animation
60
60
  #
61
61
  def last
62
- @frames.first
62
+ @frames.last
63
63
  end
64
64
 
65
65
  #
data/lib/chingu/assets.rb CHANGED
@@ -7,7 +7,11 @@ module Chingu
7
7
  def media_path(file)
8
8
  File.join(ROOT, "media", file)
9
9
  end
10
-
10
+
11
+ def root_path(file)
12
+ File.join(ROOT, file)
13
+ end
14
+
11
15
  def image_path(file)
12
16
  File.join(ROOT, "images", file)
13
17
  end
@@ -53,7 +53,7 @@ module Chingu
53
53
  # which then will pass it on to the next setup_trait() with a super-call.
54
54
  setup_trait(options)
55
55
  end
56
-
56
+
57
57
  #
58
58
  # Creates a new object from class just as new() but also:
59
59
  # - adds game object to current game state
@@ -74,6 +74,14 @@ module Chingu
74
74
  return instance
75
75
  end
76
76
 
77
+ #
78
+ # This ruby callback is called each time someone subclasses BasicGameObject or GameObject
79
+ # We hook into it to keep track of all game object classes (just as we keep track of game objects instances)
80
+ #
81
+ ## def self.inherited(klass)
82
+ ## instance.parent.add_game_object_class(klass) if instance.parent
83
+ ## end
84
+
77
85
  #
78
86
  # Disable automatic calling of update() and update_trait() each game loop
79
87
  #
@@ -33,6 +33,7 @@ module Chingu
33
33
  include Chingu::Helpers::InputClient # Adds input and input=
34
34
  include Chingu::Helpers::RotationCenter # Adds easy and verbose modification of @center_x and @center_y
35
35
 
36
+
36
37
  def initialize(options = {})
37
38
  super
38
39
 
@@ -61,7 +62,9 @@ module Chingu
61
62
  @color = options[:color]
62
63
  else
63
64
  @color = Gosu::Color.new(options[:color] || 0xFFFFFFFF)
64
- end
65
+ end
66
+
67
+ self.alpha = options[:alpha] if options[:alpha]
65
68
 
66
69
  @mode = options[:mode] || :default # :additive is also available.
67
70
  @zorder = options[:zorder] || 100
@@ -102,6 +102,8 @@ module Chingu
102
102
  def switch_game_state(state, options = {})
103
103
  options = {:setup => true, :finalize => true, :transitional => true}.merge(options)
104
104
 
105
+ @previous_game_state = current_game_state
106
+
105
107
  new_state = game_state_instance(state)
106
108
 
107
109
  if new_state
@@ -109,7 +111,6 @@ module Chingu
109
111
  new_state.game_state_manager = self
110
112
 
111
113
  # Give the soon-to-be-disabled state a chance to clean up by calling finalize() on it.
112
- @previous_game_state = current_game_state
113
114
  current_game_state.finalize if current_game_state.respond_to?(:finalize) && options[:finalize]
114
115
 
115
116
  # So BasicGameObject#create connects object to new state in its setup()
@@ -143,6 +144,8 @@ module Chingu
143
144
  def push_game_state(state, options = {})
144
145
  options = {:setup => true, :finalize => true, :transitional => true}.merge(options)
145
146
 
147
+ @previous_game_state = current_game_state
148
+
146
149
  new_state = game_state_instance(state)
147
150
 
148
151
  if new_state
@@ -157,7 +160,6 @@ module Chingu
157
160
  new_state.game_state_manager = self
158
161
 
159
162
  # Give the soon-to-be-disabled state a chance to clean up by calling finalize() on it.
160
- @previous_game_state = current_game_state
161
163
  current_game_state.finalize if current_game_state.respond_to?(:finalize) && options[:finalize]
162
164
 
163
165
  if @transitional_game_state && options[:transitional]
@@ -0,0 +1,164 @@
1
+ #--
2
+ #
3
+ # Chingu -- OpenGL accelerated 2D game framework for Ruby
4
+ # Copyright (C) 2009 ippa / ippa@rubylicio.us
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ #++
21
+
22
+ module Chingu
23
+ module GameStates
24
+
25
+ #
26
+ # Premade game state for chingu - A simple pause state.
27
+ # Pause whenever with:
28
+ # push_game_state(Chingu::GameStates::Pause)
29
+ #
30
+ # requires the global $window set to the instance of Gosu::Window (automaticly handled if you use Chingu::Window)
31
+ #
32
+ class Edit < Chingu::GameState
33
+ def initialize(options = {})
34
+ super
35
+ @color = Gosu::Color.new(200,0,0,0)
36
+ @red = Gosu::Color.new(0xFFFF0000)
37
+ @white = Gosu::Color.new(0xFFFFFFFF)
38
+ @selected_game_object = nil
39
+ self.input = { :left_mouse_button => :left_mouse_button,
40
+ :released_left_mouse_button => :released_left_mouse_button,
41
+ :e => :save_and_quit,
42
+ :s => :save,
43
+ :esc => :quit
44
+ }
45
+ end
46
+
47
+ def setup
48
+ name = if defined?(previous_game_state.filename)
49
+ previous_game_state.filename
50
+ else
51
+ "#{previous_game_state.class.to_s.downcase}.yml"
52
+ end
53
+ @filename = File.join($window.root, name)
54
+ @title = Text.create("Editing #{@filename}", :x => 5, :y => 10)
55
+ @title2 = Text.create("(S) Save (E) Save and Quit (ESC) Quit without saving", :x => 5, :y => 30)
56
+ @text = Text.create("", :x => 5, :y => 50)
57
+ end
58
+
59
+ def draw
60
+ previous_game_state.draw # Draw prev game state onto screen (in this case our level)
61
+
62
+ $window.draw_quad( 0,0,@color,
63
+ $window.width,0,@color,
64
+ $window.width,100,@color,
65
+ 0,100,@color,10)
66
+ super
67
+
68
+ previous_game_state.game_objects.select { |o| o.options[:selected] }.each do |game_object|
69
+
70
+ # rect = game_object.bounding_box
71
+ # rect.x *= $window.factor
72
+ # rect.y *= $window.factor
73
+ # $window.fill_rect(rect, @red, game_object.zorder - 1)
74
+ end
75
+
76
+ #
77
+ # draw a simple triagle-shaped cursor
78
+ #
79
+ $window.draw_triangle( $window.mouse_x, $window.mouse_y, @white,
80
+ $window.mouse_x, $window.mouse_y + 10, @white,
81
+ $window.mouse_x + 10, $window.mouse_y + 10, @white, 9999)
82
+
83
+ if @left_mouse_button && @selected_game_object
84
+ @selected_game_object.x = $window.mouse_x / $window.factor
85
+ @selected_game_object.y = $window.mouse_y / $window.factor
86
+
87
+ #
88
+ # Can we abstract this out somehow?
89
+ #
90
+ if @selected_game_object.respond_to?(:bounding_box)
91
+ @selected_game_object.bounding_box.x = @selected_game_object.x
92
+ @selected_game_object.bounding_box.y = @selected_game_object.y
93
+ end
94
+ end
95
+ end
96
+
97
+ def left_mouse_button
98
+ @left_mouse_button = true
99
+ x = $window.mouse_x / $window.factor
100
+ y = $window.mouse_y / $window.factor
101
+ @text.text = "Click @ #{x} / #{y}"
102
+ @selected_game_object = game_object_at(x, y)
103
+ if @selected_game_object
104
+ @text.text = "#{@text.text} : #{@game_object.class.to_s}"
105
+ @selected_game_object.options[:selected] = true
106
+ end
107
+ end
108
+
109
+ def released_left_mouse_button
110
+ @left_mouse_button = false
111
+ @selected_game_object = false
112
+ end
113
+
114
+ def game_object_at(x, y)
115
+ previous_game_state.game_objects.select do |game_object|
116
+ game_object.respond_to?(:bounding_box) && game_object.bounding_box.collide_point?(x,y)
117
+ end.first
118
+ end
119
+
120
+
121
+ def save
122
+ require 'yaml'
123
+ objects = []
124
+ previous_game_state.game_objects.each do |game_object|
125
+ objects << {game_object.class.to_s =>
126
+ {
127
+ :x => game_object.x,
128
+ :y => game_object.y,
129
+ :angle => game_object.angle,
130
+ :zorder => game_object.zorder,
131
+ :factor_x => game_object.factor_x,
132
+ :factor_y => game_object.factor_y,
133
+ :center_x => game_object.center_x,
134
+ :center_y => game_object.center_y,
135
+ }
136
+ }
137
+ end
138
+
139
+ #Marshal.dump(previous_game_state.game_objects, File.open(@filename, "w"))
140
+ File.open(@filename, 'w') do |out|
141
+ YAML.dump(objects, out)
142
+ end
143
+ end
144
+
145
+ def save_and_quit
146
+ save
147
+ quit
148
+ end
149
+
150
+ def quit
151
+ pop_game_state
152
+ end
153
+
154
+ #
155
+ # If we're editing a game state with automaticly called special methods,
156
+ # the following takes care of those.
157
+ #
158
+ def method_missing(symbol, *args)
159
+ previous_game_state.__send__(symbol, *args)
160
+ end
161
+
162
+ end
163
+ end
164
+ end
@@ -46,6 +46,33 @@ module Chingu
46
46
  def game_objects_of_class(klass)
47
47
  @game_objects.select { |game_object| game_object.is_a? klass }
48
48
  end
49
+
50
+ #
51
+ # Creates game objects from a Chingu-spezed game objects file (created with game state 'Edit')
52
+ #
53
+ def load_game_objects(options = {})
54
+ filename = options[:file] || "#{self.class.to_s.downcase}.yml"
55
+
56
+ require 'yaml'
57
+
58
+ if File.exists?(filename)
59
+ game_objects = YAML.load_file(filename)
60
+ game_objects.each do |game_object|
61
+ game_object.each_pair do |klassname, attributes|
62
+ begin
63
+ klass = Kernel::const_get(klassname)
64
+ unless klass.class == "GameObject"
65
+ puts "Creating #{klassname.to_s}: #{attributes.to_s}"
66
+ klass.create(attributes)
67
+ end
68
+ rescue
69
+ puts "Couldn't create class '#{klassname}'"
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+
49
76
  end
50
77
 
51
78
  end
@@ -29,26 +29,85 @@ module Chingu
29
29
  module GFX
30
30
 
31
31
  #
32
- # Fills whole window with color 'color'.
32
+ # Fills whole window with specified 'color' and 'zorder'
33
33
  #
34
- def fill(color)
35
- $window.draw_quad(0, 0, color,
36
- $window.width, 0, color,
37
- $window.width, $window.height, color,
38
- 0, $window.height, color,
39
- 0, :default)
34
+ #def fill(color, zorder = 0)
35
+ # $window.draw_quad(0, 0, color,
36
+ # $window.width, 0, color,
37
+ # $window.width, $window.height, color,
38
+ # 0, $window.height, color,
39
+ # zorder, :default)
40
+ #end
41
+ #
42
+
43
+ # Fills window or a given rect with a gradient between two colors.
44
+ #
45
+ # :from - Start with this color
46
+ # :to - End with this color
47
+ # :rect - Only fill rectangle :rect with the gradient, either a Rect-instance or [x,y,width,height] Array.
48
+ # :orientation - Either :vertical (top to bottom) or :horizontal (left to right)
49
+ #
50
+
51
+ def fill(options)
52
+ #
53
+ # if only 1 color-argument is given, assume fullscreen simple color fill.
54
+ #
55
+ if options.is_a?(Gosu::Color)
56
+ $window.draw_quad(0, 0, color,
57
+ $window.width, 0, options,
58
+ $window.width, $window.height, options,
59
+ 0, $window.height, options, 0, :default)
60
+ return
61
+ end
62
+
63
+ default_options = { :colors => [Gosu::Color.new(0xFFFFFFFF), Gosu::Color.new(0xFF000000)],
64
+ :orientation => :vertical,
65
+ :rect => Rect.new([0, 0, $window.width, $window.height]),
66
+ :zorder => 0,
67
+ :mode => :default
68
+ }
69
+ options = default_options.merge(options)
70
+ rect = Rect.new(options[:rect])
71
+
72
+ if options[:orientation] == :vertical
73
+ x = rect.x
74
+ y = rect.y
75
+ right = rect.right
76
+ bottom = rect.bottom
77
+
78
+ step = (rect.x + rect.right) / options[:colors].size
79
+ 1.upto(options[:colors].size).each do |nr|
80
+ from = options[:colors]
81
+ to =
82
+
83
+ $window.draw_quad( x, y, options[:from],
84
+ x + step, rect.y, options[:from],
85
+ x + step, rect.bottom, options[:to],
86
+ x, rect.bottom, options[:to],
87
+ options[:zorder], options[:mode]
88
+ )
89
+ end
90
+ else
91
+ $window.draw_quad( rect.x, rect.y, options[:from],
92
+ rect.x, rect.bottom, options[:from],
93
+ rect.right, rect.bottom, options[:to],
94
+ rect.right, rect.y, options[:to],
95
+ options[:zorder], options[:mode]
96
+ )
97
+ end
40
98
  end
99
+
41
100
 
42
101
  #
43
- # Fills a given Rect 'rect' with Color 'color'
102
+ # Fills a given Rect 'rect' with Color 'color', drawing with zorder 'zorder'
44
103
  #
45
- def fill_rect(rect, color)
104
+ def fill_rect(rect, color, zorder = 0)
46
105
  rect = Rect.new(rect) # Make sure it's a rect
47
106
  $window.draw_quad( rect.x, rect.y, color,
48
107
  rect.right, rect.y, color,
49
108
  rect.right, rect.bottom, color,
50
109
  rect.x, rect.bottom, color,
51
- 0, :default)
110
+ zorder, :default)
52
111
  end
53
112
 
54
113
  #
@@ -69,7 +128,8 @@ module Chingu
69
128
  :mode => :default
70
129
  }
71
130
  options = default_options.merge(options)
72
- rect = Rect.new(options[:rect])
131
+ rect = Rect.new(options[:rect])
132
+
73
133
  if options[:orientation] == :vertical
74
134
  $window.draw_quad( rect.x, rect.y, options[:from],
75
135
  rect.right, rect.y, options[:from],
@@ -55,6 +55,22 @@ module Chingu
55
55
  alias << add_layer
56
56
 
57
57
 
58
+ #
59
+ # returns true if any part of the parallax-scroller is inside the window
60
+ #
61
+ def inside_window?
62
+ return true if @repeat
63
+ @layers.each { |layer| return true if layer.inside_window? }
64
+ return false
65
+ end
66
+
67
+ #
68
+ # Returns true if all parallax-layers are outside the window
69
+ #
70
+ def outside_window?
71
+ not inside_window?
72
+ end
73
+
58
74
  #
59
75
  # Parallax#camera_x= works in inverse to Parallax#x (moving the "camera", not the image)
60
76
  #
data/lib/chingu/text.rb CHANGED
@@ -66,7 +66,7 @@ module Chingu
66
66
  super(options)
67
67
 
68
68
  @text = text || options[:text] || "-No text specified-"
69
- @font = options[:font] || @@font || default_font_name()
69
+ @font = options[:font] || @@font || Gosu::default_font_name()
70
70
  @height = @size = options[:height] || options[:size] || @@size || 15
71
71
  @line_spacing = options[:line_spacing] || 1
72
72
  @align = options[:align] || :left
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chingu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.9
4
+ version: 0.5.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ippa
@@ -30,7 +30,7 @@ cert_chain:
30
30
  hxtMlw==
31
31
  -----END CERTIFICATE-----
32
32
 
33
- date: 2009-10-25 01:00:00 +02:00
33
+ date: 2009-11-09 00:00:00 +01:00
34
34
  default_executable:
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
@@ -125,6 +125,7 @@ files:
125
125
  - lib/chingu/game_state.rb
126
126
  - lib/chingu/game_state_manager.rb
127
127
  - lib/chingu/game_states/debug.rb
128
+ - lib/chingu/game_states/edit.rb
128
129
  - lib/chingu/game_states/fade_to.rb
129
130
  - lib/chingu/game_states/pause.rb
130
131
  - lib/chingu/helpers/game_object.rb
metadata.gz.sig CHANGED
Binary file