ippa-chingu 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -1
- data/README.rdoc +120 -30
- data/chingu.gemspec +5 -5
- data/examples/example1.rb +7 -1
- data/examples/example2.rb +17 -8
- data/examples/example3.rb +1 -1
- data/examples/example4.rb +74 -26
- data/lib/chingu/assets.rb +8 -0
- data/lib/chingu/fpscounter.rb +21 -1
- data/lib/chingu/game_object.rb +53 -17
- data/lib/chingu/game_state.rb +90 -14
- data/lib/chingu/game_state_manager.rb +75 -19
- data/lib/chingu/helpers.rb +127 -19
- data/lib/chingu/input.rb +4 -4
- data/lib/chingu/parallax.rb +4 -1
- data/lib/chingu/text.rb +16 -6
- data/lib/chingu/window.rb +104 -104
- metadata +3 -3
data/History.txt
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
=== 0.0.3 / 2009-08-14
|
2
|
+
Too much to list. remade inputsystem. gamestates are better. window.rb is cleaner. lots of small bugfixes. Bigger readme.
|
3
|
+
|
1
4
|
=== 0.0.2 / 2009-08-10
|
2
5
|
tons of new stuff and fixes. complete keymap. gamestate system. moreexamples/docs. better game_object.
|
3
6
|
|
4
7
|
=== 0.0.1 / 2009-08-05
|
5
|
-
first release
|
8
|
+
first release
|
data/README.rdoc
CHANGED
@@ -34,17 +34,27 @@ Chingu consists of the following core classes:
|
|
34
34
|
The main window, use it at you use Gosu::Window.
|
35
35
|
|
36
36
|
=== Chingu::GameObject
|
37
|
-
Use for your in game objects,
|
37
|
+
Use for all your in game objects. The player, the enemies, the bullets, the powerups, the loot laying around.
|
38
|
+
It's very reusable and doesn't contain any game-logic (that's up to you!). Only stuff to put it on screen a certain way.
|
39
|
+
It also gives you a couple of bonuses with chingu, as automatic updates/draws and easier input-mapping.
|
38
40
|
Has either Chingu::Window or a Chingu::GameState as "owner".
|
39
41
|
|
40
42
|
=== Chingu::Text
|
41
|
-
Makes use of Gosu::Font more rubyish and powerful
|
43
|
+
Makes use of Gosu::Font more rubyish and powerful.
|
44
|
+
In it's core, another Chingu::GameObject + Gosu::Font.
|
45
|
+
|
46
|
+
=== Chingu::GameStateManager
|
47
|
+
Keeps track of the game states. Implements a stack-based system with push_game_state and pop_game_state.
|
42
48
|
|
43
49
|
=== Chingu::GameState
|
44
|
-
A "standalone game loop" that can be
|
50
|
+
A "standalone game loop" that can be activated and deactivated to control game flow.
|
51
|
+
A game state is very much like a main gosu window. You define update() and draw() in a gamestate.
|
52
|
+
It comes with 2 extras that main window doesn't have. #setup (called when activated) and #finalize (called when deactivated)
|
53
|
+
|
54
|
+
If using game states, the flow of draw/update/button_up/button_down is:
|
55
|
+
Chingu::Window --> Chingu::GameStateManager --> Chingu::GameState.
|
56
|
+
For example, inside game state Menu you call push_game_state(Level). When Level exists, it will go back to Menu.
|
45
57
|
|
46
|
-
=== Chingu::GameStateManager
|
47
|
-
Keeps track of the game states. The flow of draw/update/button_down is Chingu::Window --> Chingu::GameStateManager --> Chingu::GameState.
|
48
58
|
|
49
59
|
== THE BASICS
|
50
60
|
|
@@ -105,10 +115,10 @@ Chingu doesn't change any fundamental concept of Gosu, but it will make the abov
|
|
105
115
|
#
|
106
116
|
class Game < Chingu:Window
|
107
117
|
def initialize
|
108
|
-
super
|
118
|
+
super # This is always needed if you want to take advantage of what chingu offers
|
109
119
|
#
|
110
120
|
# Player will automaticly be updated and drawn since it's a Chingu::GameObject
|
111
|
-
# You'll need your own Game#update/#draw after a while, but just put #super there and Chingu can do its thing
|
121
|
+
# You'll need your own Game#update/#draw after a while, but just put #super there and Chingu can do its thing.
|
112
122
|
#
|
113
123
|
@player = Player.new
|
114
124
|
@player.input = {:left => :move_left, :right => :move_right}
|
@@ -178,6 +188,65 @@ I've chose to base it around Image#draw_rot. So basically all the arguments that
|
|
178
188
|
#
|
179
189
|
@player = Player.new(:draw => false, :update => false)
|
180
190
|
|
191
|
+
=== Input
|
192
|
+
One of the core things I wanted a more natural way of inputhandling.
|
193
|
+
You can define input -> actions on Chingu::Window, Chingu::GameState and Chingu::GameObject.
|
194
|
+
Like this:
|
195
|
+
|
196
|
+
#
|
197
|
+
# When left arrow is pressed, call @player.turn_left ... and so on.
|
198
|
+
#
|
199
|
+
@player.input = { :left => :turn_left, :right => :turn_right, :left => :halt_left, :right => :halt_right }
|
200
|
+
|
201
|
+
|
202
|
+
#
|
203
|
+
# In Gosu the equivalent would be:
|
204
|
+
#
|
205
|
+
def button_down(id)
|
206
|
+
@player.turn_left if id == Button::KbLeft
|
207
|
+
@player.turn_right if id == Button::KbRight
|
208
|
+
end
|
209
|
+
|
210
|
+
def button_up(id)
|
211
|
+
@player.halt_left if id == Button::KbLeft
|
212
|
+
@player.halt_right if id == Button::KbRight
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
Another more complex example:
|
217
|
+
|
218
|
+
#
|
219
|
+
# So what happens here?
|
220
|
+
#
|
221
|
+
# Pressing P would create an game state out of class Pause, cache it and activate it.
|
222
|
+
# Pressing ESC would call Play#close
|
223
|
+
# Holding down LEFT would call Play#move_left on every game iteration
|
224
|
+
# Holding down RIGHT would call Play#move_right on every game iteration
|
225
|
+
# Relasing SPACE would call Play#fire
|
226
|
+
#
|
227
|
+
|
228
|
+
class Play < Chingu::GameState
|
229
|
+
def initialize
|
230
|
+
self.input = { :p => Pause, :escape => :close, :holding_left => :move_left, :holding_right => :move_right, :released_space => :fire }
|
231
|
+
end
|
232
|
+
end
|
233
|
+
class Pause < Chingu::GameState
|
234
|
+
# pause logic here
|
235
|
+
end
|
236
|
+
|
237
|
+
In Gosu the above code would include code in button_up(), button_down() and a check for button_down?() in update().
|
238
|
+
|
239
|
+
Every symbol can be prefixed by either "released_" or "holding_" while no prefix at all defaults to pressed once.
|
240
|
+
So, why not :up_space or :relase_space instead of :released_space?
|
241
|
+
Or :hold_left or :down_left instead of :holding_left?
|
242
|
+
|
243
|
+
:up_space doesn't sound like english, :release_space sounds more like a command then an event.
|
244
|
+
|
245
|
+
:holding_left sounds like something that's happening over a period of time, not a single trigger, which corresponds good to what's happening when using it.
|
246
|
+
|
247
|
+
And with the default :space => :something youd imagine that :something is called once. You press :space once, :something get's executed once.
|
248
|
+
|
249
|
+
|
181
250
|
=== GameState / GameStateManager
|
182
251
|
Chingu incorporates a basic push/pop game state system (as discussed here: http://www.gamedev.net/community/forums/topic.asp?topic_id=477320).
|
183
252
|
|
@@ -186,7 +255,9 @@ Game states is a way of organizing your intros, menus, levels.
|
|
186
255
|
Game states aren't complicated. In Chingu a GameState is a class that behaves mostly like your default Gosu::Window (or in our case Chingu::Window) game loop.
|
187
256
|
|
188
257
|
|
258
|
+
# A simple GameState-example
|
189
259
|
class Intro < Chingu::GameState
|
260
|
+
|
190
261
|
def update
|
191
262
|
# game logic here
|
192
263
|
end
|
@@ -194,44 +265,62 @@ Game states aren't complicated. In Chingu a GameState is a class that behaves mo
|
|
194
265
|
def draw
|
195
266
|
# screen manipulation here
|
196
267
|
end
|
197
|
-
|
198
|
-
|
199
|
-
|
268
|
+
|
269
|
+
# Called when we enter the game state
|
270
|
+
def setup
|
271
|
+
@player.angle = 0 # point player upwards
|
200
272
|
end
|
201
273
|
|
274
|
+
# Called when we leave the current game state
|
202
275
|
def finalize
|
203
|
-
|
276
|
+
push_game_state(Menu) # switch to game state "Menu"
|
204
277
|
end
|
205
|
-
|
206
|
-
# etc etc
|
278
|
+
|
207
279
|
end
|
208
280
|
|
209
281
|
Looks familiar ye?
|
210
|
-
|
282
|
+
You can activate the above game state in 2 ways
|
211
283
|
|
212
284
|
class Game < Chingu::Window
|
213
285
|
def initialize
|
214
|
-
|
286
|
+
#
|
287
|
+
# 1) Create a new Intro-object and activate it (pushing to the top).
|
288
|
+
# This version makes more sense if you want to pass parameters to the gamestate, for example:
|
289
|
+
# push_game_state(Level.new(:level_nr => 10))
|
290
|
+
#
|
291
|
+
push_game_state(Intro.new)
|
292
|
+
|
293
|
+
#
|
294
|
+
# 2) This leaves the actual object-creation to the game state manager.
|
295
|
+
# This results in only 1 object is ever created of class 'Intro'.
|
296
|
+
# The second time 'push_game_state(Intro)' is called, it will re-use the last one.
|
297
|
+
# This means code in Intro#initialize() is only called once, Intro#setup() is called everytime Intro is activated though.
|
298
|
+
#
|
299
|
+
push_game_state(Intro)
|
215
300
|
end
|
216
301
|
end
|
217
302
|
|
218
303
|
A GameState in Chingu is just a class with the following instance methods:
|
219
304
|
|
220
|
-
*
|
305
|
+
* initialize() - called only once with push_game_state(Intro) but everytime with push_game_state(Intro.new)
|
306
|
+
* setup() - called each time the game state becomes active.
|
221
307
|
* button_down(id) - Called when a button is down
|
222
308
|
* button_up(id) - Called when a button is released
|
223
309
|
* update() - just as in your normal game loop, put your game logic here.
|
224
310
|
* draw() - just as in your normal game loop, put your screen manipulation here.
|
225
|
-
* finalize() - called when a game state
|
311
|
+
* finalize() - called when a game state de-activated (for example by pushing a new one on top with push_game_state)
|
226
312
|
|
227
313
|
Chingu::Window automatically creates a @game_state_manager and makes it accessible in our game loop.
|
228
314
|
By default the game loop calls update() / draw() on the the current game state.
|
229
315
|
|
230
|
-
Chingu also has a couple of helpers
|
316
|
+
Chingu also has a couple of helpers-methods for handling the game states:
|
231
317
|
In a main loop or in a game state:
|
232
|
-
*
|
233
|
-
*
|
234
|
-
*
|
318
|
+
* push_game_state(state) - adds a new gamestate on top of the stack, which then becomes the active one
|
319
|
+
* pop_game_state - removes active gamestate and activates the previous one
|
320
|
+
* current_game_state - returns the current game state
|
321
|
+
* previous_game_state - returns the previous game state (useful for pausing and dialog boxes, see example4.rb)
|
322
|
+
* pop_until_game_state(state) - pop game states until given state is found
|
323
|
+
* clear_game_states - removes all game states from stack
|
235
324
|
|
236
325
|
To switch to a certain gamestate with a keypress use Chingus input handler:
|
237
326
|
class Intro < Chingu::GameState
|
@@ -240,15 +329,15 @@ To switch to a certain gamestate with a keypress use Chingus input handler:
|
|
240
329
|
end
|
241
330
|
end
|
242
331
|
|
243
|
-
Or Chingus
|
332
|
+
Or Chingus shortcut:
|
244
333
|
|
245
334
|
class Intro < Chingu::GameState
|
246
335
|
def setup
|
247
|
-
self.input = { :space => Menu } # { :space => Menu.new }
|
336
|
+
self.input = { :space => Menu } # or { :space => Menu.new } if you want to create a new object each time.
|
248
337
|
end
|
249
338
|
end
|
250
339
|
|
251
|
-
|
340
|
+
Chingus inputhandler will detect that Menu is a gamestate-class, create a new instance, cache it and activate it with push_game_state().
|
252
341
|
|
253
342
|
=== Assets / Paths
|
254
343
|
|
@@ -285,12 +374,13 @@ It's not only that the second example is readable by ppl now even familiar with
|
|
285
374
|
|
286
375
|
== TODO:
|
287
376
|
* (done) Complete the input-definitions with all possible inputs (keyboard, gamepad, mouse)!
|
288
|
-
* Complete input-stuff with released-states etc
|
377
|
+
* (done) Complete input-stuff with released-states etc
|
289
378
|
* More gfx effects, for example: fade in/out to a specific color (black makes sense between levels).
|
290
|
-
* Summon good proven community gosu snippets into Chingu
|
379
|
+
* (posted request on forums) Summon good proven community gosu snippets into Chingu
|
291
380
|
* (done) Generate docs @ ippa.github.com- http://rdoc.info/projects/ippa/chingu !
|
292
381
|
* (done) A good scene-manager to manage welcome screens, levels and game flow- GameStateManager / GameState !
|
293
382
|
* More docs
|
383
|
+
* make a playable simple game in examples\ that really depends on game states
|
294
384
|
* (done) Make a gem- first gem made on github
|
295
385
|
* Automate gemgenning rake-task even more
|
296
386
|
* More examples when effects are more complete
|
@@ -298,14 +388,14 @@ It's not only that the second example is readable by ppl now even familiar with
|
|
298
388
|
* class Actor/MovingActor with maybe abit more logic then the basic GameObject. Would ppl find is useful?
|
299
389
|
* Spell check all docs, sloppy spelling turns ppl off.
|
300
390
|
* Tests
|
301
|
-
* Streamline fps / tick code
|
391
|
+
* (done) Streamline fps / tick code
|
302
392
|
* (done) Encapsulate Font.new / draw_rot with a "class Text < GameObject"
|
303
|
-
* Make it possible for ppl to use the parts of Chingu they like
|
393
|
+
* (10% done) Make it possible for ppl to use the parts of Chingu they like
|
304
394
|
* A more robust game state <-> game_object system to connect them together.
|
305
395
|
* Get better at styling rdocs
|
306
|
-
* all �gamestate� ? �game state� ?
|
307
|
-
* FIX example4: :p => Pause.new would Change the "inside_game_state" to Pause and make @player belong to Pause.
|
396
|
+
* (done) all �gamestate� ? �game state� ? it's "game state"
|
308
397
|
* intergrate rubygame_movie_make (maybe after a rename, GameAutomator? GameSequence?
|
398
|
+
* FIX example4: :p => Pause.new would Change the "inside_game_state" to Pause and make @player belong to Pause.
|
309
399
|
|
310
400
|
== WHY?
|
311
401
|
* Plain Gosu is very minimalistic, perfect to build some higher level logic on!
|
data/chingu.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{chingu}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.3.0"
|
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-08-
|
9
|
+
s.date = %q{2009-08-14}
|
10
10
|
s.description = %q{Game framework built on top of the OpenGL accelerated game lib Gosu. It adds simple yet powerfull game states, prettier inputhandling, deploymentsafe asset-handling, a basic re-usable game object and automation of common task.}
|
11
11
|
s.email = ["ippa@rubylicio.us"]
|
12
12
|
s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
|
@@ -24,11 +24,11 @@ Gem::Specification.new do |s|
|
|
24
24
|
s.specification_version = 2
|
25
25
|
|
26
26
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
27
|
-
s.add_development_dependency(%q<hoe>, [">= 2.3.
|
27
|
+
s.add_development_dependency(%q<hoe>, [">= 2.3.3"])
|
28
28
|
else
|
29
|
-
s.add_dependency(%q<hoe>, [">= 2.3.
|
29
|
+
s.add_dependency(%q<hoe>, [">= 2.3.3"])
|
30
30
|
end
|
31
31
|
else
|
32
|
-
s.add_dependency(%q<hoe>, [">= 2.3.
|
32
|
+
s.add_dependency(%q<hoe>, [">= 2.3.3"])
|
33
33
|
end
|
34
34
|
end
|
data/examples/example1.rb
CHANGED
@@ -15,7 +15,13 @@ class Game < Chingu::Window
|
|
15
15
|
def initialize
|
16
16
|
super
|
17
17
|
@player = Player.new(:x => 200, :y => 200, :image => Image["spaceship.png"])
|
18
|
-
@player.input = {:
|
18
|
+
@player.input = { :holding_left => :move_left, :holding_right => :move_right,
|
19
|
+
:holding_up => :move_up, :holding_down => :move_down}
|
20
|
+
end
|
21
|
+
|
22
|
+
def update
|
23
|
+
super
|
24
|
+
self.caption = "FPS: #{self.fps} milliseconds_since_last_tick: #{self.milliseconds_since_last_tick}"
|
19
25
|
end
|
20
26
|
end
|
21
27
|
|
data/examples/example2.rb
CHANGED
@@ -15,7 +15,11 @@ class Game < Chingu::Window
|
|
15
15
|
super
|
16
16
|
|
17
17
|
@player = Player.new(:x => 200, :y => 200, :image => Image["spaceship.png"])
|
18
|
-
@player.input = {:
|
18
|
+
@player.input = { :holding_left => :move_left,
|
19
|
+
:holding_right => :move_right,
|
20
|
+
:holding_up => :move_up,
|
21
|
+
:holding_down => :move_down,
|
22
|
+
:space => :fire}
|
19
23
|
end
|
20
24
|
|
21
25
|
#
|
@@ -43,18 +47,23 @@ class Game < Chingu::Window
|
|
43
47
|
|
44
48
|
end
|
45
49
|
|
50
|
+
#
|
51
|
+
# Our Player
|
52
|
+
#
|
46
53
|
class Player < Chingu::GameObject
|
54
|
+
def initialize(options = {})
|
55
|
+
super
|
56
|
+
@image = Image["spaceship.png"]
|
57
|
+
end
|
58
|
+
|
47
59
|
def move_left; @x -= 1; end
|
48
60
|
def move_right; @x += 1; end
|
49
61
|
def move_up; @y -= 1; end
|
50
|
-
def move_down; @y += 1; end
|
51
|
-
|
62
|
+
def move_down; @y += 1; end
|
63
|
+
|
52
64
|
def fire
|
53
65
|
Bullet.new(:x => @x, :y => @y)
|
54
|
-
end
|
55
|
-
|
56
|
-
def update
|
57
|
-
end
|
66
|
+
end
|
58
67
|
end
|
59
68
|
|
60
69
|
class Bullet < Chingu::GameObject
|
@@ -67,7 +76,7 @@ class Bullet < Chingu::GameObject
|
|
67
76
|
end
|
68
77
|
|
69
78
|
# Move the bullet forward
|
70
|
-
def update
|
79
|
+
def update(time)
|
71
80
|
@y -= 2
|
72
81
|
end
|
73
82
|
|
data/examples/example3.rb
CHANGED
@@ -9,7 +9,7 @@ include Gosu
|
|
9
9
|
class Game < Chingu::Window
|
10
10
|
def initialize
|
11
11
|
super
|
12
|
-
self.input = {:
|
12
|
+
self.input = {:holding_left => :scroll_left, :holding_right => :scroll_right, :escape => :close}
|
13
13
|
|
14
14
|
@parallax = Chingu::Parallax.new(:x => 0, :y => 0, :center_x => 0, :center_y => 0)
|
15
15
|
|
data/examples/example4.rb
CHANGED
@@ -5,7 +5,7 @@ include Gosu
|
|
5
5
|
#
|
6
6
|
# Example demonstrating jumping between 4 different game states.
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# push_game_state, pop_game_state, current_game_state previous_game_state are 4 helper-methods that Chingu mixes in
|
9
9
|
# into Chingu::Window and Chingu::GameState
|
10
10
|
#
|
11
11
|
# Behind the scenes they work against @game_state_manager that's autocreated within Chingu::Window.
|
@@ -19,7 +19,7 @@ include Gosu
|
|
19
19
|
#
|
20
20
|
# 3) @game_state_manager calls draw / update on the current active game state
|
21
21
|
#
|
22
|
-
# 4) Each
|
22
|
+
# 4) Each game state keeps a collection @game_objects which it calls draw / update on.
|
23
23
|
# Any object based on Chingu::GameObject (In this example Player and Text) automatically
|
24
24
|
# gets added to the correct state or or main window.
|
25
25
|
#
|
@@ -29,19 +29,18 @@ include Gosu
|
|
29
29
|
#
|
30
30
|
class Game < Chingu::Window
|
31
31
|
def initialize
|
32
|
-
super
|
33
|
-
|
32
|
+
super
|
33
|
+
|
34
|
+
push_game_state(Intro)
|
34
35
|
|
35
36
|
# Yes you can do crazy things like this :)
|
36
|
-
self.input = { :left_mouse_button => lambda{Chingu::Text.new(:text => "Woff!")}}
|
37
|
+
self.input = { :left_mouse_button => lambda{Chingu::Text.new(:text => "Woff!")}, :esc => :close}
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
40
|
-
#
|
41
|
-
# Our Player
|
42
|
-
#
|
41
|
+
# Our Player
|
43
42
|
class Player < Chingu::GameObject
|
44
|
-
def initialize(options)
|
43
|
+
def initialize(options = {})
|
45
44
|
super
|
46
45
|
@image = Image["spaceship.png"]
|
47
46
|
end
|
@@ -49,16 +48,42 @@ class Player < Chingu::GameObject
|
|
49
48
|
def move_left; @x -= 1; end
|
50
49
|
def move_right; @x += 1; end
|
51
50
|
def move_up; @y -= 1; end
|
52
|
-
def move_down; @y += 1; end
|
51
|
+
def move_down; @y += 1; end
|
52
|
+
|
53
|
+
def fire
|
54
|
+
Bullet.new(:x => @x, :y => @y)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# The bullet the Player fires
|
59
|
+
class Bullet < Chingu::GameObject
|
60
|
+
def initialize(options)
|
61
|
+
super
|
62
|
+
@image = Image["fire_bullet.png"]
|
63
|
+
end
|
64
|
+
|
65
|
+
def update(time)
|
66
|
+
@y -= 2
|
67
|
+
end
|
53
68
|
end
|
54
69
|
|
70
|
+
|
55
71
|
#
|
56
72
|
# GAMESTATE #1 - INTRO
|
57
73
|
#
|
58
74
|
class Intro < Chingu::GameState
|
59
|
-
def
|
60
|
-
|
61
|
-
|
75
|
+
def initialize(options)
|
76
|
+
super
|
77
|
+
@title = Chingu::Text.new(:text=>"Press and release F1", :x=>200, :y=>50, :size=>30)
|
78
|
+
self.input = { :f1 => :pressed, :released_f1 => :released, :f2 => Menu}
|
79
|
+
end
|
80
|
+
|
81
|
+
def pressed
|
82
|
+
@title.text = "F1 pressed (F2 to continue)"
|
83
|
+
end
|
84
|
+
|
85
|
+
def released
|
86
|
+
@title.text = "F1 released (F2 to continue)"
|
62
87
|
end
|
63
88
|
end
|
64
89
|
|
@@ -66,9 +91,10 @@ end
|
|
66
91
|
# GAMESTATE #2 - MENU
|
67
92
|
#
|
68
93
|
class Menu < Chingu::GameState
|
69
|
-
def
|
70
|
-
|
71
|
-
|
94
|
+
def initialize(options)
|
95
|
+
super
|
96
|
+
@title = Chingu::Text.new(:text => "Press 'S' to Start game", :x=>100, :y=>50, :size=>30)
|
97
|
+
self.input = { :s => Level.new(:level => 10) }
|
72
98
|
end
|
73
99
|
end
|
74
100
|
|
@@ -76,34 +102,56 @@ end
|
|
76
102
|
# GAMESTATE #3 - LEVEL (Gameplay, yay)
|
77
103
|
#
|
78
104
|
class Level < Chingu::GameState
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
105
|
+
#
|
106
|
+
# initialize() is called when you create the game state
|
107
|
+
#
|
108
|
+
def initialize(options)
|
109
|
+
super
|
110
|
+
@title = Chingu::Text.new(:text=>"Level #{options[:level].to_s}. P: pause R:restart", :x=>20, :y=>10, :size=>30)
|
111
|
+
@player = Player.new
|
112
|
+
@player.input = { :holding_left => :move_left,
|
113
|
+
:holding_right => :move_right,
|
114
|
+
:holding_up => :move_up,
|
115
|
+
:holding_down => :move_down,
|
116
|
+
:left_ctrl => :fire}
|
83
117
|
|
84
118
|
#
|
85
119
|
# The input-handler understands gamestates. P is pressed --> push_gamegate(Pause)
|
120
|
+
# You can also give it Procs/Lambdas which it will execute when key is pressed.
|
86
121
|
#
|
87
|
-
self.input = {:p => Pause, :
|
88
|
-
end
|
122
|
+
self.input = {:p => Pause, :r => lambda{ current_game_state.setup } }
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# setup() is called each time you switch to the game state (and on creation time).
|
127
|
+
# You can skip setup by switching with push_game_state(:setup => false) or pop_game_state(:setup => false)
|
128
|
+
#
|
129
|
+
# This can be useful if you want to display some kind of box above the gameplay (pause/options/info/... box)
|
130
|
+
#
|
131
|
+
def setup
|
132
|
+
# Place player in a good starting position
|
133
|
+
@player.x = $window.width/2
|
134
|
+
@player.y = $window.height - @player.image.height
|
135
|
+
end
|
89
136
|
end
|
90
137
|
|
91
138
|
#
|
92
139
|
# SPECIAL GAMESTATE - Pause
|
93
140
|
#
|
94
141
|
class Pause < Chingu::GameState
|
95
|
-
def
|
142
|
+
def initialize(options)
|
143
|
+
super
|
96
144
|
@title = Chingu::Text.new(:text=>"PAUSED (press 'u' to un-pause)", :x=>100, :y=>200, :size=>20, :color => Color.new(0xFF00FF00))
|
97
145
|
self.input = { :u => :un_pause }
|
98
146
|
end
|
99
147
|
|
100
148
|
def un_pause
|
101
|
-
|
149
|
+
pop_game_state(:setup => false) # Return the previous game state, dont call setup()
|
102
150
|
end
|
103
151
|
|
104
152
|
def draw
|
105
|
-
|
106
|
-
super
|
153
|
+
previous_game_state.draw # Draw prev game state onto screen (in this case our level)
|
154
|
+
super # Draw game objects in current game state, this includes Chingu::Texts
|
107
155
|
end
|
108
156
|
end
|
109
157
|
|