import pygame import sys import random import math # Initialize Pygame pygame.init() # Constants WIDTH, HEIGHT = 800, 600 FPS = 60 WHITE = (255, 255, 255) RED = (255, 0, 0) YELLOW = (255, 255, 0) BLUE = (0, 0, 255) BLACK = (0, 0, 0) GROUND_HEIGHT = 20 PLATFORM_HEIGHT = 20 PLAYER_SIZE = 50 PLAYER_SPEED = 5 JUMP_HEIGHT = 15 GRAVITY = 1 # Create the game window screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Platformer") # Clock to control the frame rate clock = pygame.time.Clock() # Player player = pygame.Rect(WIDTH // 2 - PLAYER_SIZE // 2, HEIGHT - GROUND_HEIGHT - PLAYER_SIZE, PLAYER_SIZE, PLAYER_SIZE) player_velocity = 0 on_ground = False # Platforms platform_positions = [ (50, HEIGHT - GROUND_HEIGHT - 100), (200, HEIGHT - GROUND_HEIGHT - 175), (400, HEIGHT - GROUND_HEIGHT - 150), (600, HEIGHT - GROUND_HEIGHT - 250), (300, HEIGHT - GROUND_HEIGHT - 350), (100, HEIGHT - GROUND_HEIGHT - 275), (500, HEIGHT - GROUND_HEIGHT - 400), ] platforms = [pygame.Rect(x, y, 150, PLATFORM_HEIGHT) for x, y in platform_positions] # Coins coin_positions = [(x + 75, y - 30) for x, y in platform_positions] coins = [pygame.Rect(x, y, 20, 20) for x, y in coin_positions] collected_coins = set() # Key key_image = pygame.image.load("platformer/key.png") # Load the key image key_position = (random.randint(0, WIDTH - 20), random.randint(0, HEIGHT - GROUND_HEIGHT - 20)) key = pygame.Rect(key_position[0], key_position[1], 20, 20) key_collected = False # Door door_image = pygame.image.load("platformer/door.png") door = pygame.Rect(WIDTH - 100, HEIGHT - GROUND_HEIGHT - 120, 80, 120) # Score score = 0 font = pygame.font.Font(None, 36) # Winning state winning = False # Timer start_time = 0 timer_font = pygame.font.Font(None, 36) timer_text = None # Main game loop running = True while running: # Event handling for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE and on_ground: player_velocity = -JUMP_HEIGHT if start_time == 0: start_time = pygame.time.get_ticks() # Start the timer when the player starts moving # Update keys = pygame.key.get_pressed() player.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * PLAYER_SPEED # Apply gravity player_velocity += GRAVITY player.y += player_velocity # Check for collisions with platforms (vertical) on_ground = False for platform in platforms: if player.colliderect(platform): if player_velocity > 0 and player.bottom > platform.top > player.top: player.y = platform.top - player.height player_velocity = 0 on_ground = True elif player_velocity < 0 and player.top < platform.bottom < player.bottom: player.y = platform.bottom player_velocity = 0 # Check for collisions with coins coins_to_remove = [] for coin in coins: coin_tuple = (coin.x, coin.y) if player.colliderect(coin) and coin_tuple not in collected_coins: collected_coins.add(coin_tuple) coins_to_remove.append(coin) score += 1 # Check if all coins are collected all_coins_collected = set((coin.x, coin.y) for coin in coins_to_remove) == set((coin.x, coin.y) for coin in coins) # Check for collisions with the key key_position_tuple = (key.x, key.y) if all_coins_collected and player.colliderect(key) and key_position_tuple not in collected_coins and not key_collected: key_collected = True key_message = font.render("Key collected!", True, BLUE) # Remove collected coins for coin in coins_to_remove: coins.remove(coin) # Check for collisions with platforms (horizontal) for platform in platforms: if player.colliderect(platform): if keys[pygame.K_RIGHT] and player.right > platform.left: player.right = platform.left if keys[pygame.K_LEFT] and player.left < platform.right: player.left = platform.right # Check if player is on the ground if player.bottom >= HEIGHT - GROUND_HEIGHT: player.bottom = HEIGHT - GROUND_HEIGHT player_velocity = 0 on_ground = True # Check for winning condition if all_coins_collected and key_collected and player.colliderect(door): winning = True # If the key is used on the door, remove the key from collected items collected_coins.add((key.x, key.y)) # Draw screen.fill(WHITE) # Draw the floor pygame.draw.rect(screen, BLACK, (0, HEIGHT - GROUND_HEIGHT, WIDTH, GROUND_HEIGHT)) # Draw the player pygame.draw.rect(screen, RED, player) # Draw the platforms for platform in platforms: pygame.draw.rect(screen, BLACK, platform) # Draw the coins for coin in coins: pygame.draw.ellipse(screen, YELLOW, coin) # Draw the key if key_collected and (key.x, key.y) not in collected_coins: # Calculate the vertical offset for hovering hover_offset = 10 * math.sin(pygame.time.get_ticks() * 0.005) # Use the math module for sin function key_y_offset = player.y - 20 + hover_offset # Draw the key on the player with the vertical offset screen.blit(pygame.transform.scale(key_image, (40, 20)), (player.x, key_y_offset)) elif not key_collected: # Draw the key on the ground screen.blit(pygame.transform.scale(key_image, (40, 20)), (key.x, key.y)) # Draw the door screen.blit(pygame.transform.scale(door_image, (80, 120)), (door.x, door.y)) # Draw the score score_text = font.render("Score: {}".format(score), True, BLACK) screen.blit(score_text, (10, 10)) # Draw the key collected message if key_collected: screen.blit(key_message, (WIDTH // 2 - 100, 10)) # Draw the timer if start_time > 0 and not winning: elapsed_time = pygame.time.get_ticks() - start_time seconds = elapsed_time // 1000 milliseconds = elapsed_time % 1000 timer_text = timer_font.render("Time: {}.{:03d}s".format(seconds, milliseconds), True, BLACK) screen.blit(timer_text, (WIDTH - 200, 10)) # Winning screen if winning: win_text = font.render("You win!", True, BLACK) screen.blit(win_text, (WIDTH // 2 - 50, HEIGHT // 2 - 50)) if timer_text: screen.blit(timer_text, (WIDTH // 2 - 60, HEIGHT // 2)) pygame.display.flip() pygame.time.delay(5000) # Display "You win!" for 5 seconds running = False # Update display pygame.display.flip() # Cap the frame rate clock.tick(FPS) # Quit Pygame pygame.quit() sys.exit()