import pygame import random # Initialize Pygame pygame.init() # Constants SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 WHITE = (255, 255, 255) BLACK = (0, 0, 0) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) FPS = 60 # Player properties PLAYER_WIDTH = 40 PLAYER_HEIGHT = 60 DEFAULT_PLAYER_COLOR = BLUE DEFAULT_PLAYER_SPEED = 5 GRAVITY = 0.8 JUMP_FORCE = -18 # Platform properties PLATFORM_WIDTH = 100 PLATFORM_HEIGHT = 20 PLATFORM_COLOR = RED PLATFORM_GAP = 200 # Initial gap between generated platforms MIN_PLATFORM_WIDTH = 50 # Minimum platform width MIN_PLATFORM_GAP = 150 # Minimum gap between platforms SCORE_THRESHOLD = 10 # Score threshold to trigger platform size adjustment PLATFORM_DECREASE_STEP = 5 # Step to decrease platform width COIN_DECREASE_STEP = 2 # Step to decrease coin size # Variables score = 0 high_score = 0 new_high_score = False # Create the screen screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("Simple Platformer") clock = pygame.time.Clock() class Player(pygame.sprite.Sprite): def __init__(self, color=DEFAULT_PLAYER_COLOR, speed=DEFAULT_PLAYER_SPEED): super().__init__() self.image = pygame.Surface((PLAYER_WIDTH, PLAYER_HEIGHT)) self.image.fill(color) self.rect = self.image.get_rect() self.rect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2) self.vel_y = 0 self.speed = speed self.color = color def update(self): keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: self.rect.x -= self.speed if keys[pygame.K_RIGHT]: self.rect.x += self.speed # Apply gravity self.vel_y += GRAVITY self.rect.y += self.vel_y # Check collisions with platforms platform_collision = pygame.sprite.spritecollide(self, platforms, False) for platform in platform_collision: if self.vel_y > 0: self.rect.bottom = platform.rect.top # Adjust position when falling self.vel_y = 0 elif self.vel_y < 0: self.rect.top = platform.rect.bottom self.vel_y = 0 # Check if player falls off the screen if self.rect.top > SCREEN_HEIGHT: game_over() # Jumping if keys[pygame.K_SPACE] and platform_collision: self.vel_y = JUMP_FORCE class Platform(pygame.sprite.Sprite): def __init__(self, x, y, width=PLATFORM_WIDTH, height=PLATFORM_HEIGHT): super().__init__() self.image = pygame.Surface((width, height)) self.image.fill(PLATFORM_COLOR) self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y class Coin(pygame.sprite.Sprite): def __init__(self, x, y, size=(100, 10)): super().__init__() self.image = pygame.Surface(size) self.image.fill((255, 255, 0)) # Yellow color for coin self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y # Sprite groups all_sprites = pygame.sprite.Group() platforms = pygame.sprite.Group() coins = pygame.sprite.Group() # Create platforms platform_list = [(0, SCREEN_HEIGHT - 40), (SCREEN_WIDTH // 2 - 50, SCREEN_HEIGHT // 2), (SCREEN_WIDTH * 3 // 4, SCREEN_HEIGHT * 3 // 4)] for platform_pos in platform_list: platform = Platform(*platform_pos) all_sprites.add(platform) platforms.add(platform) # Create player player = Player() all_sprites.add(player) # Function to spawn coins def spawn_coin(x, y, platform_width): # Check if there are any coins at the specified location if not any(coin.rect.collidepoint(x, y) for coin in coins): coin_size = max(10, platform_width - COIN_DECREASE_STEP * (score // SCORE_THRESHOLD)) coin = Coin(x, y, size=(coin_size, 10)) coins.add(coin) all_sprites.add(coin) # Function to display game over screen def game_over(): global high_score, new_high_score screen.fill(BLACK) game_over_font = pygame.font.Font(None, 64) game_over_text = game_over_font.render("GAME OVER", True, WHITE) screen.blit(game_over_text, (SCREEN_WIDTH // 2 - 150, SCREEN_HEIGHT // 2 - 50)) score_font = pygame.font.Font(None, 36) score_text = score_font.render("Score: " + str(score), True, WHITE) screen.blit(score_text, (SCREEN_WIDTH // 2 - 50, SCREEN_HEIGHT // 2 + 50)) # Adjusted position # Check if it's a new high score if score > high_score: high_score = score new_high_score = True if new_high_score: new_high_score_text = score_font.render("New High Score!", True, GREEN) screen.blit(new_high_score_text, (SCREEN_WIDTH // 2 - 100, SCREEN_HEIGHT // 2 + 100)) # Adjusted position else: high_score_text = score_font.render("High Score: " + str(high_score), True, WHITE) screen.blit(high_score_text, (SCREEN_WIDTH // 2 - 75, SCREEN_HEIGHT // 2 + 100)) # Adjusted position pygame.display.flip() # Wait for space bar press to restart wait_for_restart() # Function to wait for space bar press to restart def wait_for_restart(): global new_high_score waiting = True while waiting: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: # Reset game waiting = False new_high_score = False reset_game() # Function to reset the game def reset_game(): global score score = 0 player.rect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2) all_sprites.empty() platforms.empty() coins.empty() # Recreate platforms for platform_pos in platform_list: platform = Platform(*platform_pos) all_sprites.add(platform) platforms.add(platform) # Re-add player to sprite groups all_sprites.add(player) # Respawn initial coin spawn_coin(platform.rect.centerx - 50, platform.rect.centery - 12, PLATFORM_WIDTH) # Main game loop def main(return_to_title_page_callback): global score, new_high_score running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: # Check for Esc key press running = False # Update all_sprites.update() # Check for collision between player and coins coin_collision = pygame.sprite.spritecollide(player, coins, True) if coin_collision: score += 1 # Adjust the viewport to follow the player viewport_x = max(0, player.rect.centerx - SCREEN_WIDTH // 2) viewport_y = 0 # You can adjust this if you want vertical scrolling # Generate platforms to the right as the player travels right_most_platform = max(platforms, key=lambda p: p.rect.right) if right_most_platform.rect.right < viewport_x + SCREEN_WIDTH + PLATFORM_GAP: new_platform_x = right_most_platform.rect.right + PLATFORM_GAP new_platform_y = random.randint(SCREEN_HEIGHT // 2, SCREEN_HEIGHT - 100) # Adjust platform size and gap if score reaches threshold if score >= SCORE_THRESHOLD: platform_width = max(MIN_PLATFORM_WIDTH, right_most_platform.rect.width - PLATFORM_DECREASE_STEP) platform_gap = max(MIN_PLATFORM_GAP, PLATFORM_GAP - PLATFORM_DECREASE_STEP) else: platform_width = PLATFORM_WIDTH platform_gap = PLATFORM_GAP new_platform = Platform(new_platform_x, new_platform_y, width=platform_width) platforms.add(new_platform) # Decrease coin size coin_size = max(10, 100 - COIN_DECREASE_STEP * (score // SCORE_THRESHOLD)) spawn_coin(new_platform.rect.centerx - new_platform.rect.width // 2, new_platform.rect.centery - 12, new_platform.rect.width) all_sprites.add(new_platform) # Draw screen.fill(WHITE) # Draw coins first for sprite in coins: screen.blit(sprite.image, sprite.rect.move(-viewport_x, -viewport_y)) # Draw platforms next for sprite in platforms: screen.blit(sprite.image, sprite.rect.move(-viewport_x, -viewport_y)) # Draw the player for sprite in all_sprites: if sprite not in coins and sprite not in platforms: screen.blit(sprite.image, sprite.rect.move(-viewport_x, -viewport_y)) # Draw score score_font = pygame.font.Font(None, 36) score_text = score_font.render("Score: " + str(score), True, BLACK) screen.blit(score_text, (10, 10)) pygame.display.flip() clock.tick(FPS) return_to_title_page_callback() if __name__ == "__main__": main()