chingu 0.5.9 → 0.5.9.2

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