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 +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
|