rubygame 2.2.0-mswin32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/CREDITS +60 -0
  2. data/LICENSE +504 -0
  3. data/NEWS +201 -0
  4. data/README +139 -0
  5. data/ROADMAP +43 -0
  6. data/Rakefile +409 -0
  7. data/doc/extended_readme.rdoc +49 -0
  8. data/doc/getting_started.rdoc +47 -0
  9. data/doc/macosx_install.rdoc +70 -0
  10. data/doc/windows_install.rdoc +127 -0
  11. data/ext/rubygame/MANIFEST +25 -0
  12. data/ext/rubygame/rubygame_core.so +0 -0
  13. data/ext/rubygame/rubygame_event.c +644 -0
  14. data/ext/rubygame/rubygame_event.h +48 -0
  15. data/ext/rubygame/rubygame_event.obj +0 -0
  16. data/ext/rubygame/rubygame_gfx.c +942 -0
  17. data/ext/rubygame/rubygame_gfx.h +101 -0
  18. data/ext/rubygame/rubygame_gfx.obj +0 -0
  19. data/ext/rubygame/rubygame_gfx.so +0 -0
  20. data/ext/rubygame/rubygame_gl.c +154 -0
  21. data/ext/rubygame/rubygame_gl.h +32 -0
  22. data/ext/rubygame/rubygame_gl.obj +0 -0
  23. data/ext/rubygame/rubygame_image.c +108 -0
  24. data/ext/rubygame/rubygame_image.h +41 -0
  25. data/ext/rubygame/rubygame_image.obj +0 -0
  26. data/ext/rubygame/rubygame_image.so +0 -0
  27. data/ext/rubygame/rubygame_joystick.c +247 -0
  28. data/ext/rubygame/rubygame_joystick.h +41 -0
  29. data/ext/rubygame/rubygame_joystick.obj +0 -0
  30. data/ext/rubygame/rubygame_main.c +155 -0
  31. data/ext/rubygame/rubygame_main.h +33 -0
  32. data/ext/rubygame/rubygame_main.obj +0 -0
  33. data/ext/rubygame/rubygame_mixer.c +764 -0
  34. data/ext/rubygame/rubygame_mixer.h +62 -0
  35. data/ext/rubygame/rubygame_mixer.obj +0 -0
  36. data/ext/rubygame/rubygame_mixer.so +0 -0
  37. data/ext/rubygame/rubygame_screen.c +448 -0
  38. data/ext/rubygame/rubygame_screen.h +43 -0
  39. data/ext/rubygame/rubygame_screen.obj +0 -0
  40. data/ext/rubygame/rubygame_shared.c +209 -0
  41. data/ext/rubygame/rubygame_shared.h +60 -0
  42. data/ext/rubygame/rubygame_shared.obj +0 -0
  43. data/ext/rubygame/rubygame_surface.c +1147 -0
  44. data/ext/rubygame/rubygame_surface.h +62 -0
  45. data/ext/rubygame/rubygame_surface.obj +0 -0
  46. data/ext/rubygame/rubygame_time.c +183 -0
  47. data/ext/rubygame/rubygame_time.h +32 -0
  48. data/ext/rubygame/rubygame_time.obj +0 -0
  49. data/ext/rubygame/rubygame_ttf.c +599 -0
  50. data/ext/rubygame/rubygame_ttf.h +69 -0
  51. data/ext/rubygame/rubygame_ttf.obj +0 -0
  52. data/ext/rubygame/rubygame_ttf.so +0 -0
  53. data/lib/rubygame.rb +41 -0
  54. data/lib/rubygame/MANIFEST +12 -0
  55. data/lib/rubygame/clock.rb +128 -0
  56. data/lib/rubygame/color.rb +79 -0
  57. data/lib/rubygame/color/models/base.rb +106 -0
  58. data/lib/rubygame/color/models/hsl.rb +153 -0
  59. data/lib/rubygame/color/models/hsv.rb +149 -0
  60. data/lib/rubygame/color/models/rgb.rb +78 -0
  61. data/lib/rubygame/color/palettes/css.rb +49 -0
  62. data/lib/rubygame/color/palettes/palette.rb +100 -0
  63. data/lib/rubygame/color/palettes/x11.rb +177 -0
  64. data/lib/rubygame/constants.rb +238 -0
  65. data/lib/rubygame/event.rb +313 -0
  66. data/lib/rubygame/ftor.rb +370 -0
  67. data/lib/rubygame/hotspot.rb +265 -0
  68. data/lib/rubygame/keyconstants.rb +237 -0
  69. data/lib/rubygame/mediabag.rb +94 -0
  70. data/lib/rubygame/queue.rb +288 -0
  71. data/lib/rubygame/rect.rb +612 -0
  72. data/lib/rubygame/sfont.rb +223 -0
  73. data/lib/rubygame/sprite.rb +511 -0
  74. data/samples/FreeSans.ttf +0 -0
  75. data/samples/GPL.txt +340 -0
  76. data/samples/README +40 -0
  77. data/samples/chimp.bmp +0 -0
  78. data/samples/chimp.rb +313 -0
  79. data/samples/demo_gl.rb +151 -0
  80. data/samples/demo_gl_tex.rb +197 -0
  81. data/samples/demo_music.rb +75 -0
  82. data/samples/demo_rubygame.rb +284 -0
  83. data/samples/demo_sfont.rb +52 -0
  84. data/samples/demo_ttf.rb +193 -0
  85. data/samples/demo_utf8.rb +53 -0
  86. data/samples/fist.bmp +0 -0
  87. data/samples/load_and_blit.rb +22 -0
  88. data/samples/panda.png +0 -0
  89. data/samples/punch.wav +0 -0
  90. data/samples/ruby.png +0 -0
  91. data/samples/song.ogg +0 -0
  92. data/samples/term16.png +0 -0
  93. data/samples/whiff.wav +0 -0
  94. metadata +152 -0
@@ -0,0 +1,237 @@
1
+ # :enddoc:
2
+ module Rubygame
3
+ ALL_KEYS = {\
4
+ K_BACKSPACE => ["\b", "backspace"],\
5
+ K_TAB => ["\t", "tab"],\
6
+ K_CLEAR => [nil, "clear"],\
7
+ K_RETURN => ["\n", "return", "enter"],\
8
+ K_PAUSE => [nil, "pause"],\
9
+ K_ESCAPE => ["^[", "escape"],\
10
+ K_SPACE => [" ", "space"],\
11
+ K_EXCLAIM => ["!", "exclamation_mark", "exclaim"],\
12
+ K_QUOTEDBL => ["\"", "double_quote"],\
13
+ K_HASH => ["#", "hash", "pound", "bang"],\
14
+ K_DOLLAR => ["$", "dollar"],\
15
+ K_AMPERSAND => ["&", "ampersand", "and"],\
16
+ K_QUOTE => ["'", "quote"],\
17
+ K_LEFTPAREN => ["(", "left_parenthesis", "lparen"],\
18
+ K_RIGHTPAREN => [")", "right_parenthesis","rparen"],\
19
+ K_ASTERISK => ["*", "asterisk"],\
20
+ K_PLUS => ["+", "plus"],\
21
+ K_COMMA => [",", "comma"],\
22
+ K_MINUS => ["-", "minus"],\
23
+ K_PERIOD => [".", "period"],\
24
+ K_SLASH => ["/", "slash"],\
25
+ K_0 => ["0", "numberline_0"],\
26
+ K_1 => ["1", "numberline_1"],\
27
+ K_2 => ["2", "numberline_2"],\
28
+ K_3 => ["3", "numberline_3"],\
29
+ K_4 => ["4", "numberline_4"],\
30
+ K_5 => ["5", "numberline_5"],\
31
+ K_6 => ["6", "numberline_6"],\
32
+ K_7 => ["7", "numberline_7"],\
33
+ K_8 => ["8", "numberline_8"],\
34
+ K_9 => ["9", "numberline_9"],\
35
+ K_COLON => [":", "colon"],\
36
+ K_SEMICOLON => [";", "semicolon"],\
37
+ K_LESS => ["<", "less_than"],\
38
+ K_EQUALS => ["=", "equals"],\
39
+ K_GREATER => [">", "greater_than"],\
40
+ K_QUESTION => ["?", "question_mark", "question"],\
41
+ K_AT => ["@", "at"],\
42
+ K_LEFTBRACKET => ["[", "left_bracket", "lbracket"],\
43
+ K_BACKSLASH => ["\\", "backslash"],\
44
+ K_RIGHTBRACKET => ["]", "right_bracket", "rbracket"],\
45
+ K_CARET => ["^", "caret"],\
46
+ K_UNDERSCORE => ["_", "underscore"],\
47
+ K_BACKQUOTE => ["`", "backquote", "grave"],\
48
+ K_A => ["a"],\
49
+ K_B => ["b"],\
50
+ K_C => ["c"],\
51
+ K_D => ["d"],\
52
+ K_E => ["e"],\
53
+ K_F => ["f"],\
54
+ K_G => ["g"],\
55
+ K_H => ["h"],\
56
+ K_I => ["i"],\
57
+ K_J => ["j"],\
58
+ K_K => ["k"],\
59
+ K_L => ["l"],\
60
+ K_M => ["m"],\
61
+ K_N => ["n"],\
62
+ K_O => ["o"],\
63
+ K_P => ["p"],\
64
+ K_Q => ["q"],\
65
+ K_R => ["r"],\
66
+ K_S => ["s"],\
67
+ K_T => ["t"],\
68
+ K_U => ["u"],\
69
+ K_V => ["v"],\
70
+ K_W => ["w"],\
71
+ K_X => ["x"],\
72
+ K_Y => ["y"],\
73
+ K_Z => ["z"],\
74
+ K_DELETE => [nil, "delete", "del"],\
75
+ K_KP0 => ["0", "kp0", "keypad_0"],\
76
+ K_KP1 => ["1", "kp1", "keypad_1"],\
77
+ K_KP2 => ["2", "kp2", "keypad_2"],\
78
+ K_KP3 => ["3", "kp3", "keypad_3"],\
79
+ K_KP4 => ["4", "kp4", "keypad_4"],\
80
+ K_KP5 => ["5", "kp5", "keypad_5"],\
81
+ K_KP6 => ["6", "kp6", "keypad_6"],\
82
+ K_KP7 => ["7", "kp7", "keypad_7"],\
83
+ K_KP8 => ["8", "kp8", "keypad_8"],\
84
+ K_KP9 => ["9", "kp9", "keypad_9"],\
85
+ K_KP_PERIOD => [".", "period", "keypad_period"],\
86
+ K_KP_DIVIDE => ["/", "divide", "keypad_divide"],\
87
+ K_KP_MULTIPLY => ["*", "multiply", "keypad_multiply"],\
88
+ K_KP_MINUS => ["-", "minus", "keypad_minus"],\
89
+ K_KP_PLUS => ["+", "plus", "keypad_plus"],\
90
+ K_KP_ENTER => ["\n", "enter", "keypad_enter"],\
91
+ K_KP_EQUALS => ["=", "equals", "keypad_equals"],\
92
+ K_UP => [nil, "up"],\
93
+ K_DOWN => [nil, "down"],\
94
+ K_RIGHT => [nil, "right"],\
95
+ K_LEFT => [nil, "left"],\
96
+ K_INSERT => [nil, "insert", "ins"],\
97
+ K_HOME => [nil, "home"],\
98
+ K_END => [nil, "end"],\
99
+ K_PAGEUP => [nil, "page_up", "pgup"],\
100
+ K_PAGEDOWN => [nil, "page_down", "pgdn"],\
101
+ K_F1 => [nil, "f1", "function_1"],\
102
+ K_F2 => [nil, "f2", "function_2"],\
103
+ K_F3 => [nil, "f3", "function_3"],\
104
+ K_F4 => [nil, "f4", "function_4"],\
105
+ K_F5 => [nil, "f5", "function_5"],\
106
+ K_F6 => [nil, "f6", "function_6"],\
107
+ K_F7 => [nil, "f7", "function_7"],\
108
+ K_F8 => [nil, "f8", "function_8"],\
109
+ K_F9 => [nil, "f9", "function_9"],\
110
+ K_F10 => [nil, "f10", "function_10"],\
111
+ K_F11 => [nil, "f11", "function_11"],\
112
+ K_F12 => [nil, "f12", "function_12"],\
113
+ K_F13 => [nil, "f13", "function_13"],\
114
+ K_F14 => [nil, "f14", "function_14"],\
115
+ K_F15 => [nil, "f15", "function_15"],\
116
+ K_NUMLOCK => [nil, "numlock"],\
117
+ K_CAPSLOCK => [nil, "capslock", "caplock"],\
118
+ K_SCROLLOCK => [nil, "scroll_lock", "scrollock", "scrolllock"],\
119
+ K_LSHIFT => [nil, "left_shift", "lshift"],\
120
+ K_RSHIFT => [nil, "right_shift", "rshift"],\
121
+ K_LCTRL => [nil, "left_control", "lctrl"],\
122
+ K_RCTRL => [nil, "right_control", "rctrl"],\
123
+ K_LALT => [nil, "left_alt", "lalt"],\
124
+ K_RALT => [nil, "right_alt", "ralt"],\
125
+ K_LMETA => [nil, "left_meta", "lmeta"],\
126
+ K_RMETA => [nil, "right_meta", "rmeta"],\
127
+ K_LSUPER => [nil, "left_super", "lsuper"],\
128
+ K_RSUPER => [nil, "right_super", "rsuper"],\
129
+ K_MODE => [nil, "mode"],\
130
+ K_HELP => [nil, "help"],\
131
+ K_PRINT => [nil, "print_screen","prt_scr","print"],\
132
+ K_SYSREQ => [nil, "sysrq", "sysreq", "system_request"],\
133
+ K_BREAK => [nil, "break"],\
134
+ K_MENU => [nil, "menu"],\
135
+ K_POWER => [nil, "power"],\
136
+ # I have no idea how to get a Euro symbol here!
137
+ K_EURO => ["\u20ac", "euro"],\
138
+ # just K_WORLD_0 to K_WORLD_95 after this
139
+ K_WORLD_0 => [nil, "world_0"],\
140
+ K_WORLD_1 => [nil, "world_1"],\
141
+ K_WORLD_2 => [nil, "world_2"],\
142
+ K_WORLD_3 => [nil, "world_3"],\
143
+ K_WORLD_4 => [nil, "world_4"],\
144
+ K_WORLD_5 => [nil, "world_5"],\
145
+ K_WORLD_6 => [nil, "world_6"],\
146
+ K_WORLD_7 => [nil, "world_7"],\
147
+ K_WORLD_8 => [nil, "world_8"],\
148
+ K_WORLD_9 => [nil, "world_9"],\
149
+ K_WORLD_10 => [nil, "world_10"],\
150
+ K_WORLD_11 => [nil, "world_11"],\
151
+ K_WORLD_12 => [nil, "world_12"],\
152
+ K_WORLD_13 => [nil, "world_13"],\
153
+ K_WORLD_14 => [nil, "world_14"],\
154
+ K_WORLD_15 => [nil, "world_15"],\
155
+ K_WORLD_16 => [nil, "world_16"],\
156
+ K_WORLD_17 => [nil, "world_17"],\
157
+ K_WORLD_18 => [nil, "world_18"],\
158
+ K_WORLD_19 => [nil, "world_19"],\
159
+ K_WORLD_20 => [nil, "world_20"],\
160
+ K_WORLD_21 => [nil, "world_21"],\
161
+ K_WORLD_22 => [nil, "world_22"],\
162
+ K_WORLD_23 => [nil, "world_23"],\
163
+ K_WORLD_24 => [nil, "world_24"],\
164
+ K_WORLD_25 => [nil, "world_25"],\
165
+ K_WORLD_26 => [nil, "world_26"],\
166
+ K_WORLD_27 => [nil, "world_27"],\
167
+ K_WORLD_28 => [nil, "world_28"],\
168
+ K_WORLD_29 => [nil, "world_29"],\
169
+ K_WORLD_30 => [nil, "world_30"],\
170
+ K_WORLD_31 => [nil, "world_31"],\
171
+ K_WORLD_32 => [nil, "world_32"],\
172
+ K_WORLD_33 => [nil, "world_33"],\
173
+ K_WORLD_34 => [nil, "world_34"],\
174
+ K_WORLD_35 => [nil, "world_35"],\
175
+ K_WORLD_36 => [nil, "world_36"],\
176
+ K_WORLD_37 => [nil, "world_37"],\
177
+ K_WORLD_38 => [nil, "world_38"],\
178
+ K_WORLD_39 => [nil, "world_39"],\
179
+ K_WORLD_40 => [nil, "world_40"],\
180
+ K_WORLD_41 => [nil, "world_41"],\
181
+ K_WORLD_41 => [nil, "world_41"],\
182
+ K_WORLD_42 => [nil, "world_42"],\
183
+ K_WORLD_43 => [nil, "world_43"],\
184
+ K_WORLD_44 => [nil, "world_44"],\
185
+ K_WORLD_45 => [nil, "world_45"],\
186
+ K_WORLD_46 => [nil, "world_46"],\
187
+ K_WORLD_47 => [nil, "world_47"],\
188
+ K_WORLD_48 => [nil, "world_48"],\
189
+ K_WORLD_49 => [nil, "world_49"],\
190
+ K_WORLD_50 => [nil, "world_50"],\
191
+ K_WORLD_51 => [nil, "world_51"],\
192
+ K_WORLD_52 => [nil, "world_52"],\
193
+ K_WORLD_53 => [nil, "world_53"],\
194
+ K_WORLD_54 => [nil, "world_54"],\
195
+ K_WORLD_55 => [nil, "world_55"],\
196
+ K_WORLD_56 => [nil, "world_56"],\
197
+ K_WORLD_57 => [nil, "world_57"],\
198
+ K_WORLD_58 => [nil, "world_58"],\
199
+ K_WORLD_59 => [nil, "world_59"],\
200
+ K_WORLD_60 => [nil, "world_60"],\
201
+ K_WORLD_61 => [nil, "world_61"],\
202
+ K_WORLD_62 => [nil, "world_62"],\
203
+ K_WORLD_63 => [nil, "world_63"],\
204
+ K_WORLD_64 => [nil, "world_64"],\
205
+ K_WORLD_65 => [nil, "world_65"],\
206
+ K_WORLD_66 => [nil, "world_66"],\
207
+ K_WORLD_67 => [nil, "world_67"],\
208
+ K_WORLD_68 => [nil, "world_68"],\
209
+ K_WORLD_69 => [nil, "world_69"],\
210
+ K_WORLD_70 => [nil, "world_70"],\
211
+ K_WORLD_71 => [nil, "world_71"],\
212
+ K_WORLD_72 => [nil, "world_72"],\
213
+ K_WORLD_73 => [nil, "world_73"],\
214
+ K_WORLD_74 => [nil, "world_74"],\
215
+ K_WORLD_75 => [nil, "world_75"],\
216
+ K_WORLD_76 => [nil, "world_76"],\
217
+ K_WORLD_77 => [nil, "world_77"],\
218
+ K_WORLD_78 => [nil, "world_78"],\
219
+ K_WORLD_79 => [nil, "world_79"],\
220
+ K_WORLD_80 => [nil, "world_80"],\
221
+ K_WORLD_81 => [nil, "world_81"],\
222
+ K_WORLD_82 => [nil, "world_82"],\
223
+ K_WORLD_83 => [nil, "world_83"],\
224
+ K_WORLD_84 => [nil, "world_84"],\
225
+ K_WORLD_85 => [nil, "world_85"],\
226
+ K_WORLD_86 => [nil, "world_86"],\
227
+ K_WORLD_87 => [nil, "world_87"],\
228
+ K_WORLD_88 => [nil, "world_88"],\
229
+ K_WORLD_89 => [nil, "world_89"],\
230
+ K_WORLD_90 => [nil, "world_90"],\
231
+ K_WORLD_91 => [nil, "world_91"],\
232
+ K_WORLD_92 => [nil, "world_92"],\
233
+ K_WORLD_93 => [nil, "world_93"],\
234
+ K_WORLD_94 => [nil, "world_94"],\
235
+ K_WORLD_95 => [nil, "world_95"],\
236
+ }
237
+ end
@@ -0,0 +1,94 @@
1
+ #--
2
+ # Rubygame -- Ruby code and bindings to SDL to facilitate game creation
3
+ # Copyright (C) 2004-2007 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
+ require "rubygame"
21
+
22
+ module Rubygame
23
+
24
+ # *NOTE*: you must require 'rubygame/mediabag' manually to gain access to
25
+ # Rubygame::MediaBag. It is not imported with Rubygame by default!
26
+ #
27
+ # A Hash-like class which will load and retain media files (images and
28
+ # sounds), so that the file can be loaded once, but used many times.
29
+ #
30
+ # The first time a file is requested with the #[] method,that file will be
31
+ # loaded into memory. All subsequent requests for the same file will return
32
+ # a reference to the already-loaded version. Ideally, objects should not
33
+ # have to know whether or not the image has been loaded or not.
34
+ class MediaBag
35
+ @@image_ext = %W{bmp gif jpg lbm pcx png pnm ppm pgm pbm tga tif xcf xpm}
36
+ @@sound_ext = %W{wav}
37
+
38
+ def initialize()
39
+ @media = Hash.new
40
+ end
41
+
42
+ # Return a reference to the stored value for key.
43
+ # If there is no value for key, automatically attempt to load key
44
+ # as a filename (guessing the file type based on its extension)
45
+ #
46
+ def [](key)
47
+ @media[key] or load(key)
48
+ rescue Rubygame::SDLError
49
+ nil
50
+ end
51
+
52
+ # Load the file, but only if it has not been previously loaded.
53
+ def load(filename)
54
+ @media[filename] or store( filename, load_file(filename) )
55
+ end
56
+
57
+ # Store value as key, but only if there is no previous value.
58
+ def store(key,value)
59
+ @media[key] ||= value
60
+ end
61
+
62
+ # Forcibly (re)load the file, replacing the previous version in memory
63
+ # (if any).
64
+ def force_load(filename)
65
+ force_store( filename, load_file(filename) )
66
+ end
67
+
68
+ # Forcibly store value as key, replacing the previous value (if any).
69
+ def force_store(key,value)
70
+ @media[key] = value
71
+ end
72
+
73
+ def load_file(filename)
74
+ case File::extname(filename).downcase[1..-1]
75
+ when *(@@image_ext)
76
+ return load_image(filename)
77
+ when *(@@sound_ext)
78
+ return load_sound(filename)
79
+ else
80
+ raise(ArgumentError,"Unrecognized file extension `%s': %s"%
81
+ [File::extname(filename), filename])
82
+ end
83
+ end
84
+
85
+ def load_image(filename)
86
+ return Rubygame::Surface.load_image(filename)
87
+ end
88
+
89
+ def load_sound(filename)
90
+ return Rubygame::Mixer::Sample.load_audio(filename)
91
+ end
92
+ end
93
+
94
+ end
@@ -0,0 +1,288 @@
1
+ #--
2
+ # Rubygame -- Ruby code and bindings to SDL to facilitate game creation
3
+ # Copyright (C) 2004-2007 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
+ require "rubygame/event"
21
+
22
+ module Rubygame
23
+
24
+ # EventQueue provides a simple way to manage SDL's events, allowing the
25
+ # application to detect keyboard presses, mouse movements and clicks,
26
+ # joystick movement, etc. You can also post custom events to the
27
+ # EventQueue to help manage the game state.
28
+ #
29
+ # This class replaces the old Rubygame::Queue class, which is no longer
30
+ # available. While EventQueue class serves the same purpose as the old
31
+ # class, they are somewhat different in behavior. Please note that while
32
+ # the old class was a Singleton, this class is not; you may have as many
33
+ # separate instances of EventQueue as you wish (although it is strongly
34
+ # recommended that only one be used to #fetch_sdl_events).
35
+ #
36
+ # For basic usage, create a #new EventQueue with autofetch, then call the
37
+ # #each method once per game loop, passing a block which handles events.
38
+ # See the sample applications for examples of this.
39
+ #
40
+ # If you wish to ignore all events of a certain class, append those classes
41
+ # the instance variable @ignore (accessors are provided). You can ignore as
42
+ # many classes of events as you want, but make sure you don't ignore ALL
43
+ # event classes, or the user won't be able to control the game!
44
+ #
45
+ # If the program has to pause and wait for an event (for example, if the
46
+ # player must press a button to begin playing), you might find the #wait
47
+ # method to be convenient.
48
+ #
49
+ # For reference, the full list of SDL events is:
50
+ # - Event (base class, not used by itself)
51
+ # - ActiveEvent
52
+ # - JoyAxisEvent
53
+ # - JoyBallEvent
54
+ # - JoyDownEvent
55
+ # - JoyHatEvent
56
+ # - JoyUpEvent
57
+ # - KeyDownEvent
58
+ # - KeyUpEvent
59
+ # - MouseDownEvent
60
+ # - MouseMotionEvent
61
+ # - MouseUpEvent
62
+ # - QuitEvent
63
+ # - ResizeEvent
64
+ #
65
+ class EventQueue < Array
66
+ # Array of classes to be ignored by #push.
67
+ attr_accessor :ignore
68
+
69
+ # Whether to fetch SDL events automatically when #each and #wait are used.
70
+ # Enabled by default.
71
+ attr_accessor :autofetch
72
+
73
+ # Create a new EventQueue.
74
+ def initialize()
75
+ @autofetch = true
76
+ @ignore = []
77
+ yield self if block_given?
78
+ end
79
+
80
+ # Append events to the EventQueue.
81
+ # Silently ignores events whose class is in @ignore.
82
+ def push(*events)
83
+ events = events.flatten.delete_if {|e| @ignore.include?(e.class)}
84
+ events.each do |e|
85
+ super( e )
86
+ end
87
+ end
88
+
89
+ alias post push
90
+
91
+ alias peek_each each # Iterate through all events without removing.
92
+
93
+ # Iterate through all events in the EventQueue, yielding them one at a time
94
+ # to the given block. The EventQueue is flushed after all events have been
95
+ # yielded. You can use #peek_each if you want to keep the events.
96
+ #
97
+ # If the internal variable @autofetch is true, this method will call
98
+ # #fetch_sdl_events once before iterating.
99
+ def each(&block)
100
+ fetch_sdl_events if @autofetch
101
+ super
102
+ self.clear
103
+ end
104
+
105
+ # Posts pending SDL hardware events to the EventQueue. Only one EventQueue
106
+ # should call this method per application, and only if you are not using
107
+ # Rubygame#fetch_sdl_events to manually process events! Otherwise, some
108
+ # events may be removed from SDL's event stack before they can be properly
109
+ # processed!
110
+ def fetch_sdl_events
111
+ self.push(Rubygame.fetch_sdl_events())
112
+ end
113
+
114
+ # Wait for an event to be posted, then return that event.
115
+ # If there is already an event in the queue, this method will immediately
116
+ # return that event.
117
+ # Events that are ignored will not trigger the return.
118
+ #
119
+ # This method takes this argument:
120
+ # time:: how long (in milliseconds) to delay between each check for
121
+ # new events. Defaults to 10 ms.
122
+ #
123
+ # If a block is given to this method, it will be run after each
124
+ # unsuccessful check for new events. This method will pass to the block the
125
+ # number of times it has checked for new events.
126
+ #
127
+ # If the internal variable @autofetch is true, this method will call
128
+ # #fetch_sdl_events before every check for new events.
129
+ #
130
+ # Please be cautious when using this method, as it is rather easy to
131
+ # cause an infinite loop. Two ways an infinite loop might occur are:
132
+ # 1. Waiting for an SDL event when @autofetch is disabled. (This is
133
+ # not a problem if the block will post an event.)
134
+ # 2. Waiting for any event when all possible event types are ignored.
135
+ #
136
+ def wait(delay=10, &block)
137
+ iterations = 0
138
+ if block_given?
139
+ loop do
140
+ fetch_sdl_events() if @autofetch
141
+ if self.length >= 1
142
+ s = self.shift
143
+ return s unless s == nil
144
+ end
145
+ yield iterations
146
+ iterations += 1
147
+ Rubygame::Clock.delay(delay)
148
+ end
149
+ else
150
+ loop do
151
+ fetch_sdl_events() if @autofetch
152
+ s = self.shift
153
+ return s unless s == nil
154
+ iterations += 1
155
+ Rubygame::Clock.delay(delay)
156
+ end
157
+ end
158
+ end
159
+
160
+ end # class EventQueue
161
+
162
+
163
+ # A mixin module to extend EventQueue with the ability to 'deliver' specific
164
+ # types of events to subscribed objects, a la a mailing list. Each object
165
+ # must subscribe for the classes of events it wishes to receive;
166
+ # when the MailQueue receives an event of that type, it will deliver
167
+ # it to the subscribers. See #subscribe for more information.
168
+ #
169
+ # Please note that if you extend an already-existing EventQueue object
170
+ # with this mixin module (rather than including it in a class), you must
171
+ # call #setup before using the object. This will create the necessary
172
+ # internal variables for the MailQueue to work.
173
+ #
174
+ module MailQueue
175
+ # Whether to automatically deliver events as they are received.
176
+ # Enabled by default.
177
+ attr_accessor :autodeliver
178
+
179
+ # Create a new MailQueue object.
180
+ # Like EventQueue.new, this method will yield self if a block is given.
181
+ def initialize()
182
+ setup()
183
+ super
184
+ end
185
+
186
+ # Create the necessary internal variables for the MailQueue.
187
+ def setup
188
+ @subscribe = Hash.new
189
+ @autodeliver = true
190
+ end
191
+
192
+ # Returns an Array of all event classes which have at least one subscriber.
193
+ def list
194
+ @subscribe.collect { |k, v|
195
+ (v.length > 0) ? k : nil rescue NoMethodError nil
196
+ }.compact
197
+ end
198
+
199
+ # Subscribe +client+ to receive events that match +klass+.
200
+ #
201
+ # After the client object has been subscribed, the MailQueue will
202
+ # push along any event for which "klass === event" is true. This usually
203
+ # means that the event is an instance of klass or one of klass's child
204
+ # classes; however, note that klass may have changed its own #=== operator
205
+ # to have different behavior, so this is not always the case.
206
+ #
207
+ # Important: the MailQueue uses the client's #push method to deliver
208
+ # events! If the client does not have such a method, MailQueue will
209
+ # silently catch the error and move on to the next client.
210
+ #
211
+ # A client object may be subscribed for many different types of events
212
+ # simultaneously, and more than one client object may be subscribed to
213
+ # any type of event (in which case each object will receive the event).
214
+ # A client may also be subscribed multiple times for the same type (in
215
+ # which case it will receive duplicate events). Likewise, the client will
216
+ # receive duplicates if it is subscribed to multiple classes which share
217
+ # ancestry, for example Numeric and Float.
218
+ #
219
+ # If a client wishes to receive ALL types of events, it can subscribe to
220
+ # Object, which is a parent class of all objects.
221
+ #
222
+ # If the queue's @autodeliver is true, it will deliver events to
223
+ # subscribers immediately after they are posted, rather than waiting for
224
+ # #deliver to be called.
225
+ def subscribe(client,klass)
226
+ @subscribe[klass] << client
227
+ rescue NoMethodError
228
+ @subscribe[klass] = [client] if @subscribe[klass].nil?
229
+ end
230
+
231
+ # Returns true if +client+ is currently subscribed to receive events
232
+ # of type +klass+.
233
+ def subscribed?(client,klass)
234
+ return true if @subscribe[klass].include?(client) rescue NoMethodError
235
+ return false
236
+ end
237
+
238
+ # Unsubscribes the client to stop receiving events of type +klass+.
239
+ # It is safe (has no effect) to unsubscribe for an event type you
240
+ # are not subscribed to receive.
241
+ def unsubscribe(client,klass)
242
+ @subscribe[klass] -= [client] rescue NoMethodError
243
+ ensure
244
+ return
245
+ end
246
+
247
+ # This private method is used by #deliver to do the real work.
248
+ def deliver_event(event)
249
+ @subscribe.each_pair { |klass,clients|
250
+ begin
251
+ if klass === event
252
+ clients.each do |client|
253
+ client.push(event) rescue NoMethodError
254
+ end
255
+ end
256
+ rescue NoMethodError
257
+ end
258
+ }
259
+ end
260
+ private :deliver_event
261
+
262
+ # Deliver each pending event to all objects which are subscribed to
263
+ # that event class. Every client object MUST have a #push method, or
264
+ # events can't be delivered to it, and it will become very lonely!
265
+ #
266
+ # The queue will be cleared of all events after all deliveries are done.
267
+ def deliver()
268
+ each() { |event| deliver_event(event) }
269
+ clear()
270
+ end
271
+
272
+ # Append events to the queue. If @autodeliver is enabled, all events
273
+ # on the queue will be delivered to subscribed client objects immediately.
274
+ def push(*args)
275
+ # Temporarily disable autofetch to avoid infinite loop
276
+ a, @autofetch = @autofetch, false
277
+ # Fetch once to emulate autofetch, if it was enabled before
278
+ fetch_sdl_events() if a
279
+
280
+ super
281
+ deliver() if @autodeliver
282
+
283
+ @autofetch = a
284
+ return
285
+ end
286
+ end
287
+
288
+ end # module Rubygame