Pygame_Project/main.py

444 lines
16 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import pygame
import random
import math
# Определение констант
SCREEN_WIDTH = 1920
SCREEN_HEIGHT = 1080
PLAYER_WIDTH = 100
PLAYER_HEIGHT = 150
LOH_WIDTH = 300
LOH_HEIGHT = 250
BULLET_SIZE = 20
FPS = 60
BULLET_SPEED = 6
TANK_SPEED = 2
BOT_SPEED = 2
FIRE_DELAY = 1000 # Задержка между выстрелами в миллисекундах
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
# Инициализация Pygame
pygame.init()
# Создание игрового окна
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), flags=pygame.FULLSCREEN)
pygame.display.set_caption("Танчики")
# Загрузка и воспроизведение музыки
pygame.mixer.music.load('music.mp3')
pygame.mixer.music.play(-1) # Параметр -1 означает зацикливание музыки
shot_sound = pygame.mixer.Sound('shot.wav')
meme_sound = pygame.mixer.Sound("meme_sound.wav")
# Загрузка изображений
background_image = pygame.transform.scale(pygame.image.load("travka_pol.jpeg"), (960, 540))
stena = pygame.transform.scale(pygame.image.load("stena.jpeg").convert(), (100, 100))
stenki = pygame.transform.scale(pygame.image.load("stena.jpeg").convert(), (200, 200))
tank_image = pygame.transform.scale(pygame.image.load("ntank-removebg-preview.png"), (PLAYER_WIDTH, PLAYER_HEIGHT))
loh_image = pygame.transform.scale(pygame.image.load("loh.png"), (LOH_WIDTH, LOH_HEIGHT))
bullet_image = pygame.transform.scale(pygame.image.load("bullet.png"), (BULLET_SIZE, BULLET_SIZE))
menu_background = pygame.transform.scale(pygame.image.load("menu_background.jpg"), (SCREEN_WIDTH, SCREEN_HEIGHT))
# Определение класса танка
class Tank(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.original_image = tank_image
self.image = self.original_image
self.rect = self.image.get_rect(center=(x, y))
self.angle = -90 # Поворот на 90 градусов против часовой стрелки
self.TANK_SPEED = 2
self.last_fire_time = pygame.time.get_ticks() # Время последнего выстрела
self.boosted = False # Флаг, показывающий, активирован ли ускоритель
self.boost_multiplier = 2 # Множитель скорости ускорения
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
self.move_forward()
mouse_pos = pygame.mouse.get_pos()
self.angle = math.degrees(math.atan2(mouse_pos[1] - self.rect.centery, mouse_pos[0] - self.rect.centerx)) + 90
self.image = pygame.transform.rotate(self.original_image, -self.angle)
self.rect = self.image.get_rect(center=self.rect.center)
if keys[pygame.K_x]:
if not self.boosted:
self.TANK_SPEED *= self.boost_multiplier
self.boosted = True
else:
if self.boosted:
self.TANK_SPEED /= self.boost_multiplier
self.boosted = False
def move_forward(self):
angle_rad = math.radians(self.angle + 270)
self.rect.x += self.TANK_SPEED * math.cos(angle_rad)
self.rect.y += self.TANK_SPEED * math.sin(angle_rad)
def shoot(self):
current_time = pygame.time.get_ticks()
if current_time - self.last_fire_time > FIRE_DELAY: # Проверка задержки между выстрелами
shot_sound.play() # Воспроизведение звука выстрела
# Коррекция угла вылета пули, чтобы она вылетала из дула танка
offset_angle = -90 # Угол смещения для вылета пули из дула
corrected_angle = self.angle + offset_angle
# Вычисляем координаты дула танка
offset_x = 70 * math.cos(math.radians(corrected_angle))
offset_y = 70 * math.sin(math.radians(corrected_angle))
bullet = PlayerBullet(self.rect.centerx + offset_x, self.rect.centery + offset_y, self.angle + 270)
all_sprites.add(bullet)
bullets.add(bullet)
self.last_fire_time = current_time # Обновление времени последнего выстрела
# Определение класса снаряда игрока
class PlayerBullet(pygame.sprite.Sprite):
def __init__(self, x, y, angle):
super().__init__()
self.original_image = bullet_image
self.image = self.original_image
self.rect = self.image.get_rect(center=(x, y))
self.angle = angle
def update(self):
self.rect.x += BULLET_SPEED * math.cos(math.radians(self.angle))
self.rect.y += BULLET_SPEED * math.sin(math.radians(self.angle))
if not screen.get_rect().colliderect(self.rect):
self.kill()
if pygame.sprite.spritecollideany(self, walls):
self.kill() # Удаляем снаряд, если он столкнулся со стеной
# Определение класса снаряда бота
class BotBullet(pygame.sprite.Sprite):
def __init__(self, x, y, angle):
super().__init__()
self.original_image = bullet_image
self.image = self.original_image
self.rect = self.image.get_rect(center=(x, y))
self.angle = angle
def update(self):
self.rect.x += BULLET_SPEED * math.cos(math.radians(self.angle))
self.rect.y += BULLET_SPEED * math.sin(math.radians(self.angle))
if not screen.get_rect().colliderect(self.rect):
self.kill()
if pygame.sprite.spritecollideany(self, walls):
self.kill() # Удаляем снаряд, если он столкнулся со стеной
# Определение класса для бота
class Bot(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.original_image = loh_image
self.image = self.original_image
self.rect = self.image.get_rect(center=(x, y))
self.angle = random.randint(0, 360) # Случайный начальный угол поворота
self.last_fire_time = pygame.time.get_ticks() # Время последнего выстрела
self.rotate_delay = random.randint(100, 500) # Начальная задержка перед поворотом
self.rotate_timer = 0
def update(self):
self.move_random()
self.rotate_random()
self.check_bounds()
#self.shoot_random()
def move_random(self):
# Движение вперёд в направлении текущего угла поворота
angle_rad = math.radians(self.angle + 270)
self.rect.x += BOT_SPEED * math.cos(angle_rad)
self.rect.y += BOT_SPEED * math.sin(angle_rad)
def rotate_random(self):
# Случайный поворот бота
self.rotate_timer += 1
if self.rotate_timer >= self.rotate_delay:
self.angle += random.randint(-10, 10) # Случайный поворот
self.rotate_delay = random.randint(100, 500) # Новая случайная задержка перед поворотом
self.rotate_timer = 0
def check_bounds(self):
# Проверка выхода за границы экрана
if self.rect.left < 0:
self.rect.left = 0
elif self.rect.right > SCREEN_WIDTH:
self.rect.right = SCREEN_WIDTH
if self.rect.top < 0:
self.rect.top = 0
elif self.rect.bottom > SCREEN_HEIGHT:
self.rect.bottom = SCREEN_HEIGHT
#def shoot_random(self):
# Выстрел в направлении дула
#current_time = pygame.time.get_ticks()
#if current_time - self.last_fire_time > random.randint(1000, 5000):
#bullet = BotBullet(self.rect.centerx, self.rect.centery, self.angle + 90) # Стрельба в направлении дула
#all_sprites.add(bullet)
#bullets.add(bullet)
#self.last_fire_time = current_time
class Wall(pygame.sprite.Sprite):
def __init__(self, x, y, image):
super().__init__()
self.image = image
self.rect = self.image.get_rect(topleft=(x, y))
# Создание групп спрайтов
all_sprites = pygame.sprite.Group()
tanks = pygame.sprite.Group()
bullets = pygame.sprite.Group()
walls = pygame.sprite.Group() # Группа для всех стен
# Создание стен
wall_positions = [
(360, 40), (460, 730), (460, 830), (460, 930),
(960, 40), (960, 140), (960, 240),
(660, 240),
(960, 440), (960, 540), (960, 640), (960, 740),
(1260, 740), (1360, 740), (1460, 740), (1560, 740), (1660, 740),
(360, 240), (360, 340), (360, 440),
(0, 540), (60, 540), (260, 540), (360, 540), (460, 540),
(560, 540), (660, 540), (760, 540), (860, 540),
(1160, 240), (1260, 240), (1360, 240), (1460, 240), (1460, 340),
(1760, 340), (1860, 340)
]
for pos in wall_positions:
wall = Wall(*pos, stena)
all_sprites.add(wall)
walls.add(wall)
# Создание стен "stenki"
wall_stenki_positions = [
(-150, 0), (-150, 200), (-150, 400), (-150, 600), (-150, 800), (-150, 1000),
(0, -150), (200, -150), (400, -150), (600, -150), (800, -150), (1000, -150),
(1200, -150), (1400, -150), (1600, -150), (1800, -150), (1870, 0), (1870, 200),
(1870, 400), (1870, 600), (1870, 800), (1870, 1000), (0, 1030), (200, 1030),
(400, 1030), (600, 1030), (800, 1030), (1000, 1030), (1200, 1030), (1400, 1030),
(1600, 1030), (1800, 1030)
]
for pos in wall_stenki_positions:
wall_stenki = Wall(*pos, stenki)
all_sprites.add(wall_stenki)
walls.add(wall_stenki)
# Создание групп спрайтов
all_sprites = pygame.sprite.Group()
tanks = pygame.sprite.Group()
bullets = pygame.sprite.Group()
# Создание игрока
player = Tank(SCREEN_WIDTH // 8, SCREEN_HEIGHT // 7)
all_sprites.add(player)
tanks.add(player)
bot = Bot(3 * SCREEN_WIDTH // 4, SCREEN_HEIGHT // 2)
all_sprites.add(bot)
tanks.add(bot)
bot = Bot(3 * SCREEN_WIDTH // 4, SCREEN_HEIGHT // 2)
all_sprites.add(bot)
tanks.add(bot)
bot = Bot(3 * SCREEN_WIDTH // 4, SCREEN_HEIGHT // 2)
all_sprites.add(bot)
tanks.add(bot)
def draw_menu():
screen.blit(menu_background, (0, 0))
# Рисуем текст меню
font = pygame.font.Font(None, 50)
text = font.render("Start", True, WHITE)
text_rect = text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 - 50))
screen.blit(text, text_rect)
# Рисуем кнопку "Выйти"
quit_text = font.render("Quit", True, WHITE)
quit_rect = quit_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 50))
screen.blit(quit_text, quit_rect)
pygame.display.flip()
return quit_rect # Возвращаем прямоугольник для кнопки "Выйти"
def respawn_bot():
# Создание нового экземпляра бота
new_bot = Bot(random.randint(0, SCREEN_WIDTH), random.randint(0, SCREEN_HEIGHT))
all_sprites.add(new_bot)
tanks.add(new_bot)
last_meme_time = 0
meme_delay = 2000 # Задержка в миллисекундах (2 секунды)
# Главный цикл программы
menu_active = True
while menu_active:
quit_rect = draw_menu()
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # Левая кнопка мыши
if quit_rect.collidepoint(event.pos):
pygame.quit()
quit()
else:
menu_active = False # Нажата кнопка "Старт"
# Основной игровой цикл
clock = pygame.time.Clock()
running = True
while running:
player_bullets = []
bot_bullets = []
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: # Обработка левой кнопки мыши
player.shoot()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_k:
if current_time - last_meme_time > meme_delay: # Проверка задержки
meme_sound.play()
last_meme_time = current_time # Обновление времени последнего воспроизведения звука
# Обновление всех спрайтов
all_sprites.update()
# Проверка столкновений пуль с танками
for bullet in bullets:
if isinstance(bullet, PlayerBullet):
tank_hit = pygame.sprite.spritecollideany(bullet, tanks, pygame.sprite.collide_mask)
if tank_hit and isinstance(tank_hit, Bot):
tank_hit.kill() # Удаляем бота, если попал игрок
bullet.kill() # Удаляем пулю
elif isinstance(bullet, BotBullet):
tank_hit = pygame.sprite.spritecollideany(bullet, tanks, pygame.sprite.collide_mask)
if tank_hit and isinstance(tank_hit, Tank):
tank_hit.kill() # Удаляем игрока, если попал бот
bullet.kill() # Удаляем пулю
if tank_hit and isinstance(tank_hit, Bot):
tank_hit.kill() # Удаляем бота, если попал игрок
bullet.kill() # Удаляем пулю
respawn_bot() # Пересоздаем бота в случайном месте карты
bullet.update()
# Отрисовка фона
for i in range(2):
for j in range(2):
screen.blit(background_image, (i * 960, j * 540))
all_sprites.draw(screen)
screen.blit(stena, (360, 40))
screen.blit(stena, (460, 730))
screen.blit(stena, (460, 830))
screen.blit(stena, (460, 930))
screen.blit(stena, (960, 40))
screen.blit(stena, (960, 140))
screen.blit(stena, (960, 240))
screen.blit(stena, (660, 240))
screen.blit(stena, (960, 440))
screen.blit(stena, (960, 540))
screen.blit(stena, (960, 640))
screen.blit(stena, (960, 740))
screen.blit(stena, (1260, 740))
screen.blit(stena, (1360, 740))
screen.blit(stena, (1460, 740))
screen.blit(stena, (1560, 740))
screen.blit(stena, (1660, 740))
screen.blit(stena, (360, 240))
screen.blit(stena, (360, 340))
screen.blit(stena, (360, 440))
screen.blit(stena, (0, 540))
screen.blit(stena, (60, 540))
screen.blit(stena, (260, 540))
screen.blit(stena, (360, 540))
screen.blit(stena, (460, 540))
screen.blit(stena, (560, 540))
screen.blit(stena, (660, 540))
screen.blit(stena, (760, 540))
screen.blit(stena, (860, 540))
screen.blit(stena, (1160, 240))
screen.blit(stena, (1260, 240))
screen.blit(stena, (1360, 240))
screen.blit(stena, (1460, 240))
screen.blit(stena, (1460, 340))
screen.blit(stena, (1760, 340))
screen.blit(stena, (1860, 340))
screen.blit(stenki, (-150, 0))
screen.blit(stenki, (-150, 200))
screen.blit(stenki, (-150, 400))
screen.blit(stenki, (-150, 600))
screen.blit(stenki, (-150, 800))
screen.blit(stenki, (-150, 1000))
screen.blit(stenki, (0, -150))
screen.blit(stenki, (200, -150))
screen.blit(stenki, (400, -150))
screen.blit(stenki, (600, -150))
screen.blit(stenki, (800, -150))
screen.blit(stenki, (1000, -150))
screen.blit(stenki, (1200, -150))
screen.blit(stenki, (1400, -150))
screen.blit(stenki, (1600, -150))
screen.blit(stenki, (1800, -150))
screen.blit(stenki, (1870, 0))
screen.blit(stenki, (1870, 200))
screen.blit(stenki, (1870, 400))
screen.blit(stenki, (1870, 600))
screen.blit(stenki, (1870, 800))
screen.blit(stenki, (1870, 1000))
screen.blit(stenki, (0, 1030))
screen.blit(stenki, (200, 1030))
screen.blit(stenki, (400, 1030))
screen.blit(stenki, (600, 1030))
screen.blit(stenki, (800, 1030))
screen.blit(stenki, (1000, 1030))
screen.blit(stenki, (1200, 1030))
screen.blit(stenki, (1400, 1030))
screen.blit(stenki, (1600, 1030))
screen.blit(stenki, (1800, 1030))
pygame.display.flip()
clock.tick(FPS)
# Завершение работы Pygame
pygame.quit()
# token: 8f195a885b18a96da6577884cc731f850f33a9e2