gosu-examples 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +14 -0
  4. data/bin/gosu-examples +97 -0
  5. data/examples/chipmunk_and_rmagick.rb +152 -0
  6. data/examples/chipmunk_integration.rb +278 -0
  7. data/examples/cptn_ruby.rb +229 -0
  8. data/examples/media/BrokenPNG.png +0 -0
  9. data/examples/media/Cursor.png +0 -0
  10. data/examples/media/JingleBells.mp3 +0 -0
  11. data/examples/media/JingleBells.ogg +0 -0
  12. data/examples/media/Loop.wav +0 -0
  13. data/examples/media/Sample.wav +0 -0
  14. data/examples/media/SquareTexture.png +0 -0
  15. data/examples/media/Wallpaper.png +0 -0
  16. data/examples/media/WallpaperXXL.png +0 -0
  17. data/examples/media/WhiteAlpha.png +0 -0
  18. data/examples/media/audio_formats/aiff_32bit_float.aiff +0 -0
  19. data/examples/media/audio_formats/au_16bit_pcm.au +0 -0
  20. data/examples/media/audio_formats/caf_be_16bit_44khz.caf +0 -0
  21. data/examples/media/audio_formats/caf_le_16bit_44khz.caf +0 -0
  22. data/examples/media/audio_formats/caf_le_8bit_44khz.caf +0 -0
  23. data/examples/media/audio_formats/general_midi.mid +0 -0
  24. data/examples/media/audio_formats/impulse_tracker.it +0 -0
  25. data/examples/media/audio_formats/mp3_128k_stereo.mp3 +0 -0
  26. data/examples/media/audio_formats/mp3_avg_96kbit_jointstereo.mp3 +0 -0
  27. data/examples/media/audio_formats/ogg_vorbis.ogg +0 -0
  28. data/examples/media/audio_formats/wav_16bit_pcm.wav +0 -0
  29. data/examples/media/audio_formats/wav_32bit_pcm.wav +0 -0
  30. data/examples/media/audio_formats/wav_4bit_ms_adpcm.wav +0 -0
  31. data/examples/media/beep.wav +0 -0
  32. data/examples/media/cptn_ruby.png +0 -0
  33. data/examples/media/cptn_ruby_map.txt +25 -0
  34. data/examples/media/earth.png +0 -0
  35. data/examples/media/explosion.wav +0 -0
  36. data/examples/media/gem.png +0 -0
  37. data/examples/media/header.psd +0 -0
  38. data/examples/media/image_formats/test.jpg +0 -0
  39. data/examples/media/image_formats/test.psd +0 -0
  40. data/examples/media/landscape.svg +10 -0
  41. data/examples/media/large_star.png +0 -0
  42. data/examples/media/smoke.png +0 -0
  43. data/examples/media/soldier.png +0 -0
  44. data/examples/media/space.png +0 -0
  45. data/examples/media/star.png +0 -0
  46. data/examples/media/starfighter.bmp +0 -0
  47. data/examples/media/tileset.png +0 -0
  48. data/examples/media/vera.ttf +0 -0
  49. data/examples/opengl_integration.rb +224 -0
  50. data/examples/rmagick_integration.rb +413 -0
  51. data/examples/tutorial.rb +129 -0
  52. data/examples/welcome.rb +59 -0
  53. data/lib/gosu-examples/example.rb +82 -0
  54. data/lib/gosu-examples/sidebar.rb +60 -0
  55. metadata +112 -0
@@ -0,0 +1,229 @@
1
+ # Encoding: UTF-8
2
+
3
+ # Basically, the tutorial game taken to a jump'n'run perspective.
4
+
5
+ # Shows how to
6
+ # * implement jumping/gravity
7
+ # * implement scrolling using Window#translate
8
+ # * implement a simple tile-based map
9
+ # * load levels from primitive text files
10
+
11
+ # Some exercises, starting at the real basics:
12
+ # 0) understand the existing code!
13
+ # As shown in the tutorial:
14
+ # 1) change it use Gosu's Z-ordering
15
+ # 2) add gamepad support
16
+ # 3) add a score as in the tutorial game
17
+ # 4) similarly, add sound effects for various events
18
+ # Exploring this game's code and Gosu:
19
+ # 5) make the player wider, so he doesn't fall off edges as easily
20
+ # 6) add background music (check if playing in Window#update to implement
21
+ # looping)
22
+ # 7) implement parallax scrolling for the star background!
23
+ # Getting tricky:
24
+ # 8) optimize Map#draw so only tiles on screen are drawn (needs modulo, a pen
25
+ # and paper to figure out)
26
+ # 9) add loading of next level when all gems are collected
27
+ # ...Enemies, a more sophisticated object system, weapons, title and credits
28
+ # screens...
29
+
30
+ require 'rubygems'
31
+ require 'gosu'
32
+
33
+ WIDTH, HEIGHT = 600, 600
34
+
35
+ module Tiles
36
+ Grass = 0
37
+ Earth = 1
38
+ end
39
+
40
+ class CollectibleGem
41
+ attr_reader :x, :y
42
+
43
+ def initialize(image, x, y)
44
+ @image = image
45
+ @x, @y = x, y
46
+ end
47
+
48
+ def draw
49
+ # Draw, slowly rotating
50
+ @image.draw_rot(@x, @y, 0, 25 * Math.sin(Gosu::milliseconds / 133.7))
51
+ end
52
+ end
53
+
54
+ # Player class.
55
+ class Player
56
+ attr_reader :x, :y
57
+
58
+ def initialize(map, x, y)
59
+ @x, @y = x, y
60
+ @dir = :left
61
+ @vy = 0 # Vertical velocity
62
+ @map = map
63
+ # Load all animation frames
64
+ @standing, @walk1, @walk2, @jump = *Gosu::Image.load_tiles("media/cptn_ruby.png", 50, 50)
65
+ # This always points to the frame that is currently drawn.
66
+ # This is set in update, and used in draw.
67
+ @cur_image = @standing
68
+ end
69
+
70
+ def draw
71
+ # Flip vertically when facing to the left.
72
+ if @dir == :left then
73
+ offs_x = -25
74
+ factor = 1.0
75
+ else
76
+ offs_x = 25
77
+ factor = -1.0
78
+ end
79
+ @cur_image.draw(@x + offs_x, @y - 49, 0, factor, 1.0)
80
+ end
81
+
82
+ # Could the object be placed at x + offs_x/y + offs_y without being stuck?
83
+ def would_fit(offs_x, offs_y)
84
+ # Check at the center/top and center/bottom for map collisions
85
+ not @map.solid?(@x + offs_x, @y + offs_y) and
86
+ not @map.solid?(@x + offs_x, @y + offs_y - 45)
87
+ end
88
+
89
+ def update(move_x)
90
+ # Select image depending on action
91
+ if (move_x == 0)
92
+ @cur_image = @standing
93
+ else
94
+ @cur_image = (Gosu::milliseconds / 175 % 2 == 0) ? @walk1 : @walk2
95
+ end
96
+ if (@vy < 0)
97
+ @cur_image = @jump
98
+ end
99
+
100
+ # Directional walking, horizontal movement
101
+ if move_x > 0 then
102
+ @dir = :right
103
+ move_x.times { if would_fit(1, 0) then @x += 1 end }
104
+ end
105
+ if move_x < 0 then
106
+ @dir = :left
107
+ (-move_x).times { if would_fit(-1, 0) then @x -= 1 end }
108
+ end
109
+
110
+ # Acceleration/gravity
111
+ # By adding 1 each frame, and (ideally) adding vy to y, the player's
112
+ # jumping curve will be the parabole we want it to be.
113
+ @vy += 1
114
+ # Vertical movement
115
+ if @vy > 0 then
116
+ @vy.times { if would_fit(0, 1) then @y += 1 else @vy = 0 end }
117
+ end
118
+ if @vy < 0 then
119
+ (-@vy).times { if would_fit(0, -1) then @y -= 1 else @vy = 0 end }
120
+ end
121
+ end
122
+
123
+ def try_to_jump
124
+ if @map.solid?(@x, @y + 1) then
125
+ @vy = -20
126
+ end
127
+ end
128
+
129
+ def collect_gems(gems)
130
+ # Same as in the tutorial game.
131
+ gems.reject! do |c|
132
+ (c.x - @x).abs < 50 and (c.y - @y).abs < 50
133
+ end
134
+ end
135
+ end
136
+
137
+ # Map class holds and draws tiles and gems.
138
+ class Map
139
+ attr_reader :width, :height, :gems
140
+
141
+ def initialize(filename)
142
+ # Load 60x60 tiles, 5px overlap in all four directions.
143
+ @tileset = Gosu::Image.load_tiles("media/tileset.png", 60, 60, :tileable => true)
144
+
145
+ gem_img = Gosu::Image.new("media/gem.png")
146
+ @gems = []
147
+
148
+ lines = File.readlines(filename).map { |line| line.chomp }
149
+ @height = lines.size
150
+ @width = lines[0].size
151
+ @tiles = Array.new(@width) do |x|
152
+ Array.new(@height) do |y|
153
+ case lines[y][x, 1]
154
+ when '"'
155
+ Tiles::Grass
156
+ when '#'
157
+ Tiles::Earth
158
+ when 'x'
159
+ @gems.push(CollectibleGem.new(gem_img, x * 50 + 25, y * 50 + 25))
160
+ nil
161
+ else
162
+ nil
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ def draw
169
+ # Very primitive drawing function:
170
+ # Draws all the tiles, some off-screen, some on-screen.
171
+ @height.times do |y|
172
+ @width.times do |x|
173
+ tile = @tiles[x][y]
174
+ if tile
175
+ # Draw the tile with an offset (tile images have some overlap)
176
+ # Scrolling is implemented here just as in the game objects.
177
+ @tileset[tile].draw(x * 50 - 5, y * 50 - 5, 0)
178
+ end
179
+ end
180
+ end
181
+ @gems.each { |c| c.draw }
182
+ end
183
+
184
+ # Solid at a given pixel position?
185
+ def solid?(x, y)
186
+ y < 0 || @tiles[x / 50][y / 50]
187
+ end
188
+ end
189
+
190
+ class CptnRuby < (Example rescue Gosu::Window)
191
+ def initialize
192
+ super WIDTH, HEIGHT
193
+
194
+ self.caption = "Cptn. Ruby"
195
+
196
+ @sky = Gosu::Image.new("media/space.png", :tileable => true)
197
+ @map = Map.new("media/cptn_ruby_map.txt")
198
+ @cptn = Player.new(@map, 400, 100)
199
+ # The scrolling position is stored as top left corner of the screen.
200
+ @camera_x = @camera_y = 0
201
+ end
202
+
203
+ def update
204
+ move_x = 0
205
+ move_x -= 5 if Gosu::button_down? Gosu::KbLeft
206
+ move_x += 5 if Gosu::button_down? Gosu::KbRight
207
+ @cptn.update(move_x)
208
+ @cptn.collect_gems(@map.gems)
209
+ # Scrolling follows player
210
+ @camera_x = [[@cptn.x - WIDTH / 2, 0].max, @map.width * 50 - WIDTH].min
211
+ @camera_y = [[@cptn.y - HEIGHT / 2, 0].max, @map.height * 50 - HEIGHT].min
212
+ end
213
+
214
+ def draw
215
+ @sky.draw 0, 0, 0
216
+ Gosu::translate(-@camera_x, -@camera_y) do
217
+ @map.draw
218
+ @cptn.draw
219
+ end
220
+ end
221
+
222
+ def button_down(id)
223
+ if id == Gosu::KbUp then
224
+ @cptn.try_to_jump
225
+ end
226
+ end
227
+ end
228
+
229
+ CptnRuby.new.show if __FILE__ == $0
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,25 @@
1
+ #....................................................#
2
+ #....................................................#
3
+ #.............xx......x.x............................#
4
+ #............x..x....................................#
5
+ #x....x...x..x.......#####..xxx....................x.#
6
+ #.x.........................xxx.........##.........x.#
7
+ #...............""..........###...##..........##.....#
8
+ #..##..###..##..##...................................#
9
+ #........................................xx........###
10
+ #.............................###....................#
11
+ ##....##.............................................#
12
+ #....................##....##......##....##....##....#
13
+ #.................................................x..#
14
+ #...x....##....##.......x...x.....................x..#
15
+ #.....x...............x...x...x...................x..#
16
+ #......x...##.....##.................................#
17
+ #.......x.........................................#..#
18
+ #...........##........#...#...#..#.......x...........#
19
+ #...#................................................#
20
+ #....."""".................x.......#..#####...###....#
21
+ #x....#......................##......................#
22
+ #"""""#.....#.....x..................#...............#
23
+ ##xxxx......#........................................#
24
+ ##xxxx...#####............."...""""".................#
25
+ ######"""#############################################
Binary file
Binary file
Binary file
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" clip-rule="evenodd" stroke-miterlimit="10" viewBox="0 0 850.39 637.80">
3
+ <desc>SVG generated by Lineform</desc>
4
+ <defs/>
5
+ <g>
6
+ <rect width="940.00" height="734.00" x="-25.50" y="-55.50" fill="#5FB7FF" stroke="#000000" stroke-width="2.20"/>
7
+ <path d="M 223.50 49.00 C 171.16 49.00 118.84 59.51 78.91 80.50 C -0.96 122.48 -0.96 190.52 78.91 232.50 C 134.24 261.59 213.37 270.50 283.34 259.28 C 350.32 290.78 452.18 289.47 516.06 255.19 C 582.65 219.45 582.65 161.55 516.06 125.81 C 482.95 108.04 439.59 99.12 396.19 99.03 C 388.26 92.46 378.99 86.23 368.09 80.50 C 328.16 59.51 275.84 49.00 223.50 49.00 Z M 223.50 49.00 " fill="#FFFFFF" stroke="#BFBFBF" stroke-width="6.00"/>
8
+ <path d="M 735.48 183.00 C 699.52 183.00 663.55 187.05 636.11 195.16 C 607.54 203.59 593.99 214.76 595.17 225.81 C 561.74 227.76 529.60 233.37 503.83 242.72 C 438.71 266.35 438.71 304.65 503.83 328.28 C 568.96 351.91 674.56 351.91 739.69 328.28 C 787.65 310.88 800.17 285.50 777.48 263.91 C 798.41 261.97 818.28 258.74 834.86 253.84 C 889.73 237.64 889.73 211.36 834.86 195.16 C 807.42 187.05 771.44 183.00 735.48 183.00 Z M 735.48 183.00 " fill="#FFFFFF" stroke="#BFBFBF" stroke-width="6.00"/>
9
+ </g>
10
+ </svg>
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,224 @@
1
+ # Encoding: UTF-8
2
+
3
+ # The tutorial game over a landscape rendered with OpenGL.
4
+ # Basically shows how arbitrary OpenGL calls can be put into
5
+ # the block given to Window#gl, and that Gosu Images can be
6
+ # used as textures using the gl_tex_info call.
7
+
8
+ require 'rubygems'
9
+ require 'gosu'
10
+ require 'gl'
11
+
12
+ WIDTH, HEIGHT = 600, 600
13
+
14
+ module ZOrder
15
+ Background, Stars, Player, UI = *0..3
16
+ end
17
+
18
+ # The only really new class here.
19
+ # Draws a scrolling, repeating texture with a randomized height map.
20
+ class GLBackground
21
+ # Height map size
22
+ POINTS_X = 7
23
+ POINTS_Y = 7
24
+ # Scrolling speed
25
+ SCROLLS_PER_STEP = 50
26
+
27
+ def initialize
28
+ @image = Gosu::Image.new("media/earth.png", :tileable => true)
29
+ @scrolls = 0
30
+ @height_map = Array.new(POINTS_Y) { Array.new(POINTS_X) { rand } }
31
+ end
32
+
33
+ def scroll
34
+ @scrolls += 1
35
+ if @scrolls == SCROLLS_PER_STEP then
36
+ @scrolls = 0
37
+ @height_map.shift
38
+ @height_map.push Array.new(POINTS_X) { rand }
39
+ end
40
+ end
41
+
42
+ def draw(z)
43
+ # gl will execute the given block in a clean OpenGL environment, then reset
44
+ # everything so Gosu's rendering can take place again.
45
+ Gosu::gl(z) { exec_gl }
46
+ end
47
+
48
+ private
49
+
50
+ include Gl
51
+
52
+ def exec_gl
53
+ glClearColor(0.0, 0.2, 0.5, 1.0)
54
+ glClearDepth(0)
55
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
56
+
57
+ # Get the name of the OpenGL texture the Image resides on, and the
58
+ # u/v coordinates of the rect it occupies.
59
+ # gl_tex_info can return nil if the image was too large to fit onto
60
+ # a single OpenGL texture and was internally split up.
61
+ info = @image.gl_tex_info
62
+ return unless info
63
+
64
+ # Pretty straightforward OpenGL code.
65
+
66
+ glDepthFunc(GL_GEQUAL)
67
+ glEnable(GL_DEPTH_TEST)
68
+ glEnable(GL_BLEND)
69
+
70
+ glMatrixMode(GL_PROJECTION)
71
+ glLoadIdentity
72
+ glFrustum(-0.10, 0.10, -0.075, 0.075, 1, 100)
73
+
74
+ glMatrixMode(GL_MODELVIEW)
75
+ glLoadIdentity
76
+ glTranslate(0, 0, -4)
77
+
78
+ glEnable(GL_TEXTURE_2D)
79
+ glBindTexture(GL_TEXTURE_2D, info.tex_name)
80
+
81
+ offs_y = 1.0 * @scrolls / SCROLLS_PER_STEP
82
+
83
+ 0.upto(POINTS_Y - 2) do |y|
84
+ 0.upto(POINTS_X - 2) do |x|
85
+ glBegin(GL_TRIANGLE_STRIP)
86
+ z = @height_map[y][x]
87
+ glColor4d(1, 1, 1, z)
88
+ glTexCoord2d(info.left, info.top)
89
+ glVertex3d(-0.5 + (x - 0.0) / (POINTS_X-1), -0.5 + (y - offs_y - 0.0) / (POINTS_Y-2), z)
90
+
91
+ z = @height_map[y+1][x]
92
+ glColor4d(1, 1, 1, z)
93
+ glTexCoord2d(info.left, info.bottom)
94
+ glVertex3d(-0.5 + (x - 0.0) / (POINTS_X-1), -0.5 + (y - offs_y + 1.0) / (POINTS_Y-2), z)
95
+
96
+ z = @height_map[y][x + 1]
97
+ glColor4d(1, 1, 1, z)
98
+ glTexCoord2d(info.right, info.top)
99
+ glVertex3d(-0.5 + (x + 1.0) / (POINTS_X-1), -0.5 + (y - offs_y - 0.0) / (POINTS_Y-2), z)
100
+
101
+ z = @height_map[y+1][x + 1]
102
+ glColor4d(1, 1, 1, z)
103
+ glTexCoord2d(info.right, info.bottom)
104
+ glVertex3d(-0.5 + (x + 1.0) / (POINTS_X-1), -0.5 + (y - offs_y + 1.0) / (POINTS_Y-2), z)
105
+ glEnd
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ # Roughly adapted from the tutorial game. Always faces north.
112
+ class Player
113
+ Speed = 7
114
+
115
+ attr_reader :score
116
+
117
+ def initialize(x, y)
118
+ @image = Gosu::Image.new("media/starfighter.bmp")
119
+ @beep = Gosu::Sample.new("media/beep.wav")
120
+ @x, @y = x, y
121
+ @score = 0
122
+ end
123
+
124
+ def move_left
125
+ @x = [@x - Speed, 0].max
126
+ end
127
+
128
+ def move_right
129
+ @x = [@x + Speed, WIDTH].min
130
+ end
131
+
132
+ def accelerate
133
+ @y = [@y - Speed, 50].max
134
+ end
135
+
136
+ def brake
137
+ @y = [@y + Speed, HEIGHT].min
138
+ end
139
+
140
+ def draw
141
+ @image.draw(@x - @image.width / 2, @y - @image.height / 2, ZOrder::Player)
142
+ end
143
+
144
+ def collect_stars(stars)
145
+ stars.reject! do |star|
146
+ if Gosu::distance(@x, @y, star.x, star.y) < 35 then
147
+ @score += 10
148
+ @beep.play
149
+ true
150
+ else
151
+ false
152
+ end
153
+ end
154
+ end
155
+ end
156
+
157
+ # Also taken from the tutorial, but drawn with draw_rot and an increasing angle
158
+ # for extra rotation coolness!
159
+ class Star
160
+ attr_reader :x, :y
161
+
162
+ def initialize(animation)
163
+ @animation = animation
164
+ @color = Gosu::Color.new(0xff_000000)
165
+ @color.red = rand(255 - 40) + 40
166
+ @color.green = rand(255 - 40) + 40
167
+ @color.blue = rand(255 - 40) + 40
168
+ @x = rand * 800
169
+ @y = 0
170
+ end
171
+
172
+ def draw
173
+ img = @animation[Gosu::milliseconds / 100 % @animation.size];
174
+ img.draw_rot(@x, @y, ZOrder::Stars, @y, 0.5, 0.5, 1, 1, @color, :add)
175
+ end
176
+
177
+ def update
178
+ # Move towards bottom of screen
179
+ @y += 3
180
+ # Return false when out of screen (gets deleted then)
181
+ @y < 650
182
+ end
183
+ end
184
+
185
+ class OpenGLIntegration < (Example rescue Gosu::Window)
186
+ def initialize
187
+ super WIDTH, HEIGHT
188
+
189
+ self.caption = "OpenGL Integration"
190
+
191
+ @gl_background = GLBackground.new
192
+
193
+ @player = Player.new(400, 500)
194
+
195
+ @star_anim = Gosu::Image::load_tiles("media/star.png", 25, 25)
196
+ @stars = Array.new
197
+
198
+ @font = Gosu::Font.new(20)
199
+ end
200
+
201
+ def update
202
+ @player.move_left if Gosu::button_down? Gosu::KbLeft or Gosu::button_down? Gosu::GpLeft
203
+ @player.move_right if Gosu::button_down? Gosu::KbRight or Gosu::button_down? Gosu::GpRight
204
+ @player.accelerate if Gosu::button_down? Gosu::KbUp or Gosu::button_down? Gosu::GpUp
205
+ @player.brake if Gosu::button_down? Gosu::KbDown or Gosu::button_down? Gosu::GpDown
206
+
207
+ @player.collect_stars(@stars)
208
+
209
+ @stars.reject! { |star| !star.update }
210
+
211
+ @gl_background.scroll
212
+
213
+ @stars.push(Star.new(@star_anim)) if rand(20) == 0
214
+ end
215
+
216
+ def draw
217
+ @player.draw
218
+ @stars.each { |star| star.draw }
219
+ @font.draw("Score: #{@player.score}", 10, 10, ZOrder::UI, 1.0, 1.0, 0xff_ffff00)
220
+ @gl_background.draw(ZOrder::Background)
221
+ end
222
+ end
223
+
224
+ OpenGLIntegration.new.show if __FILE__ == $0