import math import sys import pygame # Screen dimensions screen_height = 960 screen_width = 960 #define game variables tile_size = 40 Game_state = 0 current_level_index = 0 total_levels = 3 # Example: 3 levels in total coin_counter = 0 # Example: Global variable to count collected coins exitbtm_locked = True # Initially, the exitbtm is locked time_limit = 60 # 60 seconds timer start_ticks = 0 # Variable to store the start time game_started = False # Flag to check if the game has started level = 1 #shows what level the game is on # Initialize Pygame and set up the display pygame.init() screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("Repeating Background") # Load images background = pygame.image.load('images/background.png') wall_image = pygame.image.load('images/wall.png') exit_image = pygame.image.load('images/exit.png') exitbtm_image = pygame.image.load('images/exitbtm.png') coin_image = pygame.image.load('images/coin.png') # Calculate the new size for the player image player_width = int(wall_image.get_width() * 0.5) player_height = int(wall_image.get_height() * 0.5) # Calculate the new size for the coin image coin_width = int(wall_image.get_width() * 0.5) coin_height = int(wall_image.get_height() * 0.5) # Resize player image player_image = pygame.transform.scale(pygame.image.load('images/player.png'), (player_width, player_height)) # Define font variables coin_font = pygame.font.SysFont(None, 36) timer_font = pygame.font.SysFont(None, 36) class Wall(pygame.sprite.Sprite): def __init__(self, x, y, width, height): super().__init__() self.image = pygame.transform.scale(wall_image, (width, height)) self.rect = self.image.get_rect() self.rect.topleft = (x, y) class Exit(pygame.sprite.Sprite): def __init__(self, x, y, width, height): super().__init__() self.image = pygame.transform.scale(exit_image, (width, height)) self.rect = self.image.get_rect() self.rect.topleft = (x, y) class Exitbtm(pygame.sprite.Sprite): def __init__(self, x, y, width, height): super().__init__() self.image = pygame.transform.scale(exitbtm_image, (width, height)) self.rect = self.image.get_rect() self.rect.topleft = (x, y) class Coin(pygame.sprite.Sprite): def __init__(self, x, y, width, height): super().__init__() self.image = pygame.transform.scale(coin_image, (coin_width, coin_height)) self.rect = self.image.get_rect() self.rect.topleft = (x, y) class Player(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.original_image = player_image self.image = self.original_image self.rect = self.image.get_rect() self.rect.topleft = (x, y) def update(self, mouse_pos, keys, world): global level # Ensure we can modify the global level variable # Calculate angle between player and mouse angle = math.degrees(math.atan2(mouse_pos[1] - self.rect.centery, mouse_pos[0] - self.rect.centerx)) angle += 90 # Adjust for Pygame's coordinate system # Rotate player image self.image = pygame.transform.rotate(self.original_image, -angle) self.rect = self.image.get_rect(center=self.rect.center) # Handle player movement new_rect = self.rect.copy() # Create a temporary rect to test movement if keys[pygame.K_LEFT]: new_rect.x -= 3 elif keys[pygame.K_RIGHT]: new_rect.x += 3 elif keys[pygame.K_UP]: new_rect.y -= 3 elif keys[pygame.K_DOWN]: new_rect.y += 3 # Check for collisions with walls for wall in world.wall_sprites: if new_rect.colliderect(wall.rect): # If collision detected with wall, don't move return # Check if player would move out of the screen boundaries if new_rect.left < map_left or new_rect.right > map_right or new_rect.top < map_top or new_rect.bottom > map_bottom: return # Check for exit condition for exit in world.exit_sprites: if isinstance(exit, Exit) and new_rect.colliderect(exit.rect): # Player has reached the exit, load the next level next_level() return # If no collision detected and within boundaries, update player position self.rect = new_rect def main_menu(): while True: screen.fill((0, 0, 0)) # Clear the screen keys = pygame.key.get_pressed() # Get the pressed keys # Draw main menu options menu_font = pygame.font.SysFont(None, 60) start_text = menu_font.render("Start (S)", True, (255, 255, 255)) instructions_text = menu_font.render("Instructions (I)", True, (255, 255, 255)) exit_text = menu_font.render("Exit (ESC)", True, (255, 255, 255)) start_rect = start_text.get_rect(center=(screen_width // 2, screen_height // 2 - 50)) instructions_rect = instructions_text.get_rect(center=(screen_width // 2, screen_height // 2)) exit_rect = exit_text.get_rect(center=(screen_width // 2, screen_height // 2 + 50)) screen.blit(start_text, start_rect) screen.blit(instructions_text, instructions_rect) screen.blit(exit_text, exit_rect) pygame.display.flip() # Update the display for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_s: # Start game return "start" elif event.key == pygame.K_i: # Instructions # Display instructions (optional) pass elif event.key == pygame.K_ESCAPE: # Exit pygame.quit() sys.exit() def game_over_screen(): global coin_counter # Ensure we can modify the global coin counter coin_counter = 0 # Reset the coin counter global exitbtm_locked # Ensure we can modify the global exitbtm_locked variable exitbtm_locked = True # Reset the exitbtm lock while True: screen.fill((0, 0, 0)) # Clear the screen keys = pygame.key.get_pressed() # Get the pressed keys # Draw game over text game_over_font = pygame.font.SysFont(None, 100) game_over_text = game_over_font.render("GAME OVER", True, (255, 0, 0)) game_over_rect = game_over_text.get_rect(center=(screen_width // 2, screen_height // 2 - 100)) screen.blit(game_over_text, game_over_rect) # Draw options option_font = pygame.font.SysFont(None, 50) retry_text = option_font.render("Retry (R)", True, (255, 255, 255)) main_menu_text = option_font.render("Main Menu (M)", True, (255, 255, 255)) exit_text = option_font.render("Exit (ESC)", True, (255, 255, 255)) retry_rect = retry_text.get_rect(center=(screen_width // 2, screen_height // 2)) main_menu_rect = main_menu_text.get_rect(center=(screen_width // 2, screen_height // 2 + 50)) exit_rect = exit_text.get_rect(center=(screen_width // 2, screen_height // 2 + 100)) screen.blit(retry_text, retry_rect) screen.blit(main_menu_text, main_menu_rect) screen.blit(exit_text, exit_rect) pygame.display.flip() # Update the display for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_r: # Retry # Reset the player position player.rect.topleft = (50, 90) # Redraw the coins on the screen world = World(world_data) # Re-initialize the world return "retry" elif event.key == pygame.K_m: # Main Menu return "main_menu" elif event.key == pygame.K_ESCAPE: # Exit pygame.quit() sys.exit() def game_over(): result = game_over_screen() if result == "retry": # Reset the game or level pass elif result == "main_menu": main_menu() # Go back to the main menu else: # Exit the game pygame.quit() sys.exit() def next_level(): global current_level_index global total_levels global coin_counter global world # Ensure this global variable is updated # Increment level index before checking current_level_index += 1 # Check if there are more levels if current_level_index < total_levels: # Reset player position for the next level player.rect.topleft = (50, 90) # Reset coin counter for the next level coin_counter = 0 # Load new level layout new_level_data = load_level(current_level_index) if new_level_data: world = World(new_level_data) else: print("Failed to load the next level data.") game_over() else: # If no more levels, go back to the first level current_level_index = 0 next_level() def draw_grid(): for line in range(0, screen_width, tile_size): pygame.draw.line(screen, (255, 255, 255), (line, 0), (line, screen_height)) pygame.draw.line(screen, (255, 255, 255), (0, line), (screen_width, line)) class World(): def __init__(self, data): self.wall_sprites = pygame.sprite.Group() # Add a group for wall self.exit_sprites = pygame.sprite.Group() # Add a group for exit self.coin_sprites = pygame.sprite.Group() # Add a group for coins row_count = 0 for row in data: col_count = 0 for tile in row: if tile == 1: wall = Wall(col_count * tile_size, row_count * tile_size, tile_size, tile_size) self.wall_sprites.add(wall) if tile == 2: exit = Exit(col_count * tile_size, row_count * tile_size, tile_size, tile_size) self.exit_sprites.add(exit) if tile == 3: exitbtm = Exitbtm(col_count * tile_size, row_count * tile_size, tile_size, tile_size) self.exit_sprites.add(exitbtm) elif tile == 4: # Handle coins offset_x = (tile_size - coin_width) // 2 offset_y = (tile_size - coin_height) // 2 coin = Coin(col_count * tile_size + offset_x, row_count * tile_size + offset_y, coin_width, coin_height) self.coin_sprites.add(coin) col_count += 1 row_count += 1 def draw(self, screen): self.wall_sprites.draw(screen) self.exit_sprites.draw(screen) # Draw the exit sprites along with the walls self.coin_sprites.draw(screen) # Draw the coins def load_level(level): if level == 1: return [ [1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 1], [1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1], [1, 4, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1], [1, 1, 4, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1], [1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1], [1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1], [1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 4, 4, 4, 0, 0, 0, 0, 1, 0, 1], [1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1], [1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1], [1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1], [1, 0, 0, 1, 1, 0, 1, 0, 0, 4, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1], [1, 0, 0, 4, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 4, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1], [1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1], [1, 4, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1], ] if level == 2: return [ [1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 4, 1, 4, 1, 1], [1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 1], [1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1], [1, 4, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [1, 1, 1, 4, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1], [1, 4, 4, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1], [1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 4, 0, 1, 1], [1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1], [1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 4, 1, 0, 1, 1, 1, 0, 4, 0, 0, 1, 0, 1], [1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1], [1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1], [1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1], [1, 0, 0, 1, 1, 0, 1, 0, 0, 4, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1], [1, 0, 0, 4, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 4, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 4, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 4, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1], [1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 4, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 4, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1], ] if level == 3: return [ [1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 1], [1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1], [1, 4, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1], [1, 1, 4, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1], [1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1], [1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1], [1, 1, 1, 1, 0, 1, 4, 1, 1, 4, 1, 1, 1, 0, 4, 4, 4, 0, 0, 0, 0, 1, 0, 1], [1, 0, 0, 0, 0, 1, 4, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1], [1, 0, 1, 1, 1, 1, 4, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1], [1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 4, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1], [1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1], [1, 0, 0, 1, 0, 0, 1, 0, 0, 4, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1], [1, 0, 0, 4, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1], [1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 4, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1], [1, 4, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1], ] # Initial level data world_data = load_level(level) world = World(world_data) # Create a group to hold all walls and the player all_sprites = pygame.sprite.Group() # Define map boundaries map_left = 0 map_top = 0 map_right = screen_width map_bottom = screen_height world = World(world_data) player = Player(50, 90) # Create player player = Player(50, 90) all_sprites.add(player) clock = pygame.time.Clock() coin_font = pygame.font.SysFont(None, 36) main_menu_result = main_menu() if main_menu_result == "start": # Start the game running = True while running: screen.fill((0, 0, 0)) # Clear the screen keys = pygame.key.get_pressed() # Get the pressed keys mouse_pos = pygame.mouse.get_pos() # Get the mouse position # Update player player.update(mouse_pos, keys, world) # Draw the repeating background for y in range(0, screen_height, background.get_height()): for x in range(0, screen_width, background.get_width()): screen.blit(background, (x, y)) if not game_started and (keys[pygame.K_LEFT] or keys[pygame.K_RIGHT] or keys[pygame.K_UP] or keys[pygame.K_DOWN]): game_started = True start_ticks = pygame.time.get_ticks() if not game_started: result = main_menu() if result == "start": start_ticks = pygame.time.get_ticks() game_started = True # Draw the world world.draw(screen) draw_grid() all_sprites.draw(screen) coin_text = coin_font.render(f"Coins: {coin_counter}", True, (0, 0, 0)) # Render the coin counter text screen.blit(coin_text, (850, 10)) # Blit the coin counter text onto the screen at position (10, 10) # Update the display pygame.display.flip() # Limit frames per second clock.tick(60) for coin in world.coin_sprites: if player.rect.colliderect(coin.rect): world.coin_sprites.remove(coin) coin_counter += 1 if len(world.coin_sprites) == 0: for exitbtm in world.exit_sprites: if isinstance(exitbtm, Exitbtm): exitbtm_locked = False for event in pygame.event.get(): if event.type == pygame.QUIT: running = False for exitbtm in world.exit_sprites: if isinstance(exitbtm, Exitbtm) and exitbtm_locked and player.rect.colliderect(exitbtm.rect): continue elif isinstance(exitbtm, Exitbtm) and not exitbtm_locked and player.rect.colliderect(exitbtm.rect): next_level() elif main_menu_result == "exit": # Exit the game pygame.quit() sys.exit()