ippa-chingu 0.2.0

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/History.txt ADDED
@@ -0,0 +1,5 @@
1
+ === 0.0.2 / 2009-08-10
2
+ tons of new stuff and fixes. complete keymap. gamestate system. moreexamples/docs. better game_object.
3
+
4
+ === 0.0.1 / 2009-08-05
5
+ first release
data/Manifest.txt ADDED
@@ -0,0 +1,34 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ chingu.gemspec
6
+ examples/example1.rb
7
+ examples/example2.rb
8
+ examples/example3.rb
9
+ examples/example4.rb
10
+ examples/media/Parallax-scroll-example-layer-0.png
11
+ examples/media/Parallax-scroll-example-layer-1.png
12
+ examples/media/Parallax-scroll-example-layer-2.png
13
+ examples/media/Parallax-scroll-example-layer-3.png
14
+ examples/media/background1.png
15
+ examples/media/fire_bullet.png
16
+ examples/media/spaceship.png
17
+ examples/media/stickfigure.bmp
18
+ examples/media/stickfigure.png
19
+ lib/chingu.rb
20
+ lib/chingu/animation.rb
21
+ lib/chingu/assets.rb
22
+ lib/chingu/chipmunk_object.rb
23
+ lib/chingu/data_structures.rb
24
+ lib/chingu/fpscounter.rb
25
+ lib/chingu/game_object.rb
26
+ lib/chingu/game_state.rb
27
+ lib/chingu/game_state_manager.rb
28
+ lib/chingu/helpers.rb
29
+ lib/chingu/input.rb
30
+ lib/chingu/named_resource.rb
31
+ lib/chingu/parallax.rb
32
+ lib/chingu/rect.rb
33
+ lib/chingu/text.rb
34
+ lib/chingu/window.rb
data/README.rdoc ADDED
@@ -0,0 +1,329 @@
1
+ = CHINGU
2
+ http://github.com/ippa/chingu/tree/master
3
+
4
+ DOCUMENTATION: http://rdoc.info/projects/ippa/chingu
5
+
6
+ This is an early preview, a lot of functionality is still missing!
7
+ It's also in a state of flux while I decide on core-naming etc.
8
+
9
+ == INSTALL
10
+ gem sources -a http://gems.github.com
11
+ sudo gem install ippa-chingu
12
+
13
+
14
+ == DESCRIPTION
15
+ Game framework built on top of the OpenGL accelerated game lib Gosu.
16
+ It adds simple yet powerfull game states, prettier inputhandling, deploymentsafe asset-handling, a basic re-usable game object and automation of common task.
17
+
18
+
19
+ == THE STORY
20
+ The last years I've dabbled around a lot with game development.
21
+ I've developed games in both Rubygame and Gosu. I've looked at gamebox.
22
+ Rubygame is a very capable framework with a lot of functionality (collision detection, very good event system etc). Gosu is way more minimalistic but also faster with OpenGL -acceleration. Gosu isn't likely to get much more complex since it does what it should do very well and fast.
23
+
24
+ After 10+ game prototypes and some finished smaller games I started to see patterns each time I started a new game. Making classes with x/y/image/other-parameters that I called update/draw on in the main loop. This became the basic Chingu::GameObject which encapsulates Gosus "Image.draw_rot" and enables automatic updating/drawing.
25
+
26
+ There was always a huge big chunk of checking keyboard-events in the main loop.
27
+ Borrowing ideas from Rubygame this has now become @player.keyboard(:left => :move_left, :space => :fire ... etc.
28
+
29
+
30
+ == OVERVIEW
31
+ Chingu consists of the following core classes:
32
+
33
+ === Chingu::Window
34
+ The main window, use it at you use Gosu::Window.
35
+
36
+ === Chingu::GameObject
37
+ Use for your in game objects, got everything to put them on the screen.
38
+ Has either Chingu::Window or a Chingu::GameState as "owner".
39
+
40
+ === Chingu::Text
41
+ Makes use of Gosu::Font more rubyish and powerful
42
+
43
+ === Chingu::GameState
44
+ A "standalone game loop" that can be switched on/off to control game flow.
45
+
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
+
49
+ == THE BASICS
50
+
51
+ === Chingu::Window
52
+ With Gosu the main window inherits from Gosu::Window. In Chingu we use Chingu::Window. It's a basic Gosu::Window with extra cheese on top of it. keyboard handling, automatic update/draw calls to all gameobjects, fps counting etc.
53
+
54
+ You're probably familiar with this very common Gosu pattern:
55
+
56
+ ROOT_PATH = File.dirname(File.expand_path(__FILE__))
57
+ class Game < Gosu::Window
58
+ def initialize
59
+ @player = Player.new
60
+ end
61
+
62
+ def update
63
+ if button_down? Button::KbLeft
64
+ @player.left
65
+ elsif button_down? Button::KbRight
66
+ @player.right
67
+ end
68
+
69
+ @player.update
70
+ end
71
+
72
+ def draw
73
+ @player.draw
74
+ end
75
+ end
76
+
77
+ class Player
78
+ attr_accessor :x,:y,:image
79
+ def initialize(options)
80
+ @x = options[:x]
81
+ @y = options[:y]
82
+ @image = Image.new(File.join(ROOT_PATH, "media", "player.png"))
83
+ end
84
+
85
+ def move_left
86
+ @x -= 1
87
+ end
88
+
89
+ def move_right
90
+ @x += 1
91
+ end
92
+
93
+ def draw
94
+ @image.draw(@x,@y,100)
95
+ end
96
+ end
97
+
98
+ Game.new.show # Start the Game update/draw loop!
99
+
100
+
101
+ Chingu doesn't change any fundamental concept of Gosu, but it will make the above code cleaner:
102
+
103
+ #
104
+ # We use Chingu::Window instead of Gosu::Window
105
+ #
106
+ class Game < Chingu:Window
107
+ def initialize
108
+ super # This is always needed
109
+ #
110
+ # 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!
112
+ #
113
+ @player = Player.new
114
+ @player.input = {:left => :move_left, :right => :move_right}
115
+ end
116
+ end
117
+
118
+ #
119
+ # If we create classes from Chingu::GameObject we get stuff for free.
120
+ # The accessors: image,x,y,zorder,angle,factor_x,factor_y,center_x,center_y,mode,update,draw
121
+ # You might recognize those from #draw_rot - http://www.libgosu.org/rdoc/classes/Gosu/Image.html#M000023
122
+ # And in it's core, that's what Chingu::GameObject is, an encapsulation of draw_rot with some extra cheese.
123
+ # For example, we get automatic calls to draw/update with Chingu::GameObject, which usually is what you want.
124
+ # You could stop this by doing: @player = Player.new(:draw => false, :update => false)
125
+ #
126
+ class Player < Chingu::GameObject
127
+ def initialize(options)
128
+ super(options.merge(:image => Image["player.png"])
129
+ end
130
+
131
+ def move_left
132
+ @x -= 1
133
+ end
134
+
135
+ def move_right
136
+ @x += 1
137
+ end
138
+ end
139
+
140
+ Game.new.show # Start the Game update/draw loop!
141
+
142
+ Roughly 50 lines became 26 more powerful lines. (you can do @player.angle = 100 for example)
143
+
144
+ If you've worked with Gosu for a while you're probably tired of passing around the window-parameter.
145
+ Chingu solves this (as has many other developers) with a global variable $window. Yes, globals are bad, but in this case it kinda makes sense. It's used under the hood in various places.
146
+
147
+ === Chingu::GameObject
148
+ This is our basic "game unit"-class, meaning most in game objects (players, enemies, bullets etc) should be inherited from Chingu::GameObject. The basic ideas behind it are:
149
+
150
+ * Encapsulate only the very common basics that Most in game objects need
151
+ * Keep naming close to Gosu, but add smart convenient methods / shortcuts and a more rubyish feeling
152
+ * No game logic allowed in GameObject, since that's not likely to be useful for others.
153
+
154
+ I've chose to base it around Image#draw_rot. So basically all the arguments that you pass to draw_rot can be passed to GameObject#new when creating a new object, an example using almost all arguments would be:
155
+
156
+ #
157
+ # You probably recognize the arguments from http://www.libgosu.org/rdoc/classes/Gosu/Image.html#M000023
158
+ #
159
+ @player = Player.new(:image => Image["player.png"], :x=>100, :y=>100, :zorder=>100, :angle=>45, :factor_x=>10, :factor_y=>10, :center_x=>0, :center_y=>0)
160
+
161
+ #
162
+ # A shortcut for the above line would be
163
+ #
164
+ @player = Player.new(:image => Image["player.png"], :x=>100, :y=>100, :zorder=>100, :angle=>45, :factor=>10, :center=>0)
165
+
166
+ #
167
+ # I've tried doing sensible defaults:
168
+ # x/y = [middle of the screen] for super quick display where it should be easy in sight)
169
+ # angle = 0 (no angle by default)
170
+ # center_x/center_y = 0.5 (basically the center of the image will be drawn at x/y)
171
+ # factor_x/factor_y = 1 (no zoom by default)
172
+ #
173
+ @player = Player.new
174
+
175
+ #
176
+ # By default Chingu::Window calls update & draw on all GameObjects in it's own update/draw.
177
+ # If this is not what you want, use :draw and :update
178
+ #
179
+ @player = Player.new(:draw => false, :update => false)
180
+
181
+ === GameState / GameStateManager
182
+ Chingu incorporates a basic push/pop game state system (as discussed here: http://www.gamedev.net/community/forums/topic.asp?topic_id=477320).
183
+
184
+ Game states is a way of organizing your intros, menus, levels.
185
+
186
+ 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
+
188
+
189
+ class Intro < Chingu::GameState
190
+ def update
191
+ # game logic here
192
+ end
193
+
194
+ def draw
195
+ # screen manipulation here
196
+ end
197
+
198
+ def button_down(id)
199
+ # called when a button is pressed
200
+ end
201
+
202
+ def finalize
203
+ push_gamestate(Menu.new) # Called when Intro dies for whatever reason.
204
+ end
205
+
206
+ # etc etc
207
+ end
208
+
209
+ Looks familiar ye?
210
+ Active that game state/game loop in your main window (which is always the spider in the net).
211
+
212
+ class Game < Chingu::Window
213
+ def initialize
214
+ push_gamestate(Intro.new)
215
+ end
216
+ end
217
+
218
+ A GameState in Chingu is just a class with the following instance methods:
219
+
220
+ * setup() - called when game state becomes active (switch_gamestate(gamestate) for example)
221
+ * button_down(id) - Called when a button is down
222
+ * button_up(id) - Called when a button is released
223
+ * update() - just as in your normal game loop, put your game logic here.
224
+ * draw() - just as in your normal game loop, put your screen manipulation here.
225
+ * finalize() - called when a game state is finished
226
+
227
+ Chingu::Window automatically creates a @game_state_manager and makes it accessible in our game loop.
228
+ By default the game loop calls update() / draw() on the the current game state.
229
+
230
+ Chingu also has a couple of helpers to easy change between game states.
231
+ In a main loop or in a game state:
232
+ * push_gamestate(state) - adds a new gamestate, which then becomes the active one
233
+ * pop_gamestate - removes active gamestate and activates the previous one
234
+ * switch_gamestate(state) - pop all gamestates until given state is found
235
+
236
+ To switch to a certain gamestate with a keypress use Chingus input handler:
237
+ class Intro < Chingu::GameState
238
+ def setup
239
+ self.input = { :space => lambda{push_gamestate(Menu.new)} }
240
+ end
241
+ end
242
+
243
+ Or Chingus pretty shortcut:
244
+
245
+ class Intro < Chingu::GameState
246
+ def setup
247
+ self.input = { :space => Menu } # { :space => Menu.new } works as well.
248
+ end
249
+ end
250
+
251
+ Chingu will detect that Menu is a gamestate-class and call push_gamestate on it when space is pressed inside Intro.
252
+
253
+ === Assets / Paths
254
+
255
+ You might wonder why this is nessesary in the straight Gosu example:
256
+ ROOT_PATH = File.dirname(File.expand_path(__FILE__))
257
+ @image = Image.new(File.join(ROOT_PATH, "media", "player.png"))
258
+
259
+ It enables you to start your game from any directory and it will still find your assets (pictures, samples, fonts etc..) correctly.
260
+ For a local development version this might not be important, you're likely to start the game from the games root-dir.
261
+ But as soon as you try to deploy (for example to windows with OCRA - http://github.com/larsch/ocra/tree/master) you'll run into trouble of you dont do it like that.
262
+
263
+ Chingu solves this problem behind the scenes for the most common assets. The 2 lines above can be replaced with:
264
+ Image["player.png"]
265
+
266
+ You also have Sound["player.png"]
267
+
268
+ Tiles and fonts are trickier since they require extra parameters so you'll have to do those the ordinary way.
269
+ You'll get $window.root (equivalent to ROOT_PATH above) for free though which points to the dir containing the game.
270
+
271
+ === Text
272
+ Text is a class to give the use of Gosu::Font more rubyish feel and fit it better into Chingu.
273
+
274
+ # Pure Gosu
275
+ @font = Gosu::Font.new($window, "verdana", 30)
276
+ @font.draw("A Text", 200, 50, 55, 2.0)
277
+
278
+ # Chingu
279
+ @text = Chingu::Text.new(:text => "A Text", :x => 200, :y => 50, :zorder => 55, :factor_x => 2.0)
280
+ @text.draw
281
+
282
+ @text.draw is usually not needed as Text is a GameObject and therefore autodrawn.
283
+ It's not only that the second example is readable by ppl now even familiar with Gosu, @text comes with a number of changeable properties, x,y,zorder,angle,factor_x,color,mode etc. Set a new x or angle or color and it will instantly update on screen.
284
+
285
+
286
+ == TODO:
287
+ * (done) Complete the input-definitions with all possible inputs (keyboard, gamepad, mouse)!
288
+ * Complete input-stuff with released-states etc
289
+ * 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
291
+ * (done) Generate docs @ ippa.github.com- http://rdoc.info/projects/ippa/chingu !
292
+ * (done) A good scene-manager to manage welcome screens, levels and game flow- GameStateManager / GameState !
293
+ * More docs
294
+ * (done) Make a gem- first gem made on github
295
+ * Automate gemgenning rake-task even more
296
+ * More examples when effects are more complete
297
+ * class ChipmunkObject
298
+ * class Actor/MovingActor with maybe abit more logic then the basic GameObject. Would ppl find is useful?
299
+ * Spell check all docs, sloppy spelling turns ppl off.
300
+ * Tests
301
+ * Streamline fps / tick code
302
+ * (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
304
+ * A more robust game state <-> game_object system to connect them together.
305
+ * 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.
308
+ * intergrate rubygame_movie_make (maybe after a rename, GameAutomator? GameSequence?
309
+
310
+ == WHY?
311
+ * Plain Gosu is very minimalistic, perfect to build some higher level logic on!
312
+ * Deployment and asset handling should be simple
313
+ * Managing game states/scenes (intros, menus, levels etc) should be simple
314
+ * There are patterns in game development
315
+
316
+ == OPINIONS
317
+ * Less code is usually better
318
+ * Hash arguments FTW. And it becomes even better in 1.9.
319
+ * Don't separate too much from Gosus core-naming
320
+
321
+ == CREDITS:
322
+ Jacius of Rubygame (For doing cool stuff that's well documented as re-usable). So far rect.rb and named_resource.rb is taken from Rubygame.
323
+
324
+ jlnr,philymore,shawn24 for constructive feedback
325
+
326
+
327
+ == REQUIREMENTS:
328
+ * Gosu latest version
329
+ * Ruby 1.8 (Has not been verified with 1.9 yet)
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+ require File.dirname(__FILE__) + '/lib/chingu'
4
+
5
+ include Chingu
6
+
7
+ Hoe.plugin :git
8
+ Hoe.spec "chingu" do
9
+ developer "ippa", "ippa@rubylicio.us"
10
+ self.readme_file = 'README.rdoc'
11
+ self.rubyforge_name = "chingu"
12
+ self.version = Chingu::VERSION
13
+ end
14
+
15
+ desc "Build a working gemspec"
16
+ task :gemspec do
17
+ system "rake git:manifest"
18
+ system "rake debug_gem | grep -v \"(in \" > chingu.gemspec"
19
+ end
data/chingu.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{chingu}
5
+ s.version = "0.2.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["ippa"]
9
+ s.date = %q{2009-08-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
+ s.email = ["ippa@rubylicio.us"]
12
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
13
+ s.files = ["History.txt", "Manifest.txt", "README.rdoc", "Rakefile", "chingu.gemspec", "examples/example1.rb", "examples/example2.rb", "examples/example3.rb", "examples/example4.rb", "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/fire_bullet.png", "examples/media/spaceship.png", "examples/media/stickfigure.bmp", "examples/media/stickfigure.png", "lib/chingu.rb", "lib/chingu/animation.rb", "lib/chingu/assets.rb", "lib/chingu/chipmunk_object.rb", "lib/chingu/data_structures.rb", "lib/chingu/fpscounter.rb", "lib/chingu/game_object.rb", "lib/chingu/game_state.rb", "lib/chingu/game_state_manager.rb", "lib/chingu/helpers.rb", "lib/chingu/input.rb", "lib/chingu/named_resource.rb", "lib/chingu/parallax.rb", "lib/chingu/rect.rb", "lib/chingu/text.rb", "lib/chingu/window.rb"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/ippa/chingu/tree/master}
16
+ s.rdoc_options = ["--main", "README.rdoc"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{chingu}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{Game framework built on top of the OpenGL accelerated game lib Gosu}
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 2
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_development_dependency(%q<hoe>, [">= 2.3.2"])
28
+ else
29
+ s.add_dependency(%q<hoe>, [">= 2.3.2"])
30
+ end
31
+ else
32
+ s.add_dependency(%q<hoe>, [">= 2.3.2"])
33
+ end
34
+ end
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require '../lib/chingu.rb'
3
+ include Gosu
4
+
5
+ #
6
+ # A minimalistic Chingu example.
7
+ # Chingu::Window provides #update and #draw which calls corresponding methods for all objects based on Chingu::Actors
8
+ #
9
+ # Image["picture.png"] is a deploymentsafe shortcut to Gosu's Image.new and supports multiple locations for "picture.png"
10
+ # By default current dir, media\ and gfx\ is searched. To add own directories:
11
+ #
12
+ # Image.autoload_dirs << File.join(self.root, "data", "my_image_dir")
13
+ #
14
+ class Game < Chingu::Window
15
+ def initialize
16
+ super
17
+ @player = Player.new(:x => 200, :y => 200, :image => Image["spaceship.png"])
18
+ @player.input = {:left => :move_left, :right => :move_right, :up => :move_up, :down => :move_down}
19
+ end
20
+ end
21
+
22
+ class Player < Chingu::GameObject
23
+ def move_left; @x -= 1; end
24
+ def move_right; @x += 1; end
25
+ def move_up; @y -= 1; end
26
+ def move_down; @y += 1; end
27
+ end
28
+
29
+
30
+ Game.new.show
@@ -0,0 +1,76 @@
1
+ require 'rubygems'
2
+ require '../lib/chingu.rb'
3
+ include Gosu
4
+
5
+ #
6
+ # A little more complicated example where we do our own #update and #draw code.
7
+ # We also add another Actor - a bullet fired with space.
8
+ #
9
+ class Game < Chingu::Window
10
+ def initialize
11
+ #
12
+ # See http://www.libgosu.org/rdoc/classes/Gosu/Window.html#M000034 for options
13
+ # By default Chingu does 640 x 480 non-fullscreen.
14
+ #
15
+ super
16
+
17
+ @player = Player.new(:x => 200, :y => 200, :image => Image["spaceship.png"])
18
+ @player.input = {:left => :move_left, :right => :move_right, :up => :move_up, :down => :move_down, :space => :fire}
19
+ end
20
+
21
+ #
22
+ # If we want to add extra graphics drawn just define your own draw.
23
+ # Be sure to call #super for enabling Chingus autodrawing of Actors.
24
+ # Putting #super before or after the background-draw-call really doesn't matter since Gosu work with "zorder".
25
+ #
26
+ def draw
27
+ # Raw Gosu Image.draw(x,y,zorder)-call
28
+ Image["background1.png"].draw(0, 0, 0)
29
+ super
30
+ end
31
+
32
+ #
33
+ # Gosus place for gamelogic is #update in the mainwindow
34
+ #
35
+ # A #super call here would call #update on all Chingu::Actors and check their inputs, and call the specified method.
36
+ #
37
+ def update
38
+
39
+ ### Your own gamelogic here
40
+
41
+ super
42
+ end
43
+
44
+ end
45
+
46
+ class Player < Chingu::GameObject
47
+ def move_left; @x -= 1; end
48
+ def move_right; @x += 1; end
49
+ def move_up; @y -= 1; end
50
+ def move_down; @y += 1; end
51
+
52
+ def fire
53
+ Bullet.new(:x => @x, :y => @y)
54
+ end
55
+
56
+ def update
57
+ end
58
+ end
59
+
60
+ class Bullet < Chingu::GameObject
61
+ #
62
+ # If we need our own initialize, just call super and Chingu does it's thing.
63
+ # Here we merge in an extra argument, specifying the bullet-image.
64
+ #
65
+ def initialize(options)
66
+ super(options.merge(:image => Image["fire_bullet.png"]))
67
+ end
68
+
69
+ # Move the bullet forward
70
+ def update
71
+ @y -= 2
72
+ end
73
+
74
+ end
75
+
76
+ Game.new.show
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ require '../lib/chingu.rb'
3
+ include Gosu
4
+
5
+ #
6
+ # Parallax-example
7
+ # Images from http://en.wikipedia.org/wiki/Parallax_scrolling
8
+ #
9
+ class Game < Chingu::Window
10
+ def initialize
11
+ super
12
+ self.input = {:left => :scroll_left, :right => :scroll_right, :escape => :close}
13
+
14
+ @parallax = Chingu::Parallax.new(:x => 0, :y => 0, :center_x => 0, :center_y => 0)
15
+
16
+ #
17
+ # If no :zorder is given to @parallax.add_background it defaults to first added -> lowest zorder
18
+ # Everywhere the :image argument is used, theese 2 values are the Same:
19
+ # 1) Image["foo.png"] 2) "foo.png"
20
+ #
21
+ # TODO: scrolling to left borks outm, fix. + get rid of center_x / center_y args in a clean way.
22
+ @parallax.add_background(:image => "Parallax-scroll-example-layer-0.png", :damping => 100, :center_x => 0, :center_y => 0)
23
+ @parallax.add_background(:image => "Parallax-scroll-example-layer-1.png", :damping => 10, :center_x => 0, :center_y => 0)
24
+ @parallax.add_background(:image => "Parallax-scroll-example-layer-2.png", :damping => 5, :center_x => 0, :center_y => 0)
25
+ @parallax.add_background(:image => "Parallax-scroll-example-layer-3.png", :damping => 1, :center_x => 0, :center_y => 0)
26
+ end
27
+
28
+ def scroll_left
29
+ @parallax.x -= 2
30
+ end
31
+
32
+ def scroll_right
33
+ @parallax.x += 2
34
+ end
35
+ end
36
+
37
+ Game.new.show
@@ -0,0 +1,110 @@
1
+ require 'rubygems'
2
+ require '../lib/chingu.rb'
3
+ include Gosu
4
+
5
+ #
6
+ # Example demonstrating jumping between 4 different game states.
7
+ #
8
+ # push_gamestate, pop_gamestate and previous_gamestate are 3 helpers that Chingu mixes in
9
+ # into Chingu::Window and Chingu::GameState
10
+ #
11
+ # Behind the scenes they work against @game_state_manager that's autocreated within Chingu::Window.
12
+ #
13
+ # Execution in example4 flows like this:
14
+ #
15
+ # 1) Core Gosu calls instancemethods draw / update in the class based on Gosu::Window
16
+ # In this example 'Game' since "Game < Chingu::Window" and "Chingu::Window < Gosu::Window"
17
+ #
18
+ # 2) In its turn Game (Chingu::Window) calls @game_state_manager.draw / update
19
+ #
20
+ # 3) @game_state_manager calls draw / update on the current active game state
21
+ #
22
+ # 4) Each gamestate keeps a collection @game_objects which it calls draw / update on.
23
+ # Any object based on Chingu::GameObject (In this example Player and Text) automatically
24
+ # gets added to the correct state or or main window.
25
+ #
26
+
27
+ #
28
+ # Our standard Chingu::Window that makes all the magic happen.
29
+ #
30
+ class Game < Chingu::Window
31
+ def initialize
32
+ super
33
+ push_gamestate(Intro)
34
+
35
+ # Yes you can do crazy things like this :)
36
+ self.input = { :left_mouse_button => lambda{Chingu::Text.new(:text => "Woff!")}}
37
+ end
38
+ end
39
+
40
+ #
41
+ # Our Player
42
+ #
43
+ class Player < Chingu::GameObject
44
+ def initialize(options)
45
+ super
46
+ @image = Image["spaceship.png"]
47
+ end
48
+
49
+ def move_left; @x -= 1; end
50
+ def move_right; @x += 1; end
51
+ def move_up; @y -= 1; end
52
+ def move_down; @y += 1; end
53
+ end
54
+
55
+ #
56
+ # GAMESTATE #1 - INTRO
57
+ #
58
+ class Intro < Chingu::GameState
59
+ def setup
60
+ @title = Chingu::Text.new(:text=>"Intro (press space)", :x=>200, :y=>50, :size=>30)
61
+ self.input = { :space => Menu, :escape => :close }
62
+ end
63
+ end
64
+
65
+ #
66
+ # GAMESTATE #2 - MENU
67
+ #
68
+ class Menu < Chingu::GameState
69
+ def setup
70
+ @title = Chingu::Text.new(:text => "GameState Menu (press 'm')", :x => 200, :y => 50, :size=>30)
71
+ self.input = { :m => Level.new(:level => 10) }
72
+ end
73
+ end
74
+
75
+ #
76
+ # GAMESTATE #3 - LEVEL (Gameplay, yay)
77
+ #
78
+ class Level < Chingu::GameState
79
+ def setup
80
+ @title = Chingu::Text.new(:text=>"Level #{options[:level].to_s}. Pause with 'P'", :x=>200, :y=>10, :size => 30)
81
+ @player = Player.new(:x => 200, :y => 200)
82
+ @player.input = {:left => :move_left, :right => :move_right, :up => :move_up, :down => :move_down, :left_ctrl => :fire}
83
+
84
+ #
85
+ # The input-handler understands gamestates. P is pressed --> push_gamegate(Pause)
86
+ #
87
+ self.input = {:p => Pause, :escape => :close}
88
+ end
89
+ end
90
+
91
+ #
92
+ # SPECIAL GAMESTATE - Pause
93
+ #
94
+ class Pause < Chingu::GameState
95
+ def setup
96
+ @title = Chingu::Text.new(:text=>"PAUSED (press 'u' to un-pause)", :x=>100, :y=>200, :size=>20, :color => Color.new(0xFF00FF00))
97
+ self.input = { :u => :un_pause }
98
+ end
99
+
100
+ def un_pause
101
+ pop_gamestate # Return the previous gamestate
102
+ end
103
+
104
+ def draw
105
+ previous_gamestate.draw # Draw prev gamestate onto screen
106
+ super # Draw game objects in current game state, this includes Chingu::Texts
107
+ end
108
+ end
109
+
110
+ Game.new.show