gosu 0.7.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (249) hide show
  1. data/COPYING.txt +29 -0
  2. data/Gosu/Async.hpp +48 -0
  3. data/Gosu/Audio.hpp +145 -0
  4. data/Gosu/AutoLink.hpp +16 -0
  5. data/Gosu/Bitmap.hpp +85 -0
  6. data/Gosu/ButtonsMac.hpp +114 -0
  7. data/Gosu/ButtonsWin.hpp +111 -0
  8. data/Gosu/ButtonsX.hpp +115 -0
  9. data/Gosu/Color.hpp +172 -0
  10. data/Gosu/Directories.hpp +36 -0
  11. data/Gosu/Font.hpp +59 -0
  12. data/Gosu/Fwd.hpp +31 -0
  13. data/Gosu/Gosu.hpp +26 -0
  14. data/Gosu/Graphics.hpp +86 -0
  15. data/Gosu/GraphicsBase.hpp +45 -0
  16. data/Gosu/IO.hpp +255 -0
  17. data/Gosu/Image.hpp +148 -0
  18. data/Gosu/ImageData.hpp +45 -0
  19. data/Gosu/Input.hpp +116 -0
  20. data/Gosu/Math.hpp +95 -0
  21. data/Gosu/Platform.hpp +61 -0
  22. data/Gosu/RotFlip.hpp +116 -0
  23. data/Gosu/Sockets.hpp +129 -0
  24. data/Gosu/Text.hpp +47 -0
  25. data/Gosu/TextInput.hpp +57 -0
  26. data/Gosu/Timing.hpp +16 -0
  27. data/Gosu/Utility.hpp +24 -0
  28. data/Gosu/WinUtility.hpp +76 -0
  29. data/Gosu/Window.hpp +84 -0
  30. data/GosuImpl/Async.cpp +37 -0
  31. data/GosuImpl/AudioFmod.cpp +417 -0
  32. data/GosuImpl/AudioSDL.cpp +255 -0
  33. data/GosuImpl/DirectoriesMac.mm +38 -0
  34. data/GosuImpl/DirectoriesUnix.cpp +48 -0
  35. data/GosuImpl/DirectoriesWin.cpp +42 -0
  36. data/GosuImpl/FileUnix.cpp +100 -0
  37. data/GosuImpl/FileWin.cpp +83 -0
  38. data/GosuImpl/Graphics/Bitmap.cpp +116 -0
  39. data/GosuImpl/Graphics/BitmapBMP.cpp +232 -0
  40. data/GosuImpl/Graphics/BitmapColorKey.cpp +39 -0
  41. data/GosuImpl/Graphics/BitmapPNG.cpp +276 -0
  42. data/GosuImpl/Graphics/BitmapUtils.cpp +67 -0
  43. data/GosuImpl/Graphics/BlockAllocator.cpp +127 -0
  44. data/GosuImpl/Graphics/BlockAllocator.hpp +34 -0
  45. data/GosuImpl/Graphics/Color.cpp +126 -0
  46. data/GosuImpl/Graphics/Common.hpp +21 -0
  47. data/GosuImpl/Graphics/DrawOp.hpp +154 -0
  48. data/GosuImpl/Graphics/Font.cpp +110 -0
  49. data/GosuImpl/Graphics/Graphics.cpp +295 -0
  50. data/GosuImpl/Graphics/Image.cpp +159 -0
  51. data/GosuImpl/Graphics/LargeImageData.cpp +115 -0
  52. data/GosuImpl/Graphics/LargeImageData.hpp +37 -0
  53. data/GosuImpl/Graphics/RotFlip.cpp +184 -0
  54. data/GosuImpl/Graphics/TexChunk.cpp +77 -0
  55. data/GosuImpl/Graphics/TexChunk.hpp +40 -0
  56. data/GosuImpl/Graphics/Text.cpp +223 -0
  57. data/GosuImpl/Graphics/TextMac.cpp +242 -0
  58. data/GosuImpl/Graphics/TextPangoFT.cpp +186 -0
  59. data/GosuImpl/Graphics/TextWin.cpp +172 -0
  60. data/GosuImpl/Graphics/Texture.cpp +104 -0
  61. data/GosuImpl/Graphics/Texture.hpp +34 -0
  62. data/GosuImpl/IO.cpp +48 -0
  63. data/GosuImpl/InputMac.mm +677 -0
  64. data/GosuImpl/InputWin.cpp +444 -0
  65. data/GosuImpl/InputX.cpp +158 -0
  66. data/GosuImpl/MacUtility.hpp +48 -0
  67. data/GosuImpl/Math.cpp +49 -0
  68. data/GosuImpl/RubyGosu.swg +474 -0
  69. data/GosuImpl/RubyGosuStub.mm +17 -0
  70. data/GosuImpl/RubyGosu_DllMain.cxx +30 -0
  71. data/GosuImpl/RubyGosu_wrap.cxx +8521 -0
  72. data/GosuImpl/RubyGosu_wrap.h +31 -0
  73. data/GosuImpl/Sockets/CommSocket.cpp +304 -0
  74. data/GosuImpl/Sockets/ListenerSocket.cpp +60 -0
  75. data/GosuImpl/Sockets/MessageSocket.cpp +136 -0
  76. data/GosuImpl/Sockets/Socket.cpp +145 -0
  77. data/GosuImpl/Sockets/Sockets.hpp +66 -0
  78. data/GosuImpl/TextInputMac.mm +207 -0
  79. data/GosuImpl/TextInputWin.cpp +197 -0
  80. data/GosuImpl/TextInputX.cpp +201 -0
  81. data/GosuImpl/TextTTFWin.cpp +247 -0
  82. data/GosuImpl/TimingUnix.cpp +17 -0
  83. data/GosuImpl/TimingWin.cpp +28 -0
  84. data/GosuImpl/Utility.cpp +140 -0
  85. data/GosuImpl/WinMain.cpp +69 -0
  86. data/GosuImpl/WinUtility.cpp +137 -0
  87. data/GosuImpl/WindowMac.mm +466 -0
  88. data/GosuImpl/WindowWin.cpp +447 -0
  89. data/GosuImpl/WindowX.cpp +392 -0
  90. data/GosuImpl/X11vroot.h +118 -0
  91. data/README.txt +13 -0
  92. data/Rakefile +178 -0
  93. data/examples/ChipmunkIntegration.rb +275 -0
  94. data/examples/CptnRuby.rb +231 -0
  95. data/examples/MoreChipmunkAndRMagick.rb +155 -0
  96. data/examples/OpenGLIntegration.rb +232 -0
  97. data/examples/RMagickIntegration.rb +449 -0
  98. data/examples/TextInput.cpp +170 -0
  99. data/examples/TextInput.rb +139 -0
  100. data/examples/Tutorial.cpp +215 -0
  101. data/examples/Tutorial.rb +137 -0
  102. data/examples/media/Beep.wav +0 -0
  103. data/examples/media/CptnRuby Gem.png +0 -0
  104. data/examples/media/CptnRuby Map.txt +25 -0
  105. data/examples/media/CptnRuby Tileset.png +0 -0
  106. data/examples/media/CptnRuby.png +0 -0
  107. data/examples/media/Cursor.png +0 -0
  108. data/examples/media/Earth.png +0 -0
  109. data/examples/media/Explosion.wav +0 -0
  110. data/examples/media/LargeStar.png +0 -0
  111. data/examples/media/Sky.jpg +0 -0
  112. data/examples/media/Smoke.png +0 -0
  113. data/examples/media/Soldier.png +0 -0
  114. data/examples/media/Space.png +0 -0
  115. data/examples/media/Star.png +0 -0
  116. data/examples/media/Starfighter.bmp +0 -0
  117. data/linux/Makefile.in +98 -0
  118. data/linux/configure +5658 -0
  119. data/linux/configure.ac +126 -0
  120. data/linux/extconf.rb +11 -0
  121. data/mac/English.lproj/InfoPlist.strings +0 -0
  122. data/mac/Gosu-Info.plist +26 -0
  123. data/mac/Gosu.xcodeproj/project.pbxproj +1194 -0
  124. data/mac/RubyGosu Template-Info.plist +26 -0
  125. data/mac/libboost_thread_1_34_1_universal.a +0 -0
  126. data/mac/libboost_thread_d_1_34_1_universal.a +0 -0
  127. data/mac/libfmod_universal.a +0 -0
  128. data/mac/libpng_universal.a +0 -0
  129. data/mac/libz_universal.a +0 -0
  130. data/reference/Async_8hpp-source.html +70 -0
  131. data/reference/Audio_8hpp-source.html +114 -0
  132. data/reference/Audio_8hpp.html +50 -0
  133. data/reference/AutoLink_8hpp-source.html +38 -0
  134. data/reference/AutoLink_8hpp.html +34 -0
  135. data/reference/Bitmap_8hpp-source.html +85 -0
  136. data/reference/Bitmap_8hpp.html +58 -0
  137. data/reference/ButtonsMac_8hpp-source.html +133 -0
  138. data/reference/ButtonsWin_8hpp-source.html +133 -0
  139. data/reference/ButtonsX_8hpp-source.html +134 -0
  140. data/reference/Color_8hpp-source.html +169 -0
  141. data/reference/Color_8hpp.html +85 -0
  142. data/reference/Directories_8hpp-source.html +42 -0
  143. data/reference/Directories_8hpp.html +46 -0
  144. data/reference/Font_8hpp-source.html +65 -0
  145. data/reference/Font_8hpp.html +41 -0
  146. data/reference/Fwd_8hpp-source.html +52 -0
  147. data/reference/Fwd_8hpp.html +37 -0
  148. data/reference/Gosu_8hpp-source.html +48 -0
  149. data/reference/Gosu_8hpp.html +34 -0
  150. data/reference/GraphicsBase_8hpp-source.html +57 -0
  151. data/reference/GraphicsBase_8hpp.html +56 -0
  152. data/reference/Graphics_8hpp-source.html +96 -0
  153. data/reference/Graphics_8hpp.html +53 -0
  154. data/reference/IO_8hpp-source.html +255 -0
  155. data/reference/IO_8hpp.html +74 -0
  156. data/reference/ImageData_8hpp-source.html +62 -0
  157. data/reference/ImageData_8hpp.html +43 -0
  158. data/reference/Image_8hpp-source.html +126 -0
  159. data/reference/Image_8hpp.html +48 -0
  160. data/reference/Input_8hpp-source.html +118 -0
  161. data/reference/Input_8hpp.html +50 -0
  162. data/reference/Math_8hpp-source.html +92 -0
  163. data/reference/Math_8hpp.html +74 -0
  164. data/reference/Platform_8hpp-source.html +83 -0
  165. data/reference/Platform_8hpp.html +73 -0
  166. data/reference/RotFlip_8hpp-source.html +138 -0
  167. data/reference/RotFlip_8hpp.html +77 -0
  168. data/reference/Sockets_8hpp-source.html +130 -0
  169. data/reference/Sockets_8hpp.html +66 -0
  170. data/reference/TextInput_8hpp-source.html +64 -0
  171. data/reference/TextInput_8hpp.html +41 -0
  172. data/reference/Text_8hpp-source.html +51 -0
  173. data/reference/Text_8hpp.html +46 -0
  174. data/reference/Timing_8hpp-source.html +36 -0
  175. data/reference/Timing_8hpp.html +42 -0
  176. data/reference/Utility_8hpp-source.html +44 -0
  177. data/reference/Utility_8hpp.html +48 -0
  178. data/reference/WinUtility_8hpp-source.html +79 -0
  179. data/reference/WinUtility_8hpp.html +64 -0
  180. data/reference/Window_8hpp-source.html +91 -0
  181. data/reference/Window_8hpp.html +41 -0
  182. data/reference/annotated.html +51 -0
  183. data/reference/classGosu_1_1Audio-members.html +34 -0
  184. data/reference/classGosu_1_1Audio.html +46 -0
  185. data/reference/classGosu_1_1Bitmap-members.html +44 -0
  186. data/reference/classGosu_1_1Bitmap.html +263 -0
  187. data/reference/classGosu_1_1Buffer-members.html +44 -0
  188. data/reference/classGosu_1_1Buffer.html +78 -0
  189. data/reference/classGosu_1_1Buffer.png +0 -0
  190. data/reference/classGosu_1_1Button-members.html +36 -0
  191. data/reference/classGosu_1_1Button.html +143 -0
  192. data/reference/classGosu_1_1Color-members.html +56 -0
  193. data/reference/classGosu_1_1Color.html +387 -0
  194. data/reference/classGosu_1_1File-members.html +41 -0
  195. data/reference/classGosu_1_1File.html +69 -0
  196. data/reference/classGosu_1_1File.png +0 -0
  197. data/reference/classGosu_1_1Font-members.html +39 -0
  198. data/reference/classGosu_1_1Font.html +309 -0
  199. data/reference/classGosu_1_1Graphics-members.html +50 -0
  200. data/reference/classGosu_1_1Graphics.html +234 -0
  201. data/reference/classGosu_1_1Image-members.html +45 -0
  202. data/reference/classGosu_1_1Image.html +518 -0
  203. data/reference/classGosu_1_1ImageData-members.html +37 -0
  204. data/reference/classGosu_1_1ImageData.html +60 -0
  205. data/reference/classGosu_1_1Input-members.html +44 -0
  206. data/reference/classGosu_1_1Input.html +223 -0
  207. data/reference/classGosu_1_1MessageSocket-members.html +40 -0
  208. data/reference/classGosu_1_1MessageSocket.html +233 -0
  209. data/reference/classGosu_1_1Resource-members.html +39 -0
  210. data/reference/classGosu_1_1Resource.html +116 -0
  211. data/reference/classGosu_1_1Resource.png +0 -0
  212. data/reference/classGosu_1_1Sample-members.html +37 -0
  213. data/reference/classGosu_1_1Sample.html +200 -0
  214. data/reference/classGosu_1_1SampleInstance-members.html +38 -0
  215. data/reference/classGosu_1_1SampleInstance.html +169 -0
  216. data/reference/classGosu_1_1Song-members.html +43 -0
  217. data/reference/classGosu_1_1Song.html +260 -0
  218. data/reference/classGosu_1_1TextInput-members.html +38 -0
  219. data/reference/classGosu_1_1TextInput.html +121 -0
  220. data/reference/classGosu_1_1Window-members.html +50 -0
  221. data/reference/classGosu_1_1Window.html +271 -0
  222. data/reference/doxyfile +233 -0
  223. data/reference/doxygen.css +433 -0
  224. data/reference/doxygen.png +0 -0
  225. data/reference/files.html +54 -0
  226. data/reference/functions.html +236 -0
  227. data/reference/functions_enum.html +45 -0
  228. data/reference/functions_func.html +227 -0
  229. data/reference/functions_vars.html +47 -0
  230. data/reference/hierarchy.html +53 -0
  231. data/reference/index.html +26 -0
  232. data/reference/namespaceGosu.html +2890 -0
  233. data/reference/namespaceGosu_1_1Colors.html +70 -0
  234. data/reference/namespaceGosu_1_1Win.html +275 -0
  235. data/reference/namespacemembers.html +216 -0
  236. data/reference/namespacemembers_enum.html +52 -0
  237. data/reference/namespacemembers_eval.html +54 -0
  238. data/reference/namespacemembers_func.html +185 -0
  239. data/reference/namespacemembers_type.html +46 -0
  240. data/reference/namespacemembers_vars.html +46 -0
  241. data/reference/namespaces.html +35 -0
  242. data/reference/tab_b.gif +0 -0
  243. data/reference/tab_l.gif +0 -0
  244. data/reference/tab_r.gif +0 -0
  245. data/reference/tabs.css +102 -0
  246. data/windows/Gosu.sln +29 -0
  247. data/windows/Gosu.vcproj +553 -0
  248. data/windows/RubyGosu.vcproj +138 -0
  249. metadata +305 -0
@@ -0,0 +1,231 @@
1
+ # Basically, the tutorial game taken to a jump'n'run perspective.
2
+
3
+ # Shows how to
4
+ # * implement jumping/gravity
5
+ # * implement scrolling
6
+ # * implement a simple tile-based map
7
+ # * load levels from primitive text files
8
+
9
+ # Some exercises, starting at the real basics:
10
+ # 0) understand the existing code!
11
+ # As shown in the tutorial:
12
+ # 1) change it use Gosu's Z-ordering
13
+ # 2) add gamepad support
14
+ # 3) add a score as in the tutorial game
15
+ # 4) similarly, add sound effects for various events
16
+ # Exploring this game's code and Gosu:
17
+ # 5) make the player wider, so he doesn't fall off edges as easily
18
+ # 6) add background music (check if playing in Window#update to implement
19
+ # looping)
20
+ # 7) implement parallax scrolling for the star background!
21
+ # Getting tricky:
22
+ # 8) optimize Map#draw so only tiles on screen are drawn (needs modulo, a pen
23
+ # and paper to figure out)
24
+ # 9) add loading of next level when all gems are collected
25
+ # ...Enemies, a more sophisticated object system, weapons, title and credits
26
+ # screens...
27
+
28
+ begin
29
+ # In case you use Gosu via rubygems.
30
+ require 'rubygems'
31
+ rescue LoadError
32
+ # In case you don't.
33
+ end
34
+
35
+ require 'gosu'
36
+ include Gosu
37
+
38
+ module Tiles
39
+ Grass = 0
40
+ Earth = 1
41
+ end
42
+
43
+ class CollectibleGem
44
+ attr_reader :x, :y
45
+
46
+ def initialize(image, x, y)
47
+ @image = image
48
+ @x, @y = x, y
49
+ end
50
+
51
+ def draw(screen_x, screen_y)
52
+ # Draw, slowly rotating
53
+ @image.draw_rot(@x - screen_x, @y - screen_y, 0,
54
+ 25 * Math.sin(milliseconds / 133.7))
55
+ end
56
+ end
57
+
58
+ # Player class.
59
+ class CptnRuby
60
+ attr_reader :x, :y
61
+
62
+ def initialize(window, x, y)
63
+ @x, @y = x, y
64
+ @dir = :left
65
+ @vy = 0 # Vertical velocity
66
+ @map = window.map
67
+ # Load all animation frames
68
+ @standing, @walk1, @walk2, @jump =
69
+ *Image.load_tiles(window, "media/CptnRuby.png", 50, 50, false)
70
+ # This always points to the frame that is currently drawn.
71
+ # This is set in update, and used in draw.
72
+ @cur_image = @standing
73
+ end
74
+
75
+ def draw(screen_x, screen_y)
76
+ # Flip vertically when facing to the left.
77
+ if @dir == :left then
78
+ offs_x = -25
79
+ factor = 1.0
80
+ else
81
+ offs_x = 25
82
+ factor = -1.0
83
+ end
84
+ @cur_image.draw(@x - screen_x + offs_x, @y - screen_y - 49, 0, factor, 1.0)
85
+ end
86
+
87
+ # Could the object be placed at x + offs_x/y + offs_y without being stuck?
88
+ def would_fit(offs_x, offs_y)
89
+ # Check at the center/top and center/bottom for map collisions
90
+ not @map.solid?(@x + offs_x, @y + offs_y) and
91
+ not @map.solid?(@x + offs_x, @y + offs_y - 45)
92
+ end
93
+
94
+ def update(move_x)
95
+ # Select image depending on action
96
+ if (move_x == 0)
97
+ @cur_image = @standing
98
+ else
99
+ @cur_image = (milliseconds / 175 % 2 == 0) ? @walk1 : @walk2
100
+ end
101
+ if (@vy < 0)
102
+ @cur_image = @jump
103
+ end
104
+
105
+ # Directional walking, horizontal movement
106
+ if move_x > 0 then
107
+ @dir = :right
108
+ move_x.times { if would_fit(1, 0) then @x += 1 end }
109
+ end
110
+ if move_x < 0 then
111
+ @dir = :left
112
+ (-move_x).times { if would_fit(-1, 0) then @x -= 1 end }
113
+ end
114
+
115
+ # Acceleration/gravity
116
+ # By adding 1 each frame, and (ideally) adding vy to y, the player's
117
+ # jumping curve will be the parabole we want it to be.
118
+ @vy += 1
119
+ # Vertical movement
120
+ if @vy > 0 then
121
+ @vy.times { if would_fit(0, 1) then @y += 1 else @vy = 0 end }
122
+ end
123
+ if @vy < 0 then
124
+ (-@vy).times { if would_fit(0, -1) then @y -= 1 else @vy = 0 end }
125
+ end
126
+ end
127
+
128
+ def try_to_jump
129
+ if @map.solid?(@x, @y + 1) then
130
+ @vy = -20
131
+ end
132
+ end
133
+
134
+ def collect_gems(gems)
135
+ # Same as in the tutorial game.
136
+ gems.reject! do |c|
137
+ (c.x - @x).abs < 50 and (c.y - @y).abs < 50
138
+ end
139
+ end
140
+ end
141
+
142
+ # Map class holds and draws tiles and gems.
143
+ class Map
144
+ attr_reader :width, :height, :gems
145
+
146
+ def initialize(window, filename)
147
+ # Load 60x60 tiles, 5px overlap in all four directions.
148
+ @tileset = Image.load_tiles(window, "media/CptnRuby Tileset.png", 60, 60, true)
149
+ @sky = Image.new(window, "media/Space.png", true)
150
+
151
+ gem_img = Image.new(window, "media/CptnRuby Gem.png", false)
152
+ @gems = []
153
+
154
+ lines = File.readlines(filename).map { |line| line.chop }
155
+ @height = lines.size
156
+ @width = lines[0].size
157
+ @tiles = Array.new(@width) do |x|
158
+ Array.new(@height) do |y|
159
+ case lines[y][x, 1]
160
+ when '"'
161
+ Tiles::Grass
162
+ when '#'
163
+ Tiles::Earth
164
+ when 'x'
165
+ @gems.push(CollectibleGem.new(gem_img, x * 50 + 25, y * 50 + 25))
166
+ nil
167
+ else
168
+ nil
169
+ end
170
+ end
171
+ end
172
+ end
173
+
174
+ def draw(screen_x, screen_y)
175
+ # Sigh, stars!
176
+ @sky.draw(0, 0, 0)
177
+
178
+
179
+ # Very primitive drawing function:
180
+ # Draws all the tiles, some off-screen, some on-screen.
181
+ @height.times do |y|
182
+ @width.times do |x|
183
+ tile = @tiles[x][y]
184
+ if tile
185
+ # Draw the tile with an offset (tile images have some overlap)
186
+ # Scrolling is implemented here just as in the game objects.
187
+ @tileset[tile].draw(x * 50 - screen_x - 5, y * 50 - screen_y - 5, 0)
188
+ end
189
+ end
190
+ end
191
+ @gems.each { |c| c.draw(screen_x, screen_y) }
192
+ end
193
+
194
+ # Solid at a given pixel position?
195
+ def solid?(x, y)
196
+ y < 0 || @tiles[x / 50][y / 50]
197
+ end
198
+ end
199
+
200
+ class Game < Window
201
+ attr_reader :map
202
+
203
+ def initialize
204
+ super(640, 480, false)
205
+ self.caption = "Cptn. Ruby"
206
+ @map = Map.new(self, "media/CptnRuby Map.txt")
207
+ @cptn = CptnRuby.new(self, 400, 100)
208
+ # Scrolling is stored as the position of the top left corner of the screen.
209
+ @screen_x = @screen_y = 0
210
+ end
211
+ def update
212
+ move_x = 0
213
+ move_x -= 5 if button_down? Button::KbLeft
214
+ move_x += 5 if button_down? Button::KbRight
215
+ @cptn.update(move_x)
216
+ @cptn.collect_gems(@map.gems)
217
+ # Scrolling follows player
218
+ @screen_x = [[@cptn.x - 320, 0].max, @map.width * 50 - 640].min
219
+ @screen_y = [[@cptn.y - 240, 0].max, @map.height * 50 - 480].min
220
+ end
221
+ def draw
222
+ @map.draw @screen_x, @screen_y
223
+ @cptn.draw @screen_x, @screen_y
224
+ end
225
+ def button_down(id)
226
+ if id == Button::KbUp then @cptn.try_to_jump end
227
+ if id == Button::KbEscape then close end
228
+ end
229
+ end
230
+
231
+ Game.new.show
@@ -0,0 +1,155 @@
1
+ # Based on the C Demo3 demonstration distributed with Chipmunk.
2
+ # Also with some help from the ChipmunkIntegration.rb program.
3
+ #
4
+ # License: Same as for Gosu (MIT)
5
+ # Created on 21/10/2007, 00:05:19 by Robert Sheehan
6
+
7
+ require 'rubygems'
8
+ require 'gosu'
9
+ require 'chipmunk'
10
+ require 'RMagick'
11
+
12
+ # Convenience method for converting from radians to a Vec2 vector.
13
+ class Numeric
14
+ def radians_to_vec2
15
+ CP::Vec2.new(Math::cos(self), Math::sin(self))
16
+ end
17
+ end
18
+
19
+ # Layering of sprites
20
+ module ZOrder
21
+ Background, Box = *0..1
22
+ end
23
+
24
+ SCREEN_WIDTH = 640
25
+ SCREEN_HEIGHT = 480
26
+ TICK = 1.0/60.0
27
+ NUM_POLYGONS = 80
28
+ NUM_SIDES = 4
29
+ EDGE_SIZE = 15
30
+
31
+ # Everything appears in the Gosu::Window.
32
+ class DemoWindow < Gosu::Window
33
+
34
+ def initialize
35
+ super(SCREEN_WIDTH, SCREEN_HEIGHT, false)
36
+ self.caption = "A Chipmunk-RMagick-Gosu Demonstration"
37
+ @space = CP::Space.new
38
+ @space.iterations = 5
39
+ @space.gravity = CP::Vec2.new(0, 100)
40
+ # you can replace the background with any image with this line
41
+ # background = Magick::ImageList.new( "media/Space.png")
42
+ fill = Magick::TextureFill.new(Magick::ImageList.new("granite:"))
43
+ background = Magick::Image.new(SCREEN_WIDTH, SCREEN_HEIGHT, fill)
44
+ setup_triangles(background)
45
+ @background_image = Gosu::Image.new(self, background, true) # turn the image into a Gosu one
46
+ @boxes = create_boxes(NUM_POLYGONS)
47
+ end
48
+
49
+ # Create all of the static triangles.
50
+ # Adds them to the space and the background image.
51
+ def setup_triangles(background)
52
+ gc = Magick::Draw.new
53
+ gc.stroke_width(2)
54
+ gc.stroke('red')
55
+ gc.fill('blue')
56
+ # all the triangles are part of the same body
57
+ body = CP::Body.new(Float::MAX, Float::MAX)
58
+ base = 15
59
+ height = 10
60
+ shape_vertices = [CP::Vec2.new(-base, base), CP::Vec2.new(base, base), CP::Vec2.new(0, -height)]
61
+ # make shapes and images
62
+ 9.times do |i|
63
+ 6.times do |j|
64
+ stagger = (j % 2) * 40
65
+ x = i * 80 + stagger
66
+ y = j * 70 + 80
67
+ shape = CP::Shape::Poly.new(body, shape_vertices, CP::Vec2.new(x, y))
68
+ shape.e = 1
69
+ shape.u = 1
70
+ @space.add_static_shape(shape)
71
+ gc.polygon(x - base + 1, y + base - 1, x + base - 1, y + base - 1, x, y - height + 1)
72
+ end
73
+ end
74
+ # do the drawing
75
+ gc.draw(background)
76
+ end
77
+
78
+ # Produces the vertices of a regular polygon.
79
+ def polygon_vertices(sides, size)
80
+ vertices = []
81
+ sides.times do |i|
82
+ angle = -2 * Math::PI * i / sides
83
+ vertices << angle.radians_to_vec2() * size
84
+ end
85
+ return vertices
86
+ end
87
+
88
+ # Produces the image of a polygon.
89
+ def polygon_image(vertices)
90
+ box_image = Magick::Image.new(EDGE_SIZE * 2, EDGE_SIZE * 2) { self.background_color = 'transparent' }
91
+ gc = Magick::Draw.new
92
+ gc.stroke('red')
93
+ gc.fill('plum')
94
+ draw_vertices = vertices.map { |v| [v.x + EDGE_SIZE, v.y + EDGE_SIZE] }.flatten
95
+ gc.polygon(*draw_vertices)
96
+ gc.draw(box_image)
97
+ return Gosu::Image.new(self, box_image, false)
98
+ end
99
+
100
+ # Produces the polygon objects and adds them to the space.
101
+ def create_boxes(num)
102
+ box_vertices = polygon_vertices(NUM_SIDES, EDGE_SIZE)
103
+ box_image = polygon_image(box_vertices)
104
+ boxes = []
105
+ num.times do
106
+ body = CP::Body.new(1, CP::moment_for_poly(1.0, box_vertices, CP::Vec2.new(0, 0))) # mass, moment of inertia
107
+ body.p = CP::Vec2.new(rand(SCREEN_WIDTH), rand(40) - 50)
108
+ shape = CP::Shape::Poly.new(body, box_vertices, CP::Vec2.new(0, 0))
109
+ shape.e = 0.0
110
+ shape.u = 0.4
111
+ boxes << Box.new(box_image, body)
112
+ @space.add_body(body)
113
+ @space.add_shape(shape)
114
+ end
115
+ return boxes
116
+ end
117
+
118
+ # All the simulation is done here.
119
+ def update
120
+ @space.step(TICK)
121
+ @boxes.each { |box| box.check_off_screen }
122
+ end
123
+
124
+ # All the updating of the screen is done here.
125
+ def draw
126
+ @background_image.draw(0, 0, ZOrder::Background)
127
+ @boxes.each { |box| box.draw }
128
+ end
129
+
130
+ end
131
+
132
+ # The falling boxes class.
133
+ # Nothing more than a body and an image.
134
+ class Box
135
+
136
+ def initialize(image, body)
137
+ @image = image
138
+ @body = body
139
+ end
140
+
141
+ # If it goes offscreen we put it back to the top.
142
+ def check_off_screen
143
+ pos = @body.p
144
+ if pos.y > SCREEN_HEIGHT + EDGE_SIZE or pos.x > SCREEN_WIDTH + EDGE_SIZE or pos.x < -EDGE_SIZE
145
+ @body.p = CP::Vec2.new(rand * SCREEN_WIDTH, 0)
146
+ end
147
+ end
148
+
149
+ def draw
150
+ @image.draw_rot(@body.p.x, @body.p.y, ZOrder::Box, @body.a.radians_to_gosu)
151
+ end
152
+ end
153
+
154
+ window = DemoWindow.new
155
+ window.show
@@ -0,0 +1,232 @@
1
+ # The tutorial game over a landscape rendered with OpenGL.
2
+ # Basically shows how arbitrary OpenGL calls can be put into
3
+ # the block given to Window#gl, and that Gosu Images can be
4
+ # used as textures using the gl_tex_info call.
5
+
6
+ begin
7
+ # In case you use Gosu via RubyGems.
8
+ require 'rubygems'
9
+ rescue LoadError
10
+ # In case you don't.
11
+ end
12
+
13
+ require 'gosu'
14
+ require 'gl'
15
+ require 'glu'
16
+
17
+ include Gl
18
+ include Glu
19
+
20
+ module ZOrder
21
+ Stars, Player, UI = *0..3
22
+ end
23
+
24
+ # The only really new class here.
25
+ # Draws a scrolling, repeating texture with a randomized height map.
26
+ class GLBackground
27
+ # Height map size
28
+ POINTS_X = 7
29
+ POINTS_Y = 7
30
+ # Scrolling speed
31
+ SCROLLS_PER_STEP = 50
32
+
33
+ def initialize(window)
34
+ @image = Gosu::Image.new(window, "media/Earth.png", true)
35
+ @scrolls = 0
36
+ @height_map = Array.new(POINTS_Y) { Array.new(POINTS_X) { rand } }
37
+ end
38
+
39
+ def scroll
40
+ @scrolls += 1
41
+ if @scrolls == SCROLLS_PER_STEP then
42
+ @scrolls = 0
43
+ @height_map.shift
44
+ @height_map.push Array.new(POINTS_X) { rand }
45
+ end
46
+ end
47
+
48
+ def exec_gl
49
+ # Get the name of the OpenGL texture the Image resides on, and the
50
+ # u/v coordinates of the rect it occupies.
51
+ # gl_tex_info can return nil if the image was too large to fit onto
52
+ # a single OpenGL texture and was internally split up.
53
+ info = @image.gl_tex_info
54
+ return unless info
55
+
56
+ # Pretty straightforward OpenGL code.
57
+
58
+ glDepthFunc(GL_GEQUAL)
59
+ glEnable(GL_DEPTH_TEST)
60
+ glEnable(GL_BLEND)
61
+
62
+ glMatrixMode(GL_PROJECTION)
63
+ glLoadIdentity
64
+ glFrustum(-0.10, 0.10, -0.075, 0.075, 1, 100)
65
+
66
+ glMatrixMode(GL_MODELVIEW)
67
+ glLoadIdentity
68
+ glTranslate(0, 0, -4)
69
+
70
+ glEnable(GL_TEXTURE_2D)
71
+ glBindTexture(GL_TEXTURE_2D, info.tex_name)
72
+
73
+ offs_y = 1.0 * @scrolls / SCROLLS_PER_STEP
74
+
75
+ 0.upto(POINTS_Y - 2) do |y|
76
+ 0.upto(POINTS_X - 2) do |x|
77
+ glBegin(GL_TRIANGLE_STRIP)
78
+ z = @height_map[y][x]
79
+ glColor4d(1, 1, 1, z)
80
+ glTexCoord2d(info.left, info.top)
81
+ glVertex3d(-0.5 + (x - 0.0) / (POINTS_X-1), -0.5 + (y - offs_y - 0.0) / (POINTS_Y-2), z)
82
+
83
+ z = @height_map[y+1][x]
84
+ glColor4d(1, 1, 1, z)
85
+ glTexCoord2d(info.left, info.bottom)
86
+ glVertex3d(-0.5 + (x - 0.0) / (POINTS_X-1), -0.5 + (y - offs_y + 1.0) / (POINTS_Y-2), z)
87
+
88
+ z = @height_map[y][x + 1]
89
+ glColor4d(1, 1, 1, z)
90
+ glTexCoord2d(info.right, info.top)
91
+ glVertex3d(-0.5 + (x + 1.0) / (POINTS_X-1), -0.5 + (y - offs_y - 0.0) / (POINTS_Y-2), z)
92
+
93
+ z = @height_map[y+1][x + 1]
94
+ glColor4d(1, 1, 1, z)
95
+ glTexCoord2d(info.right, info.bottom)
96
+ glVertex3d(-0.5 + (x + 1.0) / (POINTS_X-1), -0.5 + (y - offs_y + 1.0) / (POINTS_Y-2), z)
97
+ glEnd
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ # Roughly adapted from the tutorial game. Always faces north.
104
+ class Player
105
+ Speed = 7
106
+
107
+ attr_reader :score
108
+
109
+ def initialize(window, x, y)
110
+ @image = Gosu::Image.new(window, "media/Starfighter.bmp", false)
111
+ @beep = Gosu::Sample.new(window, "media/Beep.wav")
112
+ @x, @y = x, y
113
+ @score = 0
114
+ end
115
+
116
+ def move_left
117
+ @x = [@x - Speed, 0].max
118
+ end
119
+
120
+ def move_right
121
+ @x = [@x + Speed, 800].min
122
+ end
123
+
124
+ def accelerate
125
+ @y = [@y - Speed, 50].max
126
+ end
127
+
128
+ def brake
129
+ @y = [@y + Speed, 600].min
130
+ end
131
+
132
+ def draw
133
+ @image.draw(@x - @image.width / 2, @y - @image.height / 2, ZOrder::Player)
134
+ end
135
+
136
+ def collect_stars(stars)
137
+ stars.reject! do |star|
138
+ if Gosu::distance(@x, @y, star.x, star.y) < 35 then
139
+ @score += 10
140
+ @beep.play
141
+ true
142
+ else
143
+ false
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ # Also taken from the tutorial, but drawn with draw_rot and an increasing angle
150
+ # for extra rotation coolness!
151
+ class Star
152
+ attr_reader :x, :y
153
+
154
+ def initialize(animation)
155
+ @animation = animation
156
+ @color = Gosu::Color.new(0xff000000)
157
+ @color.red = rand(255 - 40) + 40
158
+ @color.green = rand(255 - 40) + 40
159
+ @color.blue = rand(255 - 40) + 40
160
+ @x = rand * 800
161
+ @y = 0
162
+ end
163
+
164
+ def draw
165
+ img = @animation[Gosu::milliseconds / 100 % @animation.size];
166
+ img.draw_rot(@x, @y, ZOrder::Stars, @y, 0.5, 0.5, 1, 1, @color, :additive)
167
+ end
168
+
169
+ def update
170
+ # Move towards bottom of screen
171
+ @y += 3
172
+ # Return false when out of screen (gets deleted then)
173
+ @y < 650
174
+ end
175
+ end
176
+
177
+ class GameWindow < Gosu::Window
178
+ def initialize
179
+ super(800, 600, false)
180
+ self.caption = "Gosu & OpenGL Integration Demo"
181
+
182
+ @gl_background = GLBackground.new(self)
183
+
184
+ @player = Player.new(self, 400, 500)
185
+
186
+ @star_anim = Gosu::Image::load_tiles(self, "media/Star.png", 25, 25, false)
187
+ @stars = Array.new
188
+
189
+ @font = Gosu::Font.new(self, Gosu::default_font_name, 20)
190
+ end
191
+
192
+ def update
193
+ @player.move_left if button_down? Gosu::Button::KbLeft or button_down? Gosu::Button::GpLeft
194
+ @player.move_right if button_down? Gosu::Button::KbRight or button_down? Gosu::Button::GpRight
195
+ @player.accelerate if button_down? Gosu::Button::KbUp or button_down? Gosu::Button::GpUp
196
+ @player.brake if button_down? Gosu::Button::KbDown or button_down? Gosu::Button::GpDown
197
+
198
+ @player.collect_stars(@stars)
199
+
200
+ @stars.reject! { |star| !star.update }
201
+
202
+ @gl_background.scroll
203
+
204
+ @stars.push(Star.new(@star_anim)) if rand(20) == 0
205
+ end
206
+
207
+ def draw
208
+ # gl will execute the given block in a clean OpenGL environment, then reset
209
+ # everything so Gosu's rendering can take place again.
210
+
211
+ gl do
212
+ glClearColor(0.0, 0.2, 0.5, 1.0)
213
+ glClearDepth(0)
214
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
215
+
216
+ @gl_background.exec_gl
217
+ end
218
+
219
+ @player.draw
220
+ @stars.each { |star| star.draw }
221
+ @font.draw("Score: #{@player.score}", 10, 10, ZOrder::UI, 1.0, 1.0, 0xffffff00)
222
+ end
223
+
224
+ def button_down(id)
225
+ if id == Gosu::Button::KbEscape
226
+ close
227
+ end
228
+ end
229
+ end
230
+
231
+ window = GameWindow.new
232
+ window.show