diff --git a/game_full/background.mp3 b/game_full/background.mp3 new file mode 100644 index 0000000..fabc082 Binary files /dev/null and b/game_full/background.mp3 differ diff --git a/game_full/game.py b/game_full/game.py new file mode 100644 index 0000000..85ef2a2 --- /dev/null +++ b/game_full/game.py @@ -0,0 +1,448 @@ +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() + +