模拟极光现象

模拟极光现象:借助 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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值