gosu-examples 1.0.4 → 1.0.7

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 (40) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +1 -1
  3. data/bin/gosu-examples +20 -22
  4. data/examples/chipmunk_and_rmagick.rb +25 -28
  5. data/examples/chipmunk_integration.rb +45 -48
  6. data/examples/cptn_ruby.rb +23 -26
  7. data/examples/opengl_integration.rb +61 -62
  8. data/examples/rmagick_integration.rb +87 -88
  9. data/examples/text_input.rb +157 -0
  10. data/examples/tutorial.rb +23 -26
  11. data/examples/welcome.rb +20 -23
  12. data/lib/gosu-examples/example.rb +34 -13
  13. data/lib/gosu-examples/sidebar.rb +16 -16
  14. metadata +10 -36
  15. data/examples/media/BrokenPNG.png +0 -0
  16. data/examples/media/Cursor.png +0 -0
  17. data/examples/media/JingleBells.mp3 +0 -0
  18. data/examples/media/JingleBells.ogg +0 -0
  19. data/examples/media/Loop.wav +0 -0
  20. data/examples/media/Sample.wav +0 -0
  21. data/examples/media/SquareTexture.png +0 -0
  22. data/examples/media/Wallpaper.png +0 -0
  23. data/examples/media/WallpaperXXL.png +0 -0
  24. data/examples/media/WhiteAlpha.png +0 -0
  25. data/examples/media/audio_formats/aiff_32bit_float.aiff +0 -0
  26. data/examples/media/audio_formats/au_16bit_pcm.au +0 -0
  27. data/examples/media/audio_formats/caf_be_16bit_44khz.caf +0 -0
  28. data/examples/media/audio_formats/caf_le_16bit_44khz.caf +0 -0
  29. data/examples/media/audio_formats/caf_le_8bit_44khz.caf +0 -0
  30. data/examples/media/audio_formats/general_midi.mid +0 -0
  31. data/examples/media/audio_formats/impulse_tracker.it +0 -0
  32. data/examples/media/audio_formats/mp3_128k_stereo.mp3 +0 -0
  33. data/examples/media/audio_formats/mp3_avg_96kbit_jointstereo.mp3 +0 -0
  34. data/examples/media/audio_formats/ogg_vorbis.ogg +0 -0
  35. data/examples/media/audio_formats/wav_16bit_pcm.wav +0 -0
  36. data/examples/media/audio_formats/wav_32bit_pcm.wav +0 -0
  37. data/examples/media/audio_formats/wav_4bit_ms_adpcm.wav +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/vera.ttf +0 -0
@@ -1,13 +1,12 @@
1
- # Encoding: UTF-8
2
-
3
1
  # The tutorial game over a landscape rendered with OpenGL.
4
2
  # Basically shows how arbitrary OpenGL calls can be put into
5
3
  # the block given to Window#gl, and that Gosu Images can be
6
4
  # used as textures using the gl_tex_info call.
7
5
 
8
- require 'rubygems'
9
- require 'gosu'
10
- require 'gl'
6
+ require "gosu"
7
+ require "opengl"
8
+
9
+ OpenGL.load_lib
11
10
 
12
11
  WIDTH, HEIGHT = 640, 480
13
12
 
@@ -25,11 +24,11 @@ class GLBackground
25
24
  SCROLLS_PER_STEP = 50
26
25
 
27
26
  def initialize
28
- @image = Gosu::Image.new("media/earth.png", :tileable => true)
27
+ @image = Gosu::Image.new("media/earth.png", tileable: true)
29
28
  @scrolls = 0
30
29
  @height_map = Array.new(POINTS_Y) { Array.new(POINTS_X) { rand } }
31
30
  end
32
-
31
+
33
32
  def scroll
34
33
  @scrolls += 1
35
34
  if @scrolls == SCROLLS_PER_STEP
@@ -38,22 +37,22 @@ class GLBackground
38
37
  @height_map.push Array.new(POINTS_X) { rand }
39
38
  end
40
39
  end
41
-
40
+
42
41
  def draw(z)
43
42
  # gl will execute the given block in a clean OpenGL environment, then reset
44
43
  # everything so Gosu's rendering can take place again.
45
44
  Gosu.gl(z) { exec_gl }
46
45
  end
47
-
46
+
48
47
  private
49
-
50
- include Gl
51
-
48
+
49
+ include OpenGL
50
+
52
51
  def exec_gl
53
52
  glClearColor(0.0, 0.2, 0.5, 1.0)
54
53
  glClearDepth(0)
55
54
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
56
-
55
+
57
56
  # Get the name of the OpenGL texture the Image resides on, and the
58
57
  # u/v coordinates of the rect it occupies.
59
58
  # gl_tex_info can return nil if the image was too large to fit onto
@@ -62,7 +61,7 @@ class GLBackground
62
61
  return unless info
63
62
 
64
63
  # Pretty straightforward OpenGL code.
65
-
64
+
66
65
  glDepthFunc(GL_GEQUAL)
67
66
  glEnable(GL_DEPTH_TEST)
68
67
  glEnable(GL_BLEND)
@@ -73,35 +72,35 @@ class GLBackground
73
72
 
74
73
  glMatrixMode(GL_MODELVIEW)
75
74
  glLoadIdentity
76
- glTranslate(0, 0, -4)
77
-
75
+ glTranslatef(0, 0, -4)
76
+
78
77
  glEnable(GL_TEXTURE_2D)
79
78
  glBindTexture(GL_TEXTURE_2D, info.tex_name)
80
-
79
+
81
80
  offs_y = 1.0 * @scrolls / SCROLLS_PER_STEP
82
-
81
+
83
82
  0.upto(POINTS_Y - 2) do |y|
84
83
  0.upto(POINTS_X - 2) do |x|
85
84
  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)
85
+ z = @height_map[y][x]
86
+ glColor4d(1, 1, 1, z)
87
+ glTexCoord2d(info.left, info.top)
88
+ glVertex3d(-0.5 + (x - 0.0) / (POINTS_X - 1), -0.5 + (y - offs_y - 0.0) / (POINTS_Y - 2), z)
89
+
90
+ z = @height_map[y + 1][x]
91
+ glColor4d(1, 1, 1, z)
92
+ glTexCoord2d(info.left, info.bottom)
93
+ glVertex3d(-0.5 + (x - 0.0) / (POINTS_X - 1), -0.5 + (y - offs_y + 1.0) / (POINTS_Y - 2), z)
94
+
95
+ z = @height_map[y][x + 1]
96
+ glColor4d(1, 1, 1, z)
97
+ glTexCoord2d(info.right, info.top)
98
+ glVertex3d(-0.5 + (x + 1.0) / (POINTS_X - 1), -0.5 + (y - offs_y - 0.0) / (POINTS_Y - 2), z)
99
+
100
+ z = @height_map[y + 1][x + 1]
101
+ glColor4d(1, 1, 1, z)
102
+ glTexCoord2d(info.right, info.bottom)
103
+ glVertex3d(-0.5 + (x + 1.0) / (POINTS_X - 1), -0.5 + (y - offs_y + 1.0) / (POINTS_Y - 2), z)
105
104
  glEnd
106
105
  end
107
106
  end
@@ -111,7 +110,7 @@ end
111
110
  # Roughly adapted from the tutorial game. Always faces north.
112
111
  class Player
113
112
  Speed = 7
114
-
113
+
115
114
  attr_reader :score
116
115
 
117
116
  def initialize(x, y)
@@ -124,23 +123,23 @@ class Player
124
123
  def move_left
125
124
  @x = [@x - Speed, 0].max
126
125
  end
127
-
126
+
128
127
  def move_right
129
128
  @x = [@x + Speed, WIDTH].min
130
129
  end
131
-
130
+
132
131
  def accelerate
133
132
  @y = [@y - Speed, 50].max
134
133
  end
135
-
134
+
136
135
  def brake
137
136
  @y = [@y + Speed, HEIGHT].min
138
137
  end
139
-
138
+
140
139
  def draw
141
140
  @image.draw(@x - @image.width / 2, @y - @image.height / 2, ZOrder::Player)
142
141
  end
143
-
142
+
144
143
  def collect_stars(stars)
145
144
  stars.reject! do |star|
146
145
  if Gosu.distance(@x, @y, star.x, star.y) < 35
@@ -158,7 +157,7 @@ end
158
157
  # for extra rotation coolness!
159
158
  class Star
160
159
  attr_reader :x, :y
161
-
160
+
162
161
  def initialize(animation)
163
162
  @animation = animation
164
163
  @color = Gosu::Color.new(0xff_000000)
@@ -169,11 +168,11 @@ class Star
169
168
  @y = 0
170
169
  end
171
170
 
172
- def draw
173
- img = @animation[Gosu.milliseconds / 100 % @animation.size];
171
+ def draw
172
+ img = @animation[Gosu.milliseconds / 100 % @animation.size]
174
173
  img.draw_rot(@x, @y, ZOrder::Stars, @y, 0.5, 0.5, 1, 1, @color, :add)
175
174
  end
176
-
175
+
177
176
  def update
178
177
  # Move towards bottom of screen
179
178
  @y += 3
@@ -185,40 +184,40 @@ end
185
184
  class OpenGLIntegration < (Example rescue Gosu::Window)
186
185
  def initialize
187
186
  super WIDTH, HEIGHT
188
-
187
+
189
188
  self.caption = "OpenGL Integration"
190
-
189
+
191
190
  @gl_background = GLBackground.new
192
-
191
+
193
192
  @player = Player.new(400, 500)
194
-
193
+
195
194
  @star_anim = Gosu::Image::load_tiles("media/star.png", 25, 25)
196
195
  @stars = Array.new
197
-
196
+
198
197
  @font = Gosu::Font.new(20)
199
198
  end
200
-
199
+
201
200
  def update
202
- @player.move_left if Gosu.button_down? Gosu::KB_LEFT or Gosu.button_down? Gosu::GP_LEFT
201
+ @player.move_left if Gosu.button_down? Gosu::KB_LEFT or Gosu.button_down? Gosu::GP_LEFT
203
202
  @player.move_right if Gosu.button_down? Gosu::KB_RIGHT or Gosu.button_down? Gosu::GP_RIGHT
204
- @player.accelerate if Gosu.button_down? Gosu::KB_UP or Gosu.button_down? Gosu::GP_UP
205
- @player.brake if Gosu.button_down? Gosu::KB_DOWN or Gosu.button_down? Gosu::GP_DOWN
206
-
203
+ @player.accelerate if Gosu.button_down? Gosu::KB_UP or Gosu.button_down? Gosu::GP_UP
204
+ @player.brake if Gosu.button_down? Gosu::KB_DOWN or Gosu.button_down? Gosu::GP_DOWN
205
+
207
206
  @player.collect_stars(@stars)
208
-
207
+
209
208
  @stars.reject! { |star| !star.update }
210
-
209
+
211
210
  @gl_background.scroll
212
-
211
+
213
212
  @stars.push(Star.new(@star_anim)) if rand(20) == 0
214
213
  end
215
214
 
216
215
  def draw
217
216
  @player.draw
218
217
  @stars.each { |star| star.draw }
219
- @font.draw("Score: #{@player.score}", 10, 10, ZOrder::UI, 1.0, 1.0, 0xff_ffff00)
218
+ @font.draw_text("Score: #{@player.score}", 10, 10, ZOrder::UI, 1.0, 1.0, 0xff_ffff00)
220
219
  @gl_background.draw(ZOrder::Background)
221
220
  end
222
221
  end
223
222
 
224
- OpenGLIntegration.new.show if __FILE__ == $0
223
+ OpenGLIntegration.new.show if __FILE__ == $0
@@ -1,6 +1,4 @@
1
- # Encoding: UTF-8
2
-
3
- # A (too) simple Gorilla-style shooter for two players.
1
+ # A simple Gorilla-style shooter for two players.
4
2
  # Shows how Gosu and RMagick can be used together to generate a map, implement
5
3
  # a dynamic landscape and generally look great.
6
4
  # Also shows a very minimal, yet effective way of designing a game's object system.
@@ -13,13 +11,12 @@
13
11
  # * The look of dead soldiers is, err, by accident. Soldier.png needs to be
14
12
  # designed in a less obfuscated way :)
15
13
 
16
- require 'rubygems'
17
- require 'gosu'
18
- require 'rmagick'
14
+ require "gosu"
15
+ require "rmagick"
19
16
 
20
17
  WIDTH, HEIGHT = 640, 480
21
18
 
22
- NULL_PIXEL = Magick::Pixel.from_color('none')
19
+ NULL_PIXEL = Magick::Pixel.from_color("none")
23
20
 
24
21
  # The class for this game's map.
25
22
  # Design:
@@ -35,16 +32,16 @@ class Map
35
32
  # Loading SVG files isn't possible with Gosu, so say wow!
36
33
  # (Seems to take a while though)
37
34
  sky = Magick::Image.read("media/landscape.svg").first
38
- @sky = Gosu::Image.new(sky, :tileable => true)
39
-
35
+ @sky = Gosu::Image.new(sky, tileable: true)
36
+
40
37
  # Create the map an stores the RMagick image in @image
41
38
  create_rmagick_map
42
-
39
+
43
40
  # Copy the RMagick Image to a Gosu Image (still unchanged)
44
- @gosu_image = Gosu::Image.new(@image, :tileable => true)
41
+ @gosu_image = Gosu::Image.new(@image, tileable: true)
45
42
  end
46
-
47
- def solid? x, y
43
+
44
+ def solid?(x, y)
48
45
  # Map is open at the top.
49
46
  return false if y < 0
50
47
  # Map is closed on all other sides.
@@ -52,7 +49,7 @@ class Map
52
49
  # Inside of the map, determine solidity from the map image.
53
50
  @image.pixel_color(x, y) != NULL_PIXEL
54
51
  end
55
-
52
+
56
53
  def draw
57
54
  # Sky background.
58
55
  @sky.draw 0, 0, 0
@@ -64,43 +61,43 @@ class Map
64
61
  RADIUS = 25
65
62
  # Radius of a crater, Shadow included.
66
63
  SH_RADIUS = 45
67
-
64
+
68
65
  # Create the crater image (basically a circle shape that is used to erase
69
66
  # parts of the map) and the crater shadow image.
70
67
  CRATER_IMAGE = begin
71
- crater = Magick::Image.new(2 * RADIUS, 2 * RADIUS) { self.background_color = 'none' }
72
- gc = Magick::Draw.new
73
- gc.fill('black').circle(RADIUS, RADIUS, RADIUS, 0)
74
- gc.draw crater
75
- crater
76
- end
68
+ crater = Magick::Image.new(2 * RADIUS, 2 * RADIUS) { self.background_color = "none" }
69
+ gc = Magick::Draw.new
70
+ gc.fill("black").circle(RADIUS, RADIUS, RADIUS, 0)
71
+ gc.draw crater
72
+ crater
73
+ end
77
74
  CRATER_SHADOW = CRATER_IMAGE.shadow(0, 0, (SH_RADIUS - RADIUS) / 2, 1)
78
-
79
- def blast x, y
75
+
76
+ def blast(x, y)
80
77
  # Draw the shadow (twice for more intensity), then erase a circle from the map.
81
78
  @image.composite! CRATER_SHADOW, x - SH_RADIUS, y - SH_RADIUS, Magick::AtopCompositeOp
82
79
  @image.composite! CRATER_SHADOW, x - SH_RADIUS, y - SH_RADIUS, Magick::AtopCompositeOp
83
- @image.composite! CRATER_IMAGE, x - RADIUS, y - RADIUS, Magick::DstOutCompositeOp
84
-
80
+ @image.composite! CRATER_IMAGE, x - RADIUS, y - RADIUS, Magick::DstOutCompositeOp
81
+
85
82
  # Isolate the affected portion of the RMagick image.
86
83
  dirty_portion = @image.crop(x - SH_RADIUS, y - SH_RADIUS, SH_RADIUS * 2, SH_RADIUS * 2)
87
84
  # Overwrite this part of the Gosu image. If the crater begins outside of the map, still
88
85
  # just update the inner part.
89
86
  @gosu_image.insert dirty_portion, [x - SH_RADIUS, 0].max, [y - SH_RADIUS, 0].max
90
87
  end
91
-
88
+
92
89
  private
93
-
90
+
94
91
  def create_rmagick_map
95
92
  # This is the one large RMagick image that represents the map.
96
- @image = Magick::Image.new(WIDTH, HEIGHT) { self.background_color = 'none' }
97
-
93
+ @image = Magick::Image.new(WIDTH, HEIGHT) { self.background_color = "none" }
94
+
98
95
  # Set up a Draw object that fills with an earth texture.
99
- earth = Magick::Image.read('media/earth.png').first.resize(1.5)
96
+ earth = Magick::Image.read("media/earth.png").first.resize(1.5)
100
97
  gc = Magick::Draw.new
101
- gc.pattern('earth', 0, 0, earth.columns, earth.rows) { gc.composite(0, 0, 0, 0, earth) }
102
- gc.fill('earth')
103
- gc.stroke('#603000').stroke_width(1.5)
98
+ gc.pattern("earth", 0, 0, earth.columns, earth.rows) { gc.composite(0, 0, 0, 0, earth) }
99
+ gc.fill("earth")
100
+ gc.stroke("#603000").stroke_width(1.5)
104
101
  # Draw a smooth bezier island onto the map!
105
102
  polypoints = [0, HEIGHT]
106
103
  0.upto(8) do |x|
@@ -109,20 +106,20 @@ class Map
109
106
  polypoints += [WIDTH, HEIGHT]
110
107
  gc.bezier(*polypoints)
111
108
  gc.draw(@image)
112
-
109
+
113
110
  # Create a bright-dark gradient fill, an image from it and change the map's
114
111
  # brightness with it.
115
- fill = Magick::GradientFill.new(0, HEIGHT * 0.4, WIDTH, HEIGHT * 0.4, '#fff', '#666')
112
+ fill = Magick::GradientFill.new(0, HEIGHT * 0.4, WIDTH, HEIGHT * 0.4, "#fff", "#666")
116
113
  gradient = Magick::Image.new(WIDTH, HEIGHT, fill)
117
114
  gradient = @image.composite(gradient, 0, 0, Magick::InCompositeOp)
118
115
  @image.composite!(gradient, 0, 0, Magick::MultiplyCompositeOp)
119
116
 
120
117
  # Finally, place the star in the middle of the map, just onto the ground.
121
- star = Magick::Image.read('media/large_star.png').first
118
+ star = Magick::Image.read("media/large_star.png").first
122
119
  star_y = 0
123
120
  star_y += 20 until solid?(WIDTH / 2, star_y)
124
121
  @image.composite!(star, (WIDTH - star.columns) / 2, star_y - star.rows * 0.85,
125
- Magick::DstOverCompositeOp)
122
+ Magick::DstOverCompositeOp)
126
123
  end
127
124
  end
128
125
 
@@ -132,29 +129,29 @@ end
132
129
  # draw: Draws the object (obviously)
133
130
  # update: Moves the object etc., returns false if the object is to be deleted
134
131
  # hit_by?(missile): Returns true if an object is hit by the missile, causing
135
- # it to explode on this object.
132
+ # it to explode on this object.
136
133
 
137
134
  class Player
138
135
  # Magic numbers considered harmful! This is the height of the
139
136
  # player as used for collision detection.
140
137
  HEIGHT = 14
141
-
138
+
142
139
  attr_reader :x, :y, :dead
143
-
140
+
144
141
  def initialize(window, x, y, color)
145
142
  # Only load the images once for all instances of this class.
146
143
  @@images ||= Gosu::Image.load_tiles("media/soldier.png", 40, 50)
147
-
144
+
148
145
  @window, @x, @y, @color = window, x, y, color
149
146
  @vy = 0
150
-
147
+
151
148
  # -1: left, +1: right
152
149
  @dir = -1
153
150
 
154
151
  # Aiming angle.
155
152
  @angle = 90
156
153
  end
157
-
154
+
158
155
  def draw
159
156
  if dead
160
157
  # Poor, broken soldier.
@@ -169,7 +166,7 @@ class Player
169
166
  # No: Stand around (boring).
170
167
  frame = 0
171
168
  end
172
-
169
+
173
170
  # Draw feet, then chest.
174
171
  @@images[frame].draw(x - 10 * @dir, y - 20, 0, @dir * 0.5, 0.5, @color)
175
172
  angle = @angle
@@ -177,14 +174,14 @@ class Player
177
174
  @@images[2].draw_rot(x, y - 5, 0, angle, 1, 0.5, 0.5, @dir * 0.5, @color)
178
175
  end
179
176
  end
180
-
177
+
181
178
  def update
182
179
  # First, assume that no walking happened this frame.
183
180
  @show_walk_anim = false
184
-
181
+
185
182
  # Gravity.
186
183
  @vy += 1
187
-
184
+
188
185
  if @vy > 1
189
186
  # Move upwards until hitting something.
190
187
  @vy.times do
@@ -206,19 +203,19 @@ class Player
206
203
  end
207
204
  end
208
205
  end
209
-
206
+
210
207
  # Soldiers are never deleted (they may die, but that is a different thing).
211
208
  true
212
209
  end
213
-
210
+
214
211
  def aim_up
215
212
  @angle -= 2 unless @angle < 10
216
213
  end
217
-
214
+
218
215
  def aim_down
219
216
  @angle += 2 unless @angle > 170
220
217
  end
221
-
218
+
222
219
  def try_walk(dir)
223
220
  @show_walk_anim = true
224
221
  @dir = dir
@@ -226,27 +223,27 @@ class Player
226
223
  2.times { @y -= 1 unless @window.map.solid?(x, y - HEIGHT - 1) }
227
224
  # Now move into the desired direction.
228
225
  @x += dir unless @window.map.solid?(x + dir, y) or
229
- @window.map.solid?(x + dir, y - HEIGHT)
226
+ @window.map.solid?(x + dir, y - HEIGHT)
230
227
  # To make up for unnecessary movement upwards, sink downward again.
231
228
  2.times { @y += 1 unless @window.map.solid?(x, y + 1) }
232
229
  end
233
-
230
+
234
231
  def try_jump
235
232
  @vy = -12 if @window.map.solid?(x, y + 1)
236
233
  end
237
-
234
+
238
235
  def shoot
239
236
  @window.objects << Missile.new(@window, x + 10 * @dir, y - 10, @angle * @dir)
240
237
  end
241
-
242
- def hit_by? missile
238
+
239
+ def hit_by?(missile)
243
240
  if Gosu.distance(missile.x, missile.y, x, y) < 30
244
241
  # Was hit :(
245
242
  @dead = true
246
243
  return true
247
244
  else
248
245
  return false
249
- end
246
+ end
250
247
  end
251
248
  end
252
249
 
@@ -257,14 +254,14 @@ class Missile
257
254
 
258
255
  # All missile instances use the same sound.
259
256
  EXPLOSION = Gosu::Sample.new("media/explosion.wav")
260
-
257
+
261
258
  def initialize(window, x, y, angle)
262
259
  # Horizontal/vertical velocity.
263
260
  @vx, @vy = Gosu.offset_x(angle, 20).to_i, Gosu.offset_y(angle, 20).to_i
264
-
261
+
265
262
  @window, @x, @y = window, x + @vx, y + @vy
266
263
  end
267
-
264
+
268
265
  def update
269
266
  # Movement, gravity
270
267
  @x += @vx
@@ -282,12 +279,12 @@ class Missile
282
279
  return true
283
280
  end
284
281
  end
285
-
282
+
286
283
  def draw
287
284
  # Just draw a small rectangle.
288
- Gosu.draw_rect x-2, y-2, 4, 4, 0xff_800000
285
+ Gosu.draw_rect x - 2, y - 2, 4, 4, 0xff_800000
289
286
  end
290
-
287
+
291
288
  def hit_by?(missile)
292
289
  # Missiles can't be hit by other missiles!
293
290
  false
@@ -299,25 +296,25 @@ end
299
296
  class Particle
300
297
  def initialize(window, x, y)
301
298
  # All Particle instances use the same image
302
- @@image ||= Gosu::Image.new('media/smoke.png')
303
-
299
+ @@image ||= Gosu::Image.new("media/smoke.png")
300
+
304
301
  @x, @y = x, y
305
302
  @color = Gosu::Color.new(255, 255, 255, 255)
306
303
  end
307
-
304
+
308
305
  def update
309
306
  @y -= 5
310
307
  @x = @x - 1 + rand(3)
311
308
  @color.alpha -= 5
312
-
309
+
313
310
  # Remove if faded completely.
314
311
  @color.alpha > 0
315
312
  end
316
-
313
+
317
314
  def draw
318
315
  @@image.draw(@x - 25, @y - 25, 0, 1, 1, @color)
319
316
  end
320
-
317
+
321
318
  def hit_by?(missile)
322
319
  # Smoke can't be hit!
323
320
  false
@@ -329,10 +326,10 @@ end
329
326
 
330
327
  class RMagickIntegration < (Example rescue Gosu::Window)
331
328
  attr_reader :map, :objects
332
-
329
+
333
330
  def initialize
334
331
  super WIDTH, HEIGHT
335
-
332
+
336
333
  self.caption = "RMagick Integration Demo"
337
334
 
338
335
  # Texts to display in the appropriate situations.
@@ -340,65 +337,67 @@ class RMagickIntegration < (Example rescue Gosu::Window)
340
337
  @player_won_messages = []
341
338
  2.times do |plr|
342
339
  @player_instructions << Gosu::Image.from_text(
343
- "It is the #{ plr == 0 ? 'green' : 'red' } toy soldier's turn.\n" +
340
+ "It is the #{plr == 0 ? "green" : "red"} toy soldier's turn.\n" +
344
341
  "(Arrow keys to walk and aim, Return to jump, Space to shoot)",
345
- 30, :width => width, :align => :center)
342
+ 30, width: width, align: :center,
343
+ )
346
344
  @player_won_messages << Gosu::Image.from_text(
347
- "The #{ plr == 0 ? 'green' : 'red' } toy soldier has won!",
348
- 30, :width => width, :align => :center)
345
+ "The #{plr == 0 ? "green" : "red"} toy soldier has won!",
346
+ 30, width: width, align: :center,
347
+ )
349
348
  end
350
349
 
351
350
  # Create everything!
352
351
  @map = Map.new
353
352
  @players = [Player.new(self, 100, 40, 0xff_308000), Player.new(self, WIDTH - 100, 40, 0xff_803000)]
354
353
  @objects = @players.dup
355
-
354
+
356
355
  # Let any player start.
357
356
  @current_player = rand(2)
358
357
  # Currently not waiting for a missile to hit something.
359
358
  @waiting = false
360
359
  end
361
-
360
+
362
361
  def draw
363
362
  # Draw the main game.
364
363
  @map.draw
365
364
  @objects.each { |o| o.draw }
366
-
365
+
367
366
  # If any text should be displayed, draw it - and add a nice black border around it
368
367
  # by drawing it four times, with a little offset in each direction.
369
-
368
+
370
369
  cur_text = @player_instructions[@current_player] if not @waiting
371
370
  cur_text = @player_won_messages[1 - @current_player] if @players[@current_player].dead
372
-
371
+
373
372
  if cur_text
374
373
  x, y = 0, 30
375
374
  cur_text.draw(x - 1, y, 0, 1, 1, 0xff_000000)
376
375
  cur_text.draw(x + 1, y, 0, 1, 1, 0xff_000000)
377
376
  cur_text.draw(x, y - 1, 0, 1, 1, 0xff_000000)
378
377
  cur_text.draw(x, y + 1, 0, 1, 1, 0xff_000000)
379
- cur_text.draw(x, y, 0, 1, 1, 0xff_ffffff)
378
+ cur_text.draw(x, y, 0, 1, 1, 0xff_ffffff)
380
379
  end
381
380
  end
382
-
381
+
383
382
  def update
384
383
  # if waiting for the next player's turn, continue to do so until the missile has
385
384
  # hit something.
386
385
  @waiting &&= !@objects.grep(Missile).empty?
387
-
388
- # Remove all objects whose update method returns false.
386
+
387
+ # Remove all objects whose update method returns false.
389
388
  @objects.reject! { |o| o.update == false }
390
389
 
391
390
  # If it's a player's turn, forward controls.
392
391
  if not @waiting and not @players[@current_player].dead
393
392
  player = @players[@current_player]
394
- player.aim_up if Gosu.button_down? Gosu::KB_UP
395
- player.aim_down if Gosu.button_down? Gosu::KB_DOWN
393
+ player.aim_up if Gosu.button_down? Gosu::KB_UP
394
+ player.aim_down if Gosu.button_down? Gosu::KB_DOWN
396
395
  player.try_walk(-1) if Gosu.button_down? Gosu::KB_LEFT
397
396
  player.try_walk(+1) if Gosu.button_down? Gosu::KB_RIGHT
398
- player.try_jump if Gosu.button_down? Gosu::KB_RETURN
397
+ player.try_jump if Gosu.button_down? Gosu::KB_RETURN
399
398
  end
400
399
  end
401
-
400
+
402
401
  def button_down(id)
403
402
  if id == Gosu::KB_SPACE and not @waiting and not @players[@current_player].dead
404
403
  # Shoot! This is handled in button_down because holding space shouldn't auto-fire.