rubygame 2.2.0 → 2.3.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.
@@ -0,0 +1,29 @@
1
+ /*
2
+ * Interface to SDL_mixer sound playback and mixing.
3
+ *--
4
+ * Rubygame -- Ruby code and bindings to SDL to facilitate game creation
5
+ * Copyright (C) 2004-2008 John Croisant
6
+ *
7
+ * This library is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU Lesser General Public
9
+ * License as published by the Free Software Foundation; either
10
+ * version 2.1 of the License, or (at your option) any later version.
11
+ *
12
+ * This library is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ * Lesser General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Lesser General Public
18
+ * License along with this library; if not, write to the Free Software
19
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+ *++
21
+ */
22
+
23
+
24
+ #ifndef _RUBYGAME_SOUND_H
25
+ #define _RUBYGAME_SOUND_H
26
+
27
+ extern void Rubygame_Init_Sound();
28
+
29
+ #endif
@@ -1130,6 +1130,10 @@ void Rubygame_Init_Surface()
1130
1130
  rb_define_method(cSurface,"savebmp",rbgm_image_savebmp,1);
1131
1131
  rb_define_method(cSurface,"flip",rbgm_transform_flip,2);
1132
1132
 
1133
+
1134
+ /* Include the Rubygame::NamedResource mixin module. */
1135
+ rg_include_named_resource(cSurface);
1136
+
1133
1137
 
1134
1138
  /* Surface initialization flags */
1135
1139
  rb_define_const(mRubygame,"SWSURFACE",UINT2NUM(SDL_SWSURFACE));
@@ -17,6 +17,8 @@
17
17
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
18
  #++
19
19
 
20
+ module Rubygame
21
+ module Color
20
22
 
21
23
  # A mix-in module defining color arithmetic operations.
22
24
  module ColorBase
@@ -104,3 +106,6 @@ module ColorBase
104
106
  return v
105
107
  end
106
108
  end
109
+
110
+ end
111
+ end
@@ -0,0 +1,254 @@
1
+ #--
2
+ # Rubygame -- Ruby code and bindings to SDL to facilitate game creation
3
+ # Copyright (C) 2004-2008 John Croisant
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ #++
19
+
20
+
21
+ module Rubygame
22
+
23
+ # NamedResource is a mix-in module to implement a globally-available
24
+ # resource table, a @name variable and accessors, and a system for
25
+ # automatically loading resources when they are first needed.
26
+ #
27
+ # This module is used for Rubygame::Music, Rubygame::Sound, and
28
+ # Rubygame::Surface. You can use it in your own classes this way:
29
+ #
30
+ # 1. Do 'include Rubygame::NamedResource' in your class definition.
31
+ #
32
+ # 2. Set MyClass.autoload_dirs to an Array of directories to look
33
+ # for files when autoloading. Tip: use File.join to create
34
+ # paths that work on any operating system.
35
+ #
36
+ # 3. Define #autoload to implement the behavior for your class,
37
+ # or leave it as the default if you don't need autoloading.
38
+ # See the docs for #autoload for more information.
39
+ #
40
+ # Here's an example of how you could use this for a class which
41
+ # loads maps from a file:
42
+ #
43
+ # class Map
44
+ # include Rubygame::NamedResource
45
+ #
46
+ # Map.autoload_dirs = [ File.join("maps","world_1"),
47
+ # File.join("maps","custom") ]
48
+ #
49
+ # def autoload( name )
50
+ # # Searches autoload_dirs for the file
51
+ # path = find_file( name )
52
+ #
53
+ # if( path )
54
+ # return load_map( path )
55
+ # else
56
+ # return nil
57
+ # end
58
+ # end
59
+ #
60
+ # def load_map( path )
61
+ # # Your code to do the real loading, then return
62
+ # # the created instance of Map class.
63
+ # # ...
64
+ # return map_instance
65
+ # end
66
+ # end
67
+ #
68
+ # Here's an example of how you could then use the Map class:
69
+ #
70
+ # map = Map["level_1.map"]
71
+ #
72
+ # if( map )
73
+ # start_playing( map )
74
+ # else
75
+ # raise "Oops! The map file for Level 1 doesn't exist!"
76
+ # end
77
+ #
78
+ module NamedResource
79
+
80
+
81
+ # Adds class methods when the NamedResource module is included
82
+ # in a class. (Here, we are assuming that the NamedResource
83
+ # module was included in a class called MyClass.)
84
+ module NamedResourceClassMethods
85
+
86
+ # An Array of paths to check for files. See #find_file.
87
+ attr_accessor :autoload_dirs
88
+
89
+
90
+ # call-seq:
91
+ # MyClass[ name ] -> instance or nil
92
+ #
93
+ # Retrieves an instance of the class from a per-class resource
94
+ # table (Hash).
95
+ #
96
+ # If no object has been saved under the given name, invoke
97
+ # #autoload to try to load a new instance, store it in the
98
+ # Hash table under this name, and sets the instance's @name
99
+ # to this name.
100
+ #
101
+ def []( name )
102
+ result = @resources[name]
103
+
104
+ if result.nil?
105
+ result = autoload(name)
106
+ if result
107
+ self[name] = result
108
+ result.name = name
109
+ end
110
+ end
111
+
112
+ return result
113
+ end
114
+
115
+
116
+ # call-seq:
117
+ # MyClass[ name ] = instance
118
+ #
119
+ # Stores an instance of the class in a per-class resource table
120
+ # (Hash) for future access. If another object is already stored
121
+ # with this name, the old record is lost.
122
+ #
123
+ # May raise: TypeError, if you try to store anything
124
+ # that is not kind of this class.
125
+ #
126
+ def []=( name, value )
127
+ if( value.kind_of? self )
128
+ @resources[name] = value
129
+ else
130
+ raise TypeError, "#{self}#[]= can only store instances of #{self}"
131
+ end
132
+ end
133
+
134
+ # call-seq:
135
+ # MyClass.autoload( name ) -> instance or nil
136
+ #
137
+ # This method is invoked when a non-existing resource is
138
+ # accessed with #[]. By default, this method simply returns
139
+ # nil, effectively disabling autoloading.
140
+ #
141
+ # You should override this method in your class to provide
142
+ # class-specific loading behavior, or leave it as the default if
143
+ # you don't need autoloading. Your method should return either
144
+ # an instance of the class, or nil.
145
+ #
146
+ # NOTE: The #find_file method is useful for getting the full
147
+ # path to a file which matches the name. That's what it's there
148
+ # for, so you should use it!
149
+ #
150
+ def autoload( name )
151
+ nil
152
+ end
153
+
154
+
155
+ # call-seq:
156
+ # MyClass.basename( path ) -> filename
157
+ #
158
+ # Returns the basename for the path (i.e. the
159
+ # filename without the directory). Same as
160
+ # File.basename
161
+ #
162
+ def basename( path )
163
+ File.basename( path )
164
+ end
165
+
166
+
167
+ # call-seq:
168
+ # MyClass.exist?( path ) -> true or false
169
+ #
170
+ # True if the given path points to a file
171
+ # that exists, otherwise false. Same as
172
+ # File.exist?
173
+ #
174
+ def exist?( path )
175
+ File.exist?(path)
176
+ end
177
+
178
+
179
+ # call-seq:
180
+ # MyClass.find_file( filename ) -> path or nil
181
+ #
182
+ # Checks every directory in @autoload_dirs for
183
+ # a file with the given name, and returns the
184
+ # path (directory and name) for the first match.
185
+ #
186
+ # If no directories have a file with that name,
187
+ # return nil.
188
+ #
189
+ def find_file( filename )
190
+ dir = @autoload_dirs.find { |dir|
191
+ exist?( File.join(dir,filename) )
192
+ }
193
+
194
+ if dir
195
+ return File.join(dir,filename)
196
+ else
197
+ return nil
198
+ end
199
+ end
200
+
201
+ end
202
+
203
+
204
+ # Sets up the class when this module is included.
205
+ # Adds the class methods and defines class instance
206
+ # variables.
207
+ def self.included( object ) # :nodoc:
208
+
209
+ class << object
210
+ include NamedResourceClassMethods
211
+ end
212
+
213
+ object.instance_eval do
214
+ @resources = Hash.new
215
+ @autoload_dirs = []
216
+ end
217
+
218
+ end
219
+
220
+
221
+ # Returns the instance's @name. See also #name=.
222
+ def name
223
+ @name
224
+ end
225
+
226
+ #
227
+ # Sets the instance's @name to the given String, or nil to
228
+ # unset the name. See also #name.
229
+ #
230
+ # NOTE: This does not automatically store the instance in the
231
+ # class resource table by name. Use the #[]= class method to do
232
+ # that.
233
+ #
234
+ # The string is dup'ed and frozen before being stored.
235
+ #
236
+ # May raise: TypeError, if new_name is not a String or nil.
237
+ #
238
+ def name=( new_name )
239
+ if new_name.nil?
240
+ return @name = nil
241
+ end
242
+
243
+ unless new_name.kind_of? String
244
+ raise TypeError, "name must be a String (got #{new_name.class})"
245
+ end
246
+
247
+ @name = new_name.dup
248
+ @name.freeze
249
+ end
250
+
251
+
252
+ end
253
+
254
+ end
data/samples/chimp.rb CHANGED
@@ -24,49 +24,41 @@
24
24
  # Rosetta Stone for a pygame user switching to Rubygame.
25
25
 
26
26
  require "rubygame"
27
+ include Rubygame
27
28
 
28
29
  puts 'Warning, images disabled' unless
29
- ($image_ok = (Rubygame::VERSIONS[:sdl_image] != nil))
30
+ ($image_ok = (VERSIONS[:sdl_image] != nil))
30
31
  puts 'Warning, font disabled' unless
31
- ($font_ok = (Rubygame::VERSIONS[:sdl_ttf] != nil))
32
+ ($font_ok = (VERSIONS[:sdl_ttf] != nil))
32
33
  puts 'Warning, sound disabled' unless
33
- ($sound_ok = (Rubygame::VERSIONS[:sdl_mixer] != nil))
34
-
35
- # Functions to create our resources:
36
- def load_image(name, colorkey=nil)
37
- # Rubygame::Image.load has been replaced with Surface
38
- image = Rubygame::Surface.load_image(name)
39
- if colorkey != nil
40
- if colorkey == -1
41
- colorkey = image.get_at([0,0])
42
- end
43
- image.set_colorkey(colorkey)
44
- end
45
- return image, Rubygame::Rect.new(0,0,*image.size)
46
- end
34
+ ($sound_ok = (VERSIONS[:sdl_mixer] != nil))
35
+
36
+
37
+ # Get the directory this script is in.
38
+ resources_dir = File.dirname(__FILE__)
39
+
40
+ # Set the directories to autoload images and sounds from.
41
+ # See the docs for Rubygame::NamedResource.
42
+ Surface.autoload_dirs = [ resources_dir ]
43
+ Sound.autoload_dirs = [ resources_dir ]
47
44
 
48
- def load_sound(name)
49
- return nil unless $sound_ok
50
- begin
51
- sound = Rubygame::Mixer::Sample.load_audio(name)
52
- return sound
53
- rescue Rubygame::SDLError => e
54
- warn "Cannot load sound #{name}. (#{e})\nContinuing anyway..."
55
- return nil
56
- end
57
- end
58
45
 
59
46
  # Classes for our game objects:
60
47
 
61
48
  # The fist object, which follows the mouse and punches on mouseclick
62
49
  class Fist
63
50
  # It's a sprite (an image with location data).
64
- include Rubygame::Sprites::Sprite
51
+ include Sprites::Sprite
65
52
 
66
53
  # Create and set up a new Fist object
67
54
  def initialize
68
55
  super # initialize sprite
69
- @image, @rect = load_image('fist.bmp', -1)
56
+
57
+ # Autoload the image and set its colorkey
58
+ @image = Surface['fist.bmp']
59
+ @image.set_colorkey( @image.get_at([0,0]) )
60
+
61
+ @rect = @image.make_rect()
70
62
  @punching = false # whether the fist is punching
71
63
  @mpos = [0,0] # mouse curson position
72
64
  end
@@ -78,7 +70,7 @@ class Fist
78
70
  # in @mpos for later use in Fist#update().
79
71
  def tell(ev)
80
72
  case ev
81
- when Rubygame::MouseMotionEvent
73
+ when MouseMotionEvent
82
74
  # mouse cursor moved, remember its last location for #update()
83
75
  @mpos = ev.pos
84
76
  end
@@ -110,17 +102,22 @@ end
110
102
  # A chimpanzee which moves across the screen and spins when punched.
111
103
  class Chimp
112
104
  # It's a sprite (an image with location data).
113
- include Rubygame::Sprites::Sprite
105
+ include Sprites::Sprite
114
106
 
115
107
  # Create and set up a new Chimp object
116
108
  def initialize
117
109
  super # initialize sprite
118
- @original, @rect = load_image('chimp.bmp', -1)
110
+
111
+ # Autoload the image and set its colorkey
112
+ @original = Surface['chimp.bmp']
113
+ @original.set_colorkey( @original.get_at([0,0]) )
119
114
  @image = @original # store original image during rotation
115
+
116
+ @rect = @image.make_rect()
120
117
  @rect.topleft = 10,10
118
+
121
119
  # @area is the area of the screen, which the chimp will walk across
122
- @area = Rubygame::Rect.new(0,0,
123
- *Rubygame::Screen.get_surface().size())
120
+ @area = Rubygame::Screen.get_surface().make_rect()
124
121
  @xvel = 9 # called self.move in the pygame example
125
122
 
126
123
  # In python, the integer 0 signifies false, while in ruby it does not.
@@ -168,7 +165,7 @@ class Chimp
168
165
  # and is just as efficient as incremental rotations.
169
166
  @image = @original.rotozoom(@dizzy,1,true)
170
167
  end
171
- @rect = Rubygame::Rect.new(0,0,*@image.size)
168
+ @rect = image.make_rect()
172
169
  @rect.center = center # re-center
173
170
  end
174
171
 
@@ -193,24 +190,14 @@ def main
193
190
 
194
191
  # Initialize Everything
195
192
  Rubygame.init()
196
- screen = Rubygame::Screen.set_mode([468, 60])
193
+ screen = Screen.new([468, 60])
197
194
  screen.title = 'Monkey Fever'
198
195
  screen.show_cursor = false;
199
196
  # In Rubygame, you make an EventQueue object; pygame just uses functions
200
- queue = Rubygame::EventQueue.new()
201
-
202
- begin
203
- # Not in the pygame version - for Rubygame, we need to
204
- # open the audio device. The default values are fine.
205
- Rubygame::Mixer::open_audio
206
- rescue Rubygame::SDLError => e
207
- warn e
208
- $sound_ok = false
209
- warn "Continuing without sound..."
210
- end
211
-
197
+ queue = EventQueue.new()
198
+
212
199
  # Create The Background
213
- background = Rubygame::Surface.new(screen.size)
200
+ background = Surface.new(screen.size)
214
201
  background.fill([250,250,250])
215
202
 
216
203
  # Put Text On The Background, Centered
@@ -223,9 +210,9 @@ def main
223
210
  #
224
211
  # 25 is more or less the actual font size in the pygame example,
225
212
  # based on scaling factor (0.6875) pygame applies to its default font.
226
- font = Rubygame::TTF.new("FreeSans.ttf",25)
213
+ font = TTF.new("FreeSans.ttf",25)
227
214
  text = font.render("Pummel The Chimp, And Win $$$", true, [10,10,10])
228
- textpos = Rubygame::Rect.new(0,0,*text.size)
215
+ textpos = text.make_rect()
229
216
  textpos.centerx = background.width/2
230
217
  # ATTENTION: Note that the "actor" is reversed from the pygame usage.
231
218
  # In pygame, a surface "pulls" another surface's data onto itself.
@@ -243,13 +230,16 @@ def main
243
230
  # This also differs from pygame. Rather than pass the desired framerate
244
231
  # when you call clock.tick, you set the framerate for the clock, either
245
232
  # when you create it, or afterwards with the desired_fps accessors.
246
- clock = Rubygame::Clock.new { |clock| clock.target_framerate = 30 }
233
+ clock = Clock.new { |clock| clock.target_framerate = 30 }
247
234
 
248
- whiff_sound = load_sound('whiff.wav')
249
- punch_sound = load_sound('punch.wav')
235
+ # Autoload the sound effects
236
+ whiff_sound = Sound['whiff.wav']
237
+ punch_sound = Sound['punch.wav']
238
+
250
239
  chimp = Chimp.new()
251
240
  fist = Fist.new()
252
- allsprites = Rubygame::Sprites::Group.new()
241
+
242
+ allsprites = Sprites::Group.new()
253
243
  allsprites.push(chimp, fist)
254
244
 
255
245
  #Main Loop
@@ -264,25 +254,25 @@ def main
264
254
  # Unlike in pygame, each event is detected by class, not
265
255
  # by an integer type identifier.
266
256
  case(event)
267
- when Rubygame::QuitEvent
257
+ when QuitEvent
268
258
  return # break out of the main function
269
- when Rubygame::KeyDownEvent
259
+ when KeyDownEvent
270
260
  case event.key
271
- when Rubygame::K_ESCAPE
261
+ when K_ESCAPE
272
262
  return # break out of the main function
273
263
  end
274
- when Rubygame::MouseMotionEvent
264
+ when MouseMotionEvent
275
265
  fist.tell(event)
276
- when Rubygame::MouseDownEvent
266
+ when MouseDownEvent
277
267
  if fist.punch(chimp)
278
268
  chimp.punched()
279
269
  # Only try to play the sound if it isn't nil
280
- Rubygame::Mixer::play(punch_sound,-1,0) if punch_sound
270
+ punch_sound.play if punch_sound
281
271
  else
282
272
  # Only try to play the sound if it isn't nil
283
- Rubygame::Mixer::play(whiff_sound,-1,0) if whiff_sound
273
+ whiff_sound.play if whiff_sound
284
274
  end
285
- when Rubygame::MouseUpEvent
275
+ when MouseUpEvent
286
276
  fist.unpunch()
287
277
  end
288
278
  end # end event handling
@@ -302,7 +292,6 @@ def main
302
292
  ensure
303
293
  # This ensures that we properly close and clean up everything at the end
304
294
  # of the game.
305
- Rubygame::Mixer.close_audio()
306
295
  Rubygame.quit()
307
296
  end # end main function
308
297
 
data/samples/demo_gl.rb CHANGED
File without changes
File without changes
@@ -2,10 +2,10 @@
2
2
 
3
3
  require 'rubygame'
4
4
 
5
+ include Rubygame
5
6
  Rubygame.init()
6
7
 
7
8
  def test_music()
8
- mix = Rubygame::Mixer
9
9
 
10
10
  # Use the lines below to get rid of artsd and contact ALSA directly on Linux.
11
11
  # ARTSD happens to be buggy on my old, old linux distro.
@@ -16,9 +16,7 @@ def test_music()
16
16
  end
17
17
  end
18
18
 
19
- mix.open_audio
20
- puts "Using audio driver:" + mix.driver_name
21
- music = mix::Music
19
+ puts "Using audio driver:" + Rubygame.audio_driver
22
20
 
23
21
  if ARGV[0]
24
22
  file = ARGV[0]
@@ -27,10 +25,15 @@ def test_music()
27
25
  puts "If you want, you could give a filename as an argument to this script."
28
26
  end
29
27
 
30
- mus = music.load_audio(file);
28
+ Music.autoload_dirs = [ File.dirname(__FILE__) ]
29
+ mus = Music[file];
30
+
31
+ unless mus
32
+ puts "ERROR: Couldn't find audio file '#{file}'."
33
+ end
31
34
 
32
35
  puts "Testing fading in over 3 seconds, repeating forever."
33
- mus.fade_in(3, -1);
36
+ mus.play( :fade_in => 3, :repeats => -1 );
34
37
  puts('ERROR: Music not fading in') unless mus.fading?(:in)
35
38
  sleep 3
36
39
 
@@ -52,7 +55,7 @@ def test_music()
52
55
  sleep 1
53
56
 
54
57
  puts "Resuming."
55
- mus.resume
58
+ mus.unpause
56
59
  puts "ERROR: Music not resumed" unless mus.playing?
57
60
 
58
61
  puts "Playing for 2 seconds."
@@ -66,7 +69,6 @@ def test_music()
66
69
  # Test playing of music to the end
67
70
 
68
71
  puts "ERROR: Music not ended" if mus.playing?
69
- mix.close_audio
70
72
  end
71
73
 
72
74
  music_thread = Thread.new do test_music() end
@@ -28,10 +28,21 @@ unless ($gfx_ok = (VERSIONS[:sdl_gfx] != nil))
28
28
  raise "SDL_gfx is not available. Bailing out."
29
29
  end
30
30
 
31
+
32
+ # Set up autoloading for Surfaces. Surfaces will be loaded automatically
33
+ # the first time you use Surface["filename"]. Check out the docs for
34
+ # Rubygame::NamedResource for more info about that.
35
+ #
36
+ Surface.autoload_dirs = [ File.dirname(__FILE__) ]
37
+
38
+
31
39
  class Panda
32
40
  include Sprites::Sprite
33
- @@pandapic = Surface.load_image("panda.png")
41
+
42
+ # Autoload the "panda.png" image and set its colorkey
43
+ @@pandapic = Surface["panda.png"]
34
44
  @@pandapic.set_colorkey(@@pandapic.get_at(0,0))
45
+
35
46
  attr_accessor :vx, :vy, :speed
36
47
  def initialize(x,y)
37
48
  super()
@@ -173,11 +184,12 @@ background.draw_ellipse_a([200,150],[30,25], :beige )
173
184
 
174
185
  # Let's make some labels
175
186
  require "rubygame/sfont"
176
- sfont = SFont.new("term16.png")
187
+ sfont = SFont.new( Surface["term16.png"] )
177
188
  sfont.render("Arrow keys move the spinning panda!").blit(background,[10,10])
178
189
 
179
190
  TTF.setup()
180
- ttfont = TTF.new("FreeSans.ttf",20)
191
+ ttfont_path = File.join(File.dirname(__FILE__),"FreeSans.ttf")
192
+ ttfont = TTF.new( ttfont_path, 20 )
181
193
  ttfont.render("This is some TTF text!",true,[250,250,250]).blit(background,[20,200])
182
194
 
183
195
 
File without changes
data/samples/demo_ttf.rb CHANGED
File without changes
data/samples/demo_utf8.rb CHANGED
File without changes