gosu-examples 1.0.4 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
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.