import pygame import sys import math # Attempt to import gfxdraw safely try: import pygame.gfxdraw HAS_GFXDRAW = True except ImportError: HAS_GFXDRAW = False # Initialize Pygame pygame.init() # Screen settings WIDTH, HEIGHT = 800, 600 screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Platformer with Smooth Sun Rays and Shadows") # Colors WHITE = (255, 255, 255) BLUE = (50, 50, 255) GREEN = (0, 180, 0) YELLOW = (255, 255, 0) SHADOW_ALPHA = 180 # Clock clock = pygame.time.Clock() FPS = 60 # Player settings player_size = (50, 50) player_pos = pygame.Rect(300, 300, *player_size) player_speed = 5 player_vel_y = 0 gravity = 0.5 jump_strength = -10 on_ground = False # Platforms platforms = [ pygame.Rect(0, HEIGHT - 40, WIDTH, 40), pygame.Rect(200, 450, 200, 20), pygame.Rect(450, 350, 200, 20), pygame.Rect(100, 250, 150, 20) ] def cast_light_polygon(origin, obstacles, num_rays=720, ray_length=1000): """Create a soft shadow polygon by ray casting from origin.""" points = [] angle_step = 2 * math.pi / num_rays for i in range(num_rays): angle = i * angle_step dx = math.cos(angle) dy = math.sin(angle) final_point = (origin[0] + dx * ray_length, origin[1] + dy * ray_length) for step in range(0, ray_length, 5): # fine step for precision x = origin[0] + dx * step y = origin[1] + dy * step if not (0 <= x < WIDTH and 0 <= y < HEIGHT): break if any(obs.collidepoint(x, y) for obs in obstacles): final_point = (x, y) break points.append(final_point) shadow_mask = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA) shadow_mask.fill((0, 0, 0, SHADOW_ALPHA)) if HAS_GFXDRAW: pygame.gfxdraw.filled_polygon(shadow_mask, [(int(x), int(y)) for x, y in points], (0, 0, 0, 0)) else: pygame.draw.polygon(shadow_mask, (0, 0, 0, 0), [(int(x), int(y)) for x, y in points]) return shadow_mask def blur_surface(surface, scale_factor=0.5): """Blur the surface by scaling down and back up.""" size = surface.get_size() small = pygame.transform.smoothscale(surface, (int(size[0] * scale_factor), int(size[1] * scale_factor))) return pygame.transform.smoothscale(small, size) # Game loop while True: screen.fill(WHITE) # Event handling for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # Input keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: player_pos.x -= player_speed if keys[pygame.K_RIGHT]: player_pos.x += player_speed if keys[pygame.K_SPACE] and on_ground: player_vel_y = jump_strength # Gravity player_vel_y += gravity player_pos.y += player_vel_y on_ground = False # Collision for platform in platforms: if player_pos.colliderect(platform) and player_vel_y > 0: player_pos.bottom = platform.top player_vel_y = 0 on_ground = True # Lighting sun_pos = (50, 50) obstacles = platforms + [player_pos] shadow_layer = cast_light_polygon(sun_pos, obstacles) shadow_layer = blur_surface(shadow_layer) # Draw scene for platform in platforms: pygame.draw.rect(screen, GREEN, platform) pygame.draw.rect(screen, BLUE, player_pos) screen.blit(shadow_layer, (0, 0)) # Apply smoothed shadows pygame.draw.circle(screen, YELLOW, sun_pos, 20) pygame.display.flip() clock.tick(FPS)