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 +0 -0
- data/Manifest.txt +1 -0
- data/chingu.gemspec +3 -3
- data/examples/game1.rb +117 -15
- data/lib/chingu.rb +1 -1
- data/lib/chingu/animation.rb +2 -2
- data/lib/chingu/assets.rb +5 -1
- data/lib/chingu/basic_game_object.rb +9 -1
- data/lib/chingu/game_object.rb +4 -1
- data/lib/chingu/game_state_manager.rb +4 -2
- data/lib/chingu/game_states/edit.rb +164 -0
- data/lib/chingu/helpers/game_object.rb +27 -0
- data/lib/chingu/helpers/gfx.rb +71 -11
- data/lib/chingu/parallax.rb +16 -0
- data/lib/chingu/text.rb +1 -1
- metadata +3 -2
- metadata.gz.sig +0 -0
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-
|
|
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
|
-
|
|
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
|
-
#
|
|
106
|
+
# The foremost layer in our parallax scroller is the collidable terrain
|
|
106
107
|
#
|
|
107
108
|
def solid_pixel_at?(x, y)
|
|
108
|
-
|
|
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
|
-
|
|
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
|
-
:
|
|
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
data/lib/chingu/animation.rb
CHANGED
|
@@ -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.
|
|
62
|
+
@frames.last
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
#
|
data/lib/chingu/assets.rb
CHANGED
|
@@ -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
|
#
|
data/lib/chingu/game_object.rb
CHANGED
|
@@ -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
|
data/lib/chingu/helpers/gfx.rb
CHANGED
|
@@ -29,26 +29,85 @@ module Chingu
|
|
|
29
29
|
module GFX
|
|
30
30
|
|
|
31
31
|
#
|
|
32
|
-
# Fills whole window with
|
|
32
|
+
# Fills whole window with specified 'color' and 'zorder'
|
|
33
33
|
#
|
|
34
|
-
def fill(color)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
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],
|
data/lib/chingu/parallax.rb
CHANGED
|
@@ -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-
|
|
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
|