gosu 0.7.10.1

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.
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