spele/game_full/game.py

449 lines
17 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 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()