import
pygame, time, random
-
pygame.font.init()
-
pygame.mixer.init()
-
WIDTH, HEIGHT
=
1024
,
768
WIN
=
pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(
"Вторжение пришельцев"
)
-
PLAYER_SHIP
=
pygame.image.load(
"img/ship.png"
)
-
LASER
=
pygame.image.load(
"img/pixel_laser.png"
)
-
BG
=
pygame.transform.scale(pygame.image.load(
"img/bg.jpg"
), (WIDTH, HEIGHT))
-
class
Laser:
-
-
def
__init__(
self
, x, y, img):
-
self
.x
=
x
-
15
-
self
.y
=
y
-
20
-
self
.img
=
img
-
self
.mask
=
pygame.mask.from_surface(
self
.img)
-
-
def
draw(
self
, window):
-
window.blit(
self
.img, (
self
.x,
self
.y))
-
-
def
move(
self
, vel):
-
self
.y
+
=
vel
-
-
def
off_screen(
self
, height):
-
return
not
(
self
.y <
=
height
and
self
.y >
=
0
)
-
-
def
collision(
self
, obj):
-
return
collide(
self
, obj)
-
class
Ship:
-
-
COOLDOWN
=
20
-
-
-
def
__init__(
self
, x, y, health
=
100
):
-
self
.x
=
x
-
self
.y
=
y
-
self
.health
=
health
-
self
.ship_img
=
None
-
self
.laser_img
=
None
-
self
.lasers
=
[]
-
self
.cool_down_counter
=
0
-
-
def
draw(
self
, window):
-
window.blit(
self
.ship_img, (
self
.x,
self
.y))
-
for
laser
in
self
.lasers:
-
laser.draw(window)
-
-
def
move_lasers(
self
, vel, obj):
-
self
.cooldown()
-
for
laser
in
self
.lasers:
-
laser.move(vel)
-
if
laser.off_screen(HEIGHT):
-
self
.lasers.remove(laser)
-
elif
laser.collision(obj):
-
obj.health
-
=
10
-
self
.lasers.remove(laser)
-
-
def
cooldown(
self
):
-
if
self
.cool_down_counter >
=
self
.COOLDOWN:
-
self
.cool_down_counter
=
0
-
elif
self
.cool_down_counter >
0
:
-
self
.cool_down_counter
+
=
1
-
-
def
shoot(
self
):
-
if
self
.cool_down_counter
=
=
0
:
-
laser
=
Laser(
self
.x,
self
.y,
self
.laser_img)
-
self
.lasers.append(laser)
-
self
.cool_down_counter
=
1
-
-
def
get_width(
self
):
-
return
self
.ship_img.get_width()
-
-
def
get_height(
self
):
-
return
self
.ship_img.get_height()
-
class
Player(Ship):
-
-
def
__init__(
self
, x, y, health
=
100
):
-
super
().__init__(x, y, health)
-
self
.ship_img
=
PLAYER_SHIP
-
self
.laser_img
=
LASER
-
self
.mask
=
pygame.mask.from_surface(
self
.ship_img)
-
self
.max_health
=
health
-
-
def
move_lasers(
self
, vel, objs):
-
self
.cooldown()
-
for
laser
in
self
.lasers:
-
laser.move(vel)
-
if
laser.off_screen(HEIGHT):
-
self
.lasers.remove(laser)
-
else
:
-
for
obj
in
objs:
-
if
laser.collision(obj):
-
objs.remove(obj)
-
if
laser
in
self
.lasers:
-
self
.lasers.remove(laser)
-
-
def
draw(
self
, window):
-
super
().draw(window)
-
self
.healthbar(window)
-
-
def
healthbar(
self
, window):
-
pygame.draw.rect(window, (
255
,
0
,
0
), (
self
.x,
self
.y
+
self
.ship_img.get_height()
+
10
,
-
self
.ship_img.get_width(),
10
))
-
-
pygame.draw.rect(window, (
0
,
255
,
0
), (
self
.x,
self
.y
+
self
.ship_img.get_height()
+
10
,
-
self
.ship_img.get_width()
*
(
self
.health
/
self
.max_health),
10
))
class
Enemy(Ship):
-
-
def
__init__(
self
, x, y, health
=
50
):
-
super
().__init__(x, y, health)
-
self
.ship_img
=
pygame.image.load(
'img/ufo.png'
)
-
self
.mask
=
pygame.mask.from_surface(
self
.ship_img)
-
-
def
move(
self
, vel):
-
self
.y
+
=
vel
-
def
collide(obj1, obj2):
-
offset_x
=
obj2.x
-
obj1.x
-
offset_y
=
obj2.y
-
obj1.y
-
return
obj1.mask.overlap(obj2.mask, (offset_x, offset_y)) !
=
None
-
def
main():
-
run
=
True
-
FPS
=
60
-
level
=
0
-
lives
=
3
-
-
main_font
=
pygame.font.SysFont(
"comicsans"
,
50
)
-
lost_font
=
pygame.font.SysFont(
"comicsans"
,
60
)
-
win_font
=
pygame.font.SysFont(
"comicsans"
,
60
)
-
-
enemies
=
[]
-
wave_length
=
5
-
-
-
enemy_vel
=
1
-
player_vel
=
5
-
laser_vel
=
5
-
-
-
player
=
Player(
500
,
600
)
-
-
clock
=
pygame.time.Clock()
-
-
lost
=
False
-
lost_count
=
0
-
-
win
=
False
-
win_count
=
0
-
-
def
redraw_window():
-
WIN.blit(BG, (
0
,
0
))
-
-
lives_label
=
main_font.render(f
"Жизни: {lives}"
,
1
, (
255
,
255
,
255
))
-
level_label
=
main_font.render(f
"Уровень: {level}"
,
1
, (
255
,
255
,
255
))
-
-
-
WIN.blit(lives_label, (
10
,
10
))
-
WIN.blit(level_label, (WIDTH
-
level_label.get_width()
-
10
,
10
))
-
-
for
enemy
in
enemies:
-
enemy.draw(WIN)
-
-
player.draw(WIN)
-
-
if
lost:
-
lost_label
=
lost_font.render(
"Попробуй ещё раз!"
,
1
, (
255
,
255
,
255
))
-
WIN.blit(lost_label, (WIDTH
/
2
-
lost_label.get_width()
/
2
,
350
))
-
-
if
win:
-
win_label
=
win_font.render(
"Хорошая работа!"
,
1
, (
255
,
255
,
255
))
-
WIN.blit(win_label, (WIDTH
/
2
-
win_label.get_width()
/
2
,
350
))
-
-
pygame.display.update()
-
-
while
run:
-
clock.tick(FPS)
-
redraw_window()
-
-
if
lives <
=
0
or
player.health <
=
0
:
-
pygame.mixer.music.pause()
-
lost
=
True
-
lost_count
+
=
1
-
-
if
level
=
=
16
:
-
pygame.mixer.music.pause()
-
win
=
True
-
win_count
+
=
1
-
-
if
lost:
-
if
lost_count > FPS
*
3
:
-
run
=
False
-
else
:
-
continue
-
-
if
win:
-
if
win_count > FPS
*
3
:
-
run
=
False
-
else
:
-
continue
-
-
if
len
(enemies)
=
=
0
:
-
level
+
=
1
-
wave_length
+
=
5
-
for
i
in
range
(wave_length):
-
enemy
=
Enemy(random.randrange(
50
, WIDTH
-
100
), random.randrange(
-
1500
,
-
100
))
-
enemies.append(enemy)
-
-
for
event
in
pygame.event.get():
-
if
event.
type
=
=
pygame.QUIT:
-
quit()
-
-
-
-
keys
=
pygame.key.get_pressed()
-
-
-
if
keys[pygame.K_w]
and
player.y
-
player_vel >
0
:
-
player.y
-
=
player_vel
-
-
-
if
keys[pygame.K_a]
and
player.x
-
player_vel >
0
:
-
player.x
-
=
player_vel
-
-
-
if
keys[pygame.K_s]
and
player.y
+
player_vel
+
player.get_height()
+
15
< HEIGHT:
-
player.y
+
=
player_vel
-
-
-
if
keys[pygame.K_d]
and
player.x
+
player_vel
+
player.get_width() < WIDTH:
-
player.x
+
=
player_vel
-
-
-
if
keys[pygame.K_SPACE]:
-
player.shoot()
-
-
if
keys[pygame.K_q]:
-
pygame.mixer.music.pause()
-
run
=
False
-
break
-
-
for
enemy
in
enemies[:]:
-
enemy.move(enemy_vel)
-
-
-
-
if
collide(enemy, player):
-
player.health
-
=
10
-
enemies.remove(enemy)
-
elif
enemy.y
+
enemy.get_height() > HEIGHT:
-
lives
-
=
1
-
enemies.remove(enemy)
-
-
player.move_lasers(
-
laser_vel, enemies)
-
def
main_menu():
-
title_font
=
pygame.font.SysFont(
"comicsans"
,
70
)
-
run
=
True
-
-
pygame.mixer.music.unpause()
-
pygame.mixer.music.load(
'sounds/bg.wav'
)
-
pygame.mixer.music.play(
-
1
)
-
pygame.mixer.music.set_volume(
0.2
)
-
-
while
run:
-
-
WIN.blit(BG, (
0
,
0
))
-
title_label
=
title_font.render(
"Нажмите ЛКМ, чтобы начать..."
,
1
, (
255
,
255
,
255
))
-
WIN.blit(title_label, (WIDTH
/
2
-
title_label.get_width()
/
2
,
350
))
-
pygame.display.update()
-
for
event
in
pygame.event.get():
-
if
event.
type
=
=
pygame.QUIT:
-
run
=
False
-
if
event.
type
=
=
pygame.MOUSEBUTTONDOWN:
-
pygame.mixer.music.unpause()
-
main()
-
pygame.quit()
-
main_menu()