1. `import` `pygame, time, random`
3. `# Для работы со шрифтами:`
4. `pygame.font.init()`
6. `# Чтобы проигрывать музыку:`
7. `pygame.mixer.init()`
9. `# Параметры окна`
10. `WIDTH, HEIGHT` `=` `1024``,` `768`
11. `WIN` `=` `pygame.display.set_mode((WIDTH, HEIGHT))`
12. `pygame.display.set_caption(``"Вторжение пришельцев"``)`
14. `# Корабль игрока`
15. `PLAYER_SHIP` `=` `pygame.image.load(``"img/ship.png"``)`
17. `# Пули`
18. `LASER` `=` `pygame.image.load(``"img/pixel_laser.png"``)`
20. `# Задний фон`
21. `BG` `=` `pygame.transform.scale(pygame.image.load(``"img/bg.jpg"``), (WIDTH, HEIGHT))`
23. `class` `Laser:`
24. `# Создаём пулю и задаём её логику`
25. `def` `__init__(``self``, x, y, img):`
26. `self``.x` `=` `x``-``15`
27. `self``.y` `=` `y``-``20`
28. `self``.img` `=` `img`
29. `self``.mask` `=` `pygame.mask.from_surface(``self``.img)`
31. `def` `draw(``self``, window):`
32. `window.blit(``self``.img, (``self``.x,` `self``.y))`
34. `def` `move(``self``, vel):`
35. `self``.y` `+``=` `vel`
37. `def` `off_screen(``self``, height):`
38. `return` `not``(``self``.y <``=` `height` `and` `self``.y >``=` `0``)`
40. `def` `collision(``self``, obj):`
41. `return` `collide(``self``, obj)`
43. `class` `Ship:`
44. `# Скорость стрельбы`
45. `COOLDOWN` `=` `20`
47. `# Настройки корабля`
48. `def` `__init__(``self``, x, y, health``=``100``):`
49. `self``.x` `=` `x`
50. `self``.y` `=` `y`
51. `self``.health` `=` `health`
52. `self``.ship_img` `=` `None`
53. `self``.laser_img` `=` `None`
54. `self``.lasers` `=` `[]`
55. `self``.cool_down_counter` `=` `0`
57. `def` `draw(``self``, window):`
58. `window.blit(``self``.ship_img, (``self``.x,` `self``.y))`
59. `for` `laser` `in` `self``.lasers:`
60. `laser.draw(window)`
62. `def` `move_lasers(``self``, vel, obj):`
63. `self``.cooldown()`
64. `for` `laser` `in` `self``.lasers:`
65. `laser.move(vel)`
66. `if` `laser.off_screen(HEIGHT):`
67. `self``.lasers.remove(laser)`
68. `elif` `laser.collision(obj):`
69. `obj.health` `-``=` `10`
70. `self``.lasers.remove(laser)`
72. `def` `cooldown(``self``):`
73. `if` `self``.cool_down_counter >``=` `self``.COOLDOWN:`
74. `self``.cool_down_counter` `=` `0`
75. `elif` `self``.cool_down_counter >` `0``:`
76. `self``.cool_down_counter` `+``=` `1`
78. `def` `shoot(``self``):`
79. `if` `self``.cool_down_counter` `=``=` `0``:`
80. `laser` `=` `Laser(``self``.x,` `self``.y,` `self``.laser_img)`
81. `self``.lasers.append(laser)`
82. `self``.cool_down_counter` `=` `1`
84. `def` `get_width(``self``):`
85. `return` `self``.ship_img.get_width()`
87. `def` `get_height(``self``):`
88. `return` `self``.ship_img.get_height()`
90. `class` `Player(Ship):`
91. `# Создаём корабль игрока`
92. `def` `__init__(``self``, x, y, health``=``100``):`
93. `super``().__init__(x, y, health)`
94. `self``.ship_img` `=` `PLAYER_SHIP`
95. `self``.laser_img` `=` `LASER`
96. `self``.mask` `=` `pygame.mask.from_surface(``self``.ship_img)`
97. `self``.max_health` `=` `health`
99. `def` `move_lasers(``self``, vel, objs):`
100. `self``.cooldown()`
101. `for` `laser` `in` `self``.lasers:`
102. `laser.move(vel)`
103. `if` `laser.off_screen(HEIGHT):`
104. `self``.lasers.remove(laser)`
105. `else``:`
106. `for` `obj` `in` `objs:`
107. `if` `laser.collision(obj):`
108. `objs.remove(obj)`
109. `if` `laser` `in` `self``.lasers:`
110. `self``.lasers.remove(laser)`
112. `def` `draw(``self``, window):`
113. `super``().draw(window)`
114. `self``.healthbar(window)`
116. `def` `healthbar(``self``, window):`
117. `pygame.draw.rect(window, (``255``,``0``,``0``), (``self``.x,` `self``.y` `+` `self``.ship_img.get_height()` `+` `10``,`
118. `self``.ship_img.get_width(),` `10``))`
120. `pygame.draw.rect(window, (``0``,``255``,``0``), (``self``.x,` `self``.y` `+` `self``.ship_img.get_height()` `+` `10``,`
121. `self``.ship_img.get_width()` `*` `(``self``.health``/``self``.max_health),` `10``))`
122. `class` `Enemy(Ship):`
123. `# Пришельцы`
124. `def` `__init__(``self``, x, y, health``=``50``):`
125. `super``().__init__(x, y, health)`
126. `self``.ship_img` `=` `pygame.image.load(``'img/ufo.png'``)`
127. `self``.mask` `=` `pygame.mask.from_surface(``self``.ship_img)`
129. `def` `move(``self``, vel):`
130. `self``.y` `+``=` `vel`
132. `def` `collide(obj1, obj2):`
133. `offset_x` `=` `obj2.x` `-` `obj1.x`
134. `offset_y` `=` `obj2.y` `-` `obj1.y`
135. `return` `obj1.mask.overlap(obj2.mask, (offset_x, offset_y)) !``=` `None`
137. `def` `main():`
138. `run` `=` `True`
139. `FPS` `=` `60`
140. `level` `=` `0`
141. `lives` `=` `3`
143. `main_font` `=` `pygame.font.SysFont(``"comicsans"``,` `50``)`
144. `lost_font` `=` `pygame.font.SysFont(``"comicsans"``,` `60``)`
145. `win_font` `=` `pygame.font.SysFont(``"comicsans"``,` `60``)`
147. `enemies` `=` `[]`
148. `wave_length` `=` `5`
150. `# Задаём скорость пришельцев, пуль, игрока`
151. `enemy_vel` `=` `1`
152. `player_vel` `=` `5`
153. `laser_vel` `=` `5`
155. `# Начальная позиция игрока`
156. `player` `=` `Player(``500``,` `600``)`
158. `clock` `=` `pygame.time.Clock()`
160. `lost` `=` `False`
161. `lost_count` `=` `0`
163. `win` `=` `False`
164. `win_count` `=` `0`
166. `def` `redraw_window():`
167. `WIN.blit(BG, (``0``,``0``))`
168. `# Переменные, которые хранят кол-во жизней и номер уровня`
169. `lives_label` `=` `main_font.render(f``"Жизни: {lives}"``,` `1``, (``255``,``255``,``255``))`
170. `level_label` `=` `main_font.render(f``"Уровень: {level}"``,` `1``, (``255``,``255``,``255``))`
172. `# Вывод на экран жизней и номер уровня`
173. `WIN.blit(lives_label, (``10``,` `10``))`
174. `WIN.blit(level_label, (WIDTH` `-` `level_label.get_width()` `-` `10``,` `10``))`
176. `for` `enemy` `in` `enemies:`
177. `enemy.draw(WIN)`
179. `player.draw(WIN)`
181. `if` `lost:`
182. `lost_label` `=` `lost_font.render(``"Попробуй ещё раз!"``,` `1``, (``255``,``255``,``255``))`
183. `WIN.blit(lost_label, (WIDTH``/``2` `-` `lost_label.get_width()``/``2``,` `350``))`
185. `if` `win:`
186. `win_label` `=` `win_font.render(``"Хорошая работа!"``,` `1``, (``255``,``255``,``255``))`
187. `WIN.blit(win_label, (WIDTH``/``2` `-` `win_label.get_width()``/``2``,` `350``))`
189. `pygame.display.update()`
191. `while` `run:`
192. `clock.tick(FPS)`
193. `redraw_window()`
195. `if` `lives <``=` `0` `or` `player.health <``=` `0``:`
196. `pygame.mixer.music.pause()`
197. `lost` `=` `True`
198. `lost_count` `+``=` `1`
200. `if` `level` `=``=` `16``:`
201. `pygame.mixer.music.pause()`
202. `win` `=` `True`
203. `win_count` `+``=` `1`
205. `if` `lost:`
206. `if` `lost_count > FPS` `*` `3``:`
207. `run` `=` `False`
208. `else``:`
209. `continue`
211. `if` `win:`
212. `if` `win_count > FPS` `*` `3``:`
213. `run` `=` `False`
214. `else``:`
215. `continue`
217. `if` `len``(enemies)` `=``=` `0``:`
218. `level` `+``=` `1`
219. `wave_length` `+``=` `5`
220. `for` `i` `in` `range``(wave_length):`
221. `enemy` `=` `Enemy(random.randrange(``50``, WIDTH``-``100``), random.randrange(``-``1500``,` `-``100``))`
222. `enemies.append(enemy)`
224. `for` `event` `in` `pygame.event.get():`
225. `if` `event.``type` `=``=` `pygame.QUIT:`
226. `quit()`
228. `# Задаём направления, в которых может двигаться игрок`
229. `# и запрещаем кораблю игрока вылетать за границы игрового поля`
230. `keys` `=` `pygame.key.get_pressed()`
232. `# Движение вверх и запрет на вылет за верхнюю границу экрана`
233. `if` `keys[pygame.K_w]` `and` `player.y` `-` `player_vel >` `0``:`
234. `player.y` `-``=` `player_vel`
236. `# Движение влево и запрет на вылет за левую границу экрана`
237. `if` `keys[pygame.K_a]` `and` `player.x` `-` `player_vel >` `0``:`
238. `player.x` `-``=` `player_vel`
240. `# Движение вниз и запрет на вылет за нижнюю границу экрана`
241. `if` `keys[pygame.K_s]` `and` `player.y` `+` `player_vel` `+` `player.get_height()` `+` `15` `< HEIGHT:`
242. `player.y` `+``=` `player_vel`
244. `# Движение вправо и запрет на вылет за правую границу экрана`
245. `if` `keys[pygame.K_d]` `and` `player.x` `+` `player_vel` `+` `player.get_width() < WIDTH:`
246. `player.x` `+``=` `player_vel`
248. `# Теперь корабль будет стрелять при нажании клавиши "Пробел"`
249. `if` `keys[pygame.K_SPACE]:`
250. `player.shoot()`
251. `# Рестарт игры`
252. `if` `keys[pygame.K_q]:`
253. `pygame.mixer.music.pause()`
254. `run` `=` `False`
255. `break`
257. `for` `enemy` `in` `enemies[:]:`
258. `enemy.move(enemy_vel)`
260. `# При столкновении пришельца и игрока, здоровье игрока`
261. `# Уменьшается на 10, а пришелец стирается`
262. `if` `collide(enemy, player):`
263. `player.health` `-``=` `10`
264. `enemies.remove(enemy)`
265. `elif` `enemy.y` `+` `enemy.get_height() > HEIGHT:`
266. `lives` `-``=` `1`
267. `enemies.remove(enemy)`
269. `player.move_lasers(``-``laser_vel, enemies)`
271. `def` `main_menu():`
272. `title_font` `=` `pygame.font.SysFont(``"comicsans"``,` `70``)`
273. `run` `=` `True`
275. `pygame.mixer.music.unpause()`
276. `pygame.mixer.music.load(``'sounds/bg.wav'``)`
277. `pygame.mixer.music.play(``-``1``)`
278. `pygame.mixer.music.set_volume(``0.2``)`
280. `while` `run:`
282. `WIN.blit(BG, (``0``,``0``))`
283. `title_label` `=` `title_font.render(``"Нажмите ЛКМ, чтобы начать..."``,` `1``, (``255``,``255``,``255``))`
284. `WIN.blit(title_label, (WIDTH``/``2` `-` `title_label.get_width()``/``2``,` `350``))`
285. `pygame.display.update()`
286. `for` `event` `in` `pygame.event.get():`
287. `if` `event.``type` `=``=` `pygame.QUIT:`
288. `run` `=` `False`
289. `if` `event.``type` `=``=` `pygame.MOUSEBUTTONDOWN:`
290. `pygame.mixer.music.unpause()`
291. `main()`
292. `pygame.quit()`
294. `main_menu()`