import pygame import sys import math import os import random pygame.init() width, height = 800, 670 screen = pygame.display.set_mode((width, height)) pygame.display.set_caption('Labirints') os.chdir("C:\\Users\\aleks\\Desktop\\game") pygame.mixer.music.load('background.mp3') pygame.mixer.music.play(-1) cheese_image = pygame.image.load("sprites\cheese\cheese.png").convert_alpha() BLACK = (0, 0, 0) BLUE = (0, 0, 255) cheese_count = 0 maze = [ "#########################", "#.................#.....#", "#.##.#.########.#.#.#####", "#......#........#.#.....#", "#.#.##...##.#####.#####.#", "#.#.#######.#.....#...#.#", "#.#.......#.#.#####.#.#.#", "#.##..###.#.#.#.....#...#", "#.....###.#.#.#.#######.#", "#.##....#...#...#.#.....#", "#.##.##.###.#####.#.#..##", "#.....#...#...#...#.#...#", "#.#.#.###.###.#.###.#.#.#", "#.#.#...........#...#.#.#", "#.#.##.###.####.#.###.#.#", "#.#.#...##.##...#.#...#.#", "#.#.#.#.##....###.#.###.#", "#.#.#.#....##.#...#.#...#", "#.#.#.#.##..###.###.#.###", "#.......................#", "#########################" ] class Button: def __init__(self, x, y, width, height, text, action=None): self.rect = pygame.Rect(x, y, width, height) self.color = (100, 100, 100) self.text = text self.font = pygame.font.Font(None, 36) self.text_surface = self.font.render(self.text, True, (255, 255, 255)) self.text_rect = self.text_surface.get_rect(center=self.rect.center) self.action = action def draw(self, surface): pygame.draw.rect(surface, self.color, self.rect) surface.blit(self.text_surface, self.text_rect) def draw_start_screen(screen): screen.fill(BLUE) title_font = pygame.font.Font(None, 72) title_text = title_font.render("Labirints", True, (255, 255, 255)) title_rect = title_text.get_rect(center=(width // 2, height // 2 - 50)) screen.blit(title_text, title_rect) play_button = Button(width // 2 - 100, height - 100, 200, 50, "Play") play_button.draw(screen) pygame.display.flip() def reset_game(): global player, enemy, cheese_count player = Player(32, 32) enemy = Enemy(700, 610, player) player.reset_cheese_count() player.cheeses = [] cheese_count = 0 def handle_game_over(): screen.fill(BLUE) title_font = pygame.font.Font(None, 72) title_text = title_font.render("Game Over", True, (255, 255, 255)) title_rect = title_text.get_rect(center=(width // 2, height // 2 - 50)) screen.blit(title_text, title_rect) replay_button = Button(width // 2 - 100, height // 2 + 50, 200, 50, "Replay", action=main_game_loop) replay_button.draw(screen) pygame.display.flip() replay_waiting = True while replay_waiting: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = pygame.mouse.get_pos() if replay_button.rect.collidepoint(mouse_pos): replay_waiting = False reset_game() return False def draw_victory_screen(): screen.fill(BLUE) title_font = pygame.font.Font(None, 72) title_text = title_font.render("Victory!", True, (255, 255, 255)) title_rect = title_text.get_rect(center=(width // 2, height // 2 - 50)) screen.blit(title_text, title_rect) replay_button = Button(width // 2 - 100, height // 2 + 50, 200, 50, "Replay", action=main_game_loop) replay_button.draw(screen) pygame.display.flip() def handle_victory(): replay_button = Button(width // 2 - 100, height // 2 + 50, 200, 50, "Replay", action=main_game_loop) replay_waiting = True while replay_waiting: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = pygame.mouse.get_pos() if replay_button.rect.collidepoint(mouse_pos): replay_waiting = False return True return False class Cheese(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.image = pygame.transform.scale(cheese_image, (30, 30)) self.rect = self.image.get_rect() self.rect.topleft = (x, y) class Player(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() # Загрузка изображений персонажа и изменение их размера self.images = { "up": [pygame.transform.scale(pygame.image.load('sprites/rodent/up.png').convert_alpha(), (25, 25)), pygame.transform.scale(pygame.image.load('sprites/rodent/up1.png').convert_alpha(), (25, 25))], "down": [pygame.transform.scale(pygame.image.load('sprites/rodent/down.png').convert_alpha(), (25, 25)), pygame.transform.scale(pygame.image.load('sprites/rodent/down1.png').convert_alpha(), (25, 25))], "left": [pygame.transform.scale(pygame.image.load('sprites/rodent/left.png').convert_alpha(), (25, 25)), pygame.transform.scale(pygame.image.load('sprites/rodent/left1.png').convert_alpha(), (25, 25))], "right": [pygame.transform.scale(pygame.image.load('sprites/rodent/right.png').convert_alpha(), (25, 25)), pygame.transform.scale(pygame.image.load('sprites/rodent/right1.png').convert_alpha(), (25, 25))] } self.direction = "down" # Initial direction self.image_index = 0 # Index of the current image in the animation self.image = self.images[self.direction][self.image_index] self.rect = self.image.get_rect() self.rect.topleft = (x, y) self.speed = 10 self.cheeses = [] self.cheese_count = 0 def reset_cheese_count(self): self.cheese_count = 0 # Reset cheese count to zero def move(self, dx, dy, walls): old_rect = self.rect.copy() # Копируем текущее положение игрока self.rect.x += dx self.rect.y += dy # Проверка столкновений по горизонтали for wall in walls: if self.rect.colliderect(wall): if dx > 0: self.rect.right = wall.left elif dx < 0: self.rect.left = wall.right # Проверка столкновений по вертикали for wall in walls: if self.rect.colliderect(wall): if dy > 0: self.rect.bottom = wall.top elif dy < 0: self.rect.top = wall.bottom # Если после обновления положения игрока есть столкновение с другими стенами, # возвращаем его на предыдущее положение if self.rect.collidelist(walls) != -1: self.rect = old_rect def update_image(self, dx, dy): if dx > 0: self.direction = "right" elif dx < 0: self.direction = "left" elif dy > 0: self.direction = "down" elif dy < 0: self.direction = "up" # Update the image index for animation self.image_index = (self.image_index + 1) % len(self.images[self.direction]) self.image = self.images[self.direction][self.image_index] def draw(self, surface): surface.blit(self.image, self.rect) def generate_random_cheese(self, walls, num_cheese=1): # По умолчанию создаем 3 кусочка сыра for _ in range(num_cheese): while True: x = random.randint(0, width - 30) y = random.randint(0, height - 30) rect = pygame.Rect(x, y, 30, 30) if not any(wall.colliderect(rect) for wall in walls): self.cheeses.append(Cheese(x, y)) break def check_cheese_collision(self, cheeses): for cheese in cheeses[:]: if self.rect.colliderect(cheese.rect): cheeses.remove(cheese) def draw_maze(maze): walls = [] for y, row in enumerate(maze): for x, char in enumerate(row): if char == '#': pygame.draw.rect(screen, BLACK, (x * 32, y * 32, 32, 32)) walls.append(pygame.Rect(x * 32, y * 32, 32, 32)) return walls class Enemy(pygame.sprite.Sprite): def __init__(self, x, y, player): super().__init__() self.images = { "up": [pygame.transform.scale(pygame.image.load('sprites/cat/up.png').convert_alpha(), (25, 25)), pygame.transform.scale(pygame.image.load('sprites/cat/up3.png').convert_alpha(), (25, 25))], "down": [pygame.transform.scale(pygame.image.load('sprites/cat/down.png').convert_alpha(), (25, 25)), pygame.transform.scale(pygame.image.load('sprites/cat/down3.png').convert_alpha(), (25, 25))], "left": [pygame.transform.scale(pygame.image.load('sprites/cat/left.png').convert_alpha(), (25, 25)), pygame.transform.scale(pygame.image.load('sprites/cat/left3.png').convert_alpha(), (25, 25))], "right": [pygame.transform.scale(pygame.image.load('sprites/cat/right.png').convert_alpha(), (25, 25)), pygame.transform.scale(pygame.image.load('sprites/cat/right3.png').convert_alpha(), (25, 25))] } self.direction = "down" # Initial direction self.image_index = 0 # Index of the current image in the animation self.image = self.images[self.direction][self.image_index] self.rect = pygame.Rect(x, y, 30, 30) self.rect.topleft = (x, y) self.speed = 5 self.player = player def check_collision_ahead(self, walls): # Проверяем столкновение в точке впереди противника future_rect = self.rect.move(self.speed, 0) if self.direction == "right" else \ self.rect.move(-self.speed, 0) if self.direction == "left" else \ self.rect.move(0, self.speed) if self.direction == "down" else \ self.rect.move(0, -self.speed) # "up" for wall in walls: if wall.colliderect(future_rect): return True return False def update(self, walls): dx, dy = 0, 0 keys = pygame.key.get_pressed() # Обработка нажатий клавиш для управления врагом if keys[pygame.K_a]: dx = -self.speed self.direction = "left" elif keys[pygame.K_d]: dx = self.speed self.direction = "right" elif keys[pygame.K_w]: dy = -self.speed self.direction = "up" elif keys[pygame.K_s]: dy = self.speed self.direction = "down" new_rect = self.rect.move(dx, dy) if not self.check_collision(new_rect, walls): self.rect = new_rect # Если двигается только по одной оси, то разрешаем движение if dx != 0 and dy == 0: new_rect = self.rect.move(dx, 0) if not self.check_collision(new_rect, walls): self.rect = new_rect elif dy != 0 and dx == 0: new_rect = self.rect.move(0, dy) if not self.check_collision(new_rect, walls): self.rect = new_rect # Update animation self.image_index = (self.image_index + 1) % len(self.images[self.direction]) self.image = self.images[self.direction][self.image_index] def check_collision(self, new_rect, walls): # Проверяем столкновение только с несколькими точками на пути противника for i in range(0, new_rect.width, self.speed): x = new_rect.left + i if self.speed > 0 else new_rect.right - i for j in range(0, new_rect.height, self.speed): y = new_rect.top + j if self.speed > 0 else new_rect.bottom - j if self.is_wall(x, y, walls): return True return False def is_wall(self, x, y, walls): # Проверяем, находится ли точка (x, y) внутри стены for wall in walls: if wall.collidepoint(x, y): return True return False def draw(self, surface): surface.blit(self.image, self.rect) player = Player(32, 32) enemy = Enemy(700, 610, player) def draw_text(surface, text, pos, font, color): text_surface = font.render(text, True, color) text_rect = text_surface.get_rect() text_rect.topleft = pos surface.blit(text_surface, text_rect) def generate_random_cheese(player, walls): player.generate_random_cheese(walls) def main_game_loop(): global cheese_count cheese_count = 0 red_square_timer = 0 clock = pygame.time.Clock() cheese_count = 0 # Initialize cheese count font = pygame.font.Font(None, 36) # Font for displaying text running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False current_time = pygame.time.get_ticks() dt = clock.tick(30) / 1000.0 # Преобразуем миллисекунды в секунды replay_button = Button(width // 2 - 100, height // 2 + 50, 200, 50, "Replay", action=main_game_loop) if player.rect.colliderect(enemy.rect): if handle_game_over(): reset_game() red_square_timer += dt if red_square_timer >= 5: red_square_timer -= 5 generate_random_cheese(player, walls) player.check_cheese_collision(player.cheeses) keys = pygame.key.get_pressed() dx, dy = 0, 0 # Check horizontal movement if keys[pygame.K_LEFT]: dx = -player.speed elif keys[pygame.K_RIGHT]: dx = player.speed # Check vertical movement if keys[pygame.K_UP]: dy = -player.speed elif keys[pygame.K_DOWN]: dy = player.speed # Ensure that the player can only move in one direction at a time if dx != 0 and dy != 0: # Diagonal movement detected, prioritize one direction if keys[pygame.K_LEFT]: dy = 0 # Prevent vertical movement elif keys[pygame.K_RIGHT]: dy = 0 # Prevent vertical movement elif keys[pygame.K_UP]: dx = 0 # Prevent horizontal movement elif keys[pygame.K_DOWN]: dx = 0 # Prevent horizontal movement walls = draw_maze(maze) collision = player.move(dx, dy, walls) player.update_image(dx, dy) enemy.update(walls) screen.fill(BLUE) draw_maze(maze) player.draw(screen) enemy.draw(screen) for cheese in player.cheeses: screen.blit(cheese.image, cheese.rect) cheeses_to_remove = [] for cheese in player.cheeses: if player.rect.colliderect(cheese.rect): cheese_count += 1 # Increment cheese count player.cheeses.remove(cheese) for cheese in cheeses_to_remove: player.cheeses.remove(cheese) draw_text(screen, f"Cheese: {cheese_count}", (10, 10), font, (255, 255, 255)) if cheese_count >= 5: draw_victory_screen() if handle_victory(): reset_game() continue pygame.display.flip() clock.tick(10) # Reduce animation speed for better visibility def main(): play_button = Button(width // 2 - 100, height - 100, 200, 50, "Play") draw_start_screen(screen) waiting = True while waiting: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = pygame.mouse.get_pos() if play_button.rect.collidepoint(mouse_pos): waiting = False main_game_loop() if __name__ == "__main__": main()