-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathstar_vader.rb
190 lines (171 loc) · 4.94 KB
/
star_vader.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
require 'gosu'
require_relative 'player'
require_relative 'enemy'
require_relative 'lazer'
require_relative 'explosion'
require_relative 'credit'
class StarVader < Gosu::Window
WIDTH = 800
HEIGHT = 600
ENEMY_FREQUENCY = 0.03
MAX_ENEMIES = 100
def initialize
super WIDTH, HEIGHT
self.caption = 'May the force be with you...'
@scene = :start
@background_image = Gosu::Image.new('images/start.png')
@start_music = Gosu::Song.new('sounds/black_vortex.mp3')
@start_music.play true
end
def initialize_game
@scene = :game
@background_image = Gosu::Image.new('images/background.png')
@game_music = Gosu::Song.new('sounds/phantom_from_space.mp3')
@game_music.play true
@explosion_sound = Gosu::Sample.new('sounds/explosion.mp3')
@lazer_sound = Gosu::Sample.new('sounds/tie_lazer.wav')
@player = Player.new(self)
@enemies = []
@lazers = []
@explosions = []
@enemies_appeared = 0
@enemies_destroyed = 0
end
def initialize_end(fate)
@scene = :end
@background_image = Gosu::Image.new('images/end.png')
@game_music = Gosu::Song.new('sounds/despair_and_triumph.mp3')
@game_music.play true
case fate
when :count_reached
@message = "You vanquished #{@enemies_destroyed} rebels!"
escaped = (MAX_ENEMIES - @enemies_destroyed)
@message2 = "but... #{escaped} escaped your clutches."
when :hit_by_enemy
@message = 'The rebel scum collided with your vessel.'
@message2 = "You ended #{@enemies_destroyed} rebels before this fate."
when :out_of_bounds
@message = 'You fled the battle in preparation of your revenge.'
@message2 = "You vanquished #{@enemies_destroyed} rebels anyway."
end
@bottom_message = "Press 'p' to play again, or 'q' to quit."
@message_font = Gosu::Font.new(28, name: 'Star Jedi')
@credits = []
y = 700
File.open('credits.txt').each do |line|
@credits.push Credit.new(self, line.chomp, 100, y)
y += 30
end
end
def draw
case @scene
when :start
draw_start
when :game
draw_game
when :end
draw_end
end
end
def draw_start
@background_image.draw 0, 0, 0
end
def draw_game
@background_image.draw 0, 0, 0
@player.draw
@enemies.each(&:draw)
@lazers.each(&:draw)
@explosions.each(&:draw)
end
def draw_end
@background_image.draw 0, 0, 0
clip_to(50, 140, 700, 360) do
@credits.each(&:draw)
end
draw_line 0, 140, Gosu::Color::RED, WIDTH, 140, Gosu::Color::RED
@message_font.draw @message, 40, 40, 1, 1, 1, Gosu::Color::YELLOW
@message_font.draw @message2, 40, 75, 1, 1, 1, Gosu::Color::YELLOW
draw_line 0, 500, Gosu::Color::RED, WIDTH, 500, Gosu::Color::RED
@message_font.draw @bottom_message, 180, 540, 1, 1, 1, Gosu::Color::WHITE
end
def update
case @scene
when :game
update_game
when :end
update_end
end
end
def update_game
@player.turn_left if button_down? Gosu::KbLeft
@player.turn_right if button_down? Gosu::KbRight
@player.accelerate if button_down? Gosu::KbUp
@player.move
if rand < ENEMY_FREQUENCY
@enemies.push Enemy.new(self)
@enemies_appeared += 1
end
@enemies.each(&:move)
@lazers.each(&:move)
@enemies.dup.each do |enemy|
@lazers.dup.each do |lazer|
distance = Gosu.distance(enemy.x, enemy.y, lazer.x, lazer.y)
if distance < enemy.radius + lazer.radius
@enemies.delete enemy
@lazers.delete lazer
@explosions.push Explosion.new(self, enemy.x, enemy.y)
@explosion_sound.play
@enemies_destroyed += 1
end
end
end
@enemies.dup.each do |enemy|
@enemies.delete enemy if enemy.y > HEIGHT + enemy.radius
end
@explosions.dup.each do |explosion|
@explosions.delete explosion if explosion.finished?
end
@lazers.dup.each do |lazer|
@lazers.delete lazer unless lazer.onscreen?
end
initialize_end(:count_reached) if @enemies_appeared > MAX_ENEMIES
@enemies.each do |enemy|
distance = Gosu.distance enemy.x, enemy.y, @player.x, @player.y
initialize_end(:hit_by_enemy) if distance < @player.radius + enemy.radius
end
initialize_end(:out_of_bounds) if @player.y < -@player.radius
end
def update_end
@credits.each(&:move)
@credits.each(&:reset) if @credits.last.y < 150
end
def button_down(key)
case @scene
when :start
button_down_start(key)
when :game
button_down_game(key)
when :end
button_down_end(key)
end
end
def button_down_start(_key)
initialize_game
end
def button_down_game(key)
if key == Gosu::KbSpace
@lazers.push Lazer.new(self, @player.x, @player.y, @player.angle)
@lazer_sound.play
end
end
def button_down_end(key)
case key
when Gosu::KbQ
close
when Gosu::KbP
initialize_game
end
end
end
window = StarVader.new
window.show