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 +5 -0
- data/Manifest.txt +34 -0
- data/README.rdoc +329 -0
- data/Rakefile +19 -0
- data/chingu.gemspec +34 -0
- data/examples/example1.rb +30 -0
- data/examples/example2.rb +76 -0
- data/examples/example3.rb +37 -0
- data/examples/example4.rb +110 -0
- data/examples/media/Parallax-scroll-example-layer-0.png +0 -0
- data/examples/media/Parallax-scroll-example-layer-1.png +0 -0
- data/examples/media/Parallax-scroll-example-layer-2.png +0 -0
- data/examples/media/Parallax-scroll-example-layer-3.png +0 -0
- data/examples/media/background1.png +0 -0
- data/examples/media/fire_bullet.png +0 -0
- data/examples/media/spaceship.png +0 -0
- data/examples/media/stickfigure.bmp +0 -0
- data/examples/media/stickfigure.png +0 -0
- data/lib/chingu/animation.rb +109 -0
- data/lib/chingu/assets.rb +50 -0
- data/lib/chingu/chipmunk_object.rb +117 -0
- data/lib/chingu/data_structures.rb +6 -0
- data/lib/chingu/fpscounter.rb +21 -0
- data/lib/chingu/game_object.rb +101 -0
- data/lib/chingu/game_state.rb +39 -0
- data/lib/chingu/game_state_manager.rb +84 -0
- data/lib/chingu/helpers.rb +41 -0
- data/lib/chingu/input.rb +100 -0
- data/lib/chingu/named_resource.rb +254 -0
- data/lib/chingu/parallax.rb +80 -0
- data/lib/chingu/rect.rb +612 -0
- data/lib/chingu/text.rb +46 -0
- data/lib/chingu/window.rb +161 -0
- data/lib/chingu.rb +29 -0
- metadata +99 -0
data/History.txt
ADDED
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
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|