模拟极光现象:借助 Pygame 或 turtle,绘制出色彩斑斓、动态变化的极光形状,在屏幕上展示极光在夜空中舞动的效果。
import pygame
import math
import random
import colorsys
from pygame.locals import *
# 初始化Pygame
pygame.init()
pygame.display.set_caption("极光模拟器")
# 屏幕设置
SCREEN_WIDTH, SCREEN_HEIGHT = 1280, 720
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), FULLSCREEN | HWSURFACE | DOUBLEBUF)
clock = pygame.time.Clock()
# 颜色转换工具
def hsl_to_rgb(h, s, l):
return tuple(round(i * 255) for i in colorsys.hls_to_rgb(h, l, s))
# 极光粒子类
class AuroraParticle:
def __init__(self, layer):
self.layer = layer # 层级(0-2)
self.reset()
def reset(self):
# 基础参数
self.x = random.uniform(-SCREEN_WIDTH * 0.2, SCREEN_WIDTH * 1.2)
self.y = SCREEN_HEIGHT * random.uniform(0.1, 0.4)
self.base_y = self.y
self.speed = random.uniform(0.3, 1.5) * (3 - self.layer)
# 颜色参数
self.hue = random.uniform(0.2, 0.35) # 主色调(青绿色范围)
self.saturation = random.uniform(0.6, 0.9)
self.alpha = random.randint(30, 150)
# 动态参数
self.phase = random.uniform(0, 2 * math.pi)
self.amplitude = SCREEN_HEIGHT * 0.05 * (self.layer + 1)
self.wave_speed = random.uniform(0.01, 0.03)
def update(self):
# 水平移动
self.x += self.speed
if self.x > SCREEN_WIDTH * 1.2:
self.x = -SCREEN_WIDTH * 0.2
# 垂直波动
self.y = self.base_y + math.sin(pygame.time.get_ticks() * self.wave_speed + self.phase) * self.amplitude
# 颜色变化
self.hue += random.uniform(-0.001, 0.001)
self.hue = max(0.15, min(0.45, self.hue))
self.alpha = 100 + int(math.sin(pygame.time.get_ticks() * 0.005) * 50)
# 星空粒子类
class Star:
def __init__(self):
self.x = random.randint(0, SCREEN_WIDTH)
self.y = random.randint(0, SCREEN_HEIGHT)
self.size = random.uniform(0.5, 2.5)
self.intensity = random.random()
def draw(self):
brightness = 150 + int(math.sin(pygame.time.get_ticks() * 0.001 + self.x) * 100)
color = (brightness, brightness, brightness)
pygame.draw.circle(screen, color, (self.x, self.y), self.size)
# 初始化极光粒子
aurora_layers = [[] for _ in range(3)]
for layer in range(3):
for _ in range(150):
aurora_layers[layer].append(AuroraParticle(layer))
# 初始化星空
stars = [Star() for _ in range(200)]
# 主循环
running = True
while running:
# 事件处理
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
running = False
# 绘制背景
screen.fill((0, 0, 20)) # 深蓝色夜空
# 绘制星空
for star in stars:
star.draw()
# 绘制极光(从底层到顶层)
for layer in [2, 1, 0]:
for p in aurora_layers[layer]:
# 更新粒子
p.update()
# 计算颜色
color = hsl_to_rgb(p.hue, p.saturation, 0.5)
alpha_color = color + (p.alpha,)
# 创建透明表面
surf = pygame.Surface((30, 100), pygame.SRCALPHA)
# 绘制光带(渐变透明)
for i in range(30):
alpha = int(p.alpha * (1 - abs(15 - i) / 15))
pygame.draw.line(
surf,
color + (alpha,),
(i, 0),
(i, 100),
1
)
# 旋转并绘制到屏幕
angle = math.sin(pygame.time.get_ticks() * 0.001 + p.x * 0.01) * 5
rotated = pygame.transform.rotate(surf, angle)
screen.blit(rotated, (p.x - rotated.get_width() // 2, p.y - rotated.get_height() // 2))
# 绘制前景山脉
mountain_surf = pygame.Surface((SCREEN_WIDTH, 200), pygame.SRCALPHA)
for x in range(0, SCREEN_WIDTH, 20):
height = 100 + math.sin(x * 0.01) * 30
pygame.draw.polygon(
mountain_surf,
(0, 30, 0, 200),
[(x, 200), (x + 10, 200 - height), (x + 20, 200)]
)
screen.blit(mountain_surf, (0, SCREEN_HEIGHT - 200))
# 更新显示
pygame.display.flip()
clock.tick(60)
pygame.quit()