2022-10-12    2025-12-20    2137 字  5 分钟

如何使用hugo

import pygame  
import random  
import math  
import sys  
import string  
  
# 初始化 Pygamepygame.init()  
  
# 设置窗口尺寸  
WIDTH, HEIGHT = 1600, 900  
screen = pygame.display.set_mode((WIDTH, HEIGHT))  
pygame.display.set_caption("Python Fireworks with Letters")  
  
# 颜色定义  
BLACK = (0, 0, 0)  
WHITE = (255, 255, 255)  
COLORS = [  
    (255, 50, 50),  # 红色  
    (50, 255, 50),  # 绿色  
    (50, 50, 255),  # 蓝色  
    (255, 255, 50),  # 黄色  
    (255, 50, 255),  # 紫色  
    (50, 255, 255),  # 青色  
    (255, 150, 50),  # 橙色  
    (255, 255, 255)  # 白色  
]  
  
# 字母列表(可以自定义)  
LETTERS = ["H3C", "IMO"]  
# LETTERS =  ["H", "3", "C"]  
FONT_SIZE = 50  
HOLLOW_THICKNESS = 1  # 镂空字母的轮廓厚度  
  
DOT_SPACING = 2  # 1=连续,2=隔1点,3=隔2点,以此类推  
# ========== 新增:背景图加载 ==========def load_background_image(image_path, width, height):  
    """加载并缩放背景图"""  
    try:  
        # 加载图片  
        bg_image = pygame.image.load(image_path).convert_alpha()  
        # 缩放图片到窗口尺寸  
        bg_image = pygame.transform.scale(bg_image, (width, height))  
        return bg_image  
    except pygame.error as e:  
        print(f"无法加载背景图: {e}")  
        print("将使用黑色背景替代")  
        # 创建黑色背景  
        bg_image = pygame.Surface((width, height))  
        bg_image.fill(BLACK)  
        return bg_image  
  
# 加载背景图(请替换为你的背景图路径)  
# 可以使用:  
# 1. 绝对路径:"C:/images/background.jpg"  
# 2. 相对路径:"background.jpg"(图片放在代码同一目录)  
# 3. 留空使用黑色背景  
BACKGROUND_IMAGE_PATH = "bg.png"  # 修改这里为你的背景图路径  
background = load_background_image(BACKGROUND_IMAGE_PATH, WIDTH, HEIGHT)  
# 字母粒子类  
class LetterParticle:  
    def __init__(self, x, y, letter, color, velocity_x, velocity_y, gravity=0.1, decay=0.97):  
        self.x = x  
        self.y = y  
        self.letter = letter  
        self.color = color  
        self.velocity_x = velocity_x  
        self.velocity_y = velocity_y  
        self.gravity = gravity  
        self.decay = decay  
        self.lifetime = 255  # 用于淡出效果  
        self.rotation = random.uniform(0, 360)  
        self.rotation_speed = random.uniform(-2, 2)  
        self.rotate = random.random() < 0.8  
        if random.random() < 0.1:  
            self.font = pygame.font.SysFont(None, 150)  
            self.rotate = False  
        else:  
            self.font = pygame.font.SysFont(None, FONT_SIZE)  
        self.scale = 1.0  
        # 亮度变化  
        self.brightness = 255  
        self.brightness_speed = random.uniform(1, 2)  
        self.scale_decay = 0.99  
  
  
    def update(self):  
        self.x += self.velocity_x  
        self.y += self.velocity_y  
        self.velocity_y += self.gravity  
        self.velocity_x *= self.decay  
        self.velocity_y *= self.decay  
        self.lifetime -= 2  
        self.rotation += self.rotation_speed  
        self.scale *= self.scale_decay  
  
    def draw(self, surface):  
        if self.lifetime > 0 and self.brightness > 0:  
            # 计算当前透明度  
            alpha = max(0, min(255, self.lifetime * self.brightness / 255))  
  
            # 1. 绘制镂空字符  
            hollow_surface = self.draw_hollow_text(  
                surface, self.letter, (0, 0), self.color, self.font,  
                HOLLOW_THICKNESS, dot_spacing=2  # dot_spacing=2 是隔1个点绘制  
            )  
  
            # 2. 应用缩放  
            new_size = (int(hollow_surface.get_width() * self.scale),  
                        int(hollow_surface.get_height() * self.scale))  
            if new_size[0] > 0 and new_size[1] > 0:  
                hollow_surface = pygame.transform.scale(hollow_surface, new_size)  
  
            # 3. 应用旋转  
            if self.rotate:  
                hollow_surface = pygame.transform.rotate(hollow_surface, self.rotation)  
  
            # 4. 设置透明度  
            hollow_surface.set_alpha(alpha)  
  
            # 5. 绘制光晕效果(镂空字母的光晕更柔和)  
            # if alpha > 100:  
            #     glow_size = int(hollow_surface.get_width() * 1.1)            #            #     glow_surface = pygame.Surface((glow_size, glow_size), pygame.SRCALPHA)            #     # 绘制渐变光晕  
            #     for r in range(glow_size // 2, 0, -1):  
            #         glow_alpha = int(alpha * (r / (glow_size // 2)) / 20)  # 把 /10 改成 /20,让光晕更淡  
            #         # glow_alpha = int(alpha * (r / (glow_size // 2)) / 10)  
            #         if glow_alpha > 0:            #             pygame.draw.circle(            #                 glow_surface, (*self.color[:3], glow_alpha),            #                 (glow_size // 2, glow_size // 2), r            #             )            #     glow_rect = glow_surface.get_rect(center=(int(self.x), int(self.y)))            #     surface.blit(glow_surface, glow_rect)  
            # 6. 绘制镂空字符  
            text_rect = hollow_surface.get_rect(center=(int(self.x), int(self.y)))  
            surface.blit(hollow_surface, text_rect)  
  
    def is_dead(self):  
        return self.lifetime <= 0 or self.y > HEIGHT + 50 or self.scale < 0.3  
  
    def draw_hollow_text(self, surface, text, pos, color, font, thickness=2, dot_spacing=2):  
        """绘制点状镂空文字的核心方法  
        :param thickness: 轮廓厚度  
        :param dot_spacing: 点之间的间隔(越小越密,1=连续,2=隔1个点,3=隔2个点)  
        """        # 1. 先渲染实心文字作为掩码  
        text_surface = font.render(text, True, WHITE)  
        # 2. 获取文字的掩码(轮廓)  
        mask = pygame.mask.from_surface(text_surface)  
        # 3. 创建新的Surface用于绘制轮廓  
        hollow_surface = pygame.Surface(text_surface.get_size(), pygame.SRCALPHA)  
  
        # 4. 遍历掩码,绘制点状轮廓像素  
        for x in range(text_surface.get_width()):  
            for y in range(text_surface.get_height()):  
                if mask.get_at((x, y)):  
                    # 检查周围像素是否非掩码(轮廓边缘)  
                    is_edge = False  
                    # 上下左右检测  
                    for dx in [-1, 0, 1]:  
                        for dy in [-1, 0, 1]:  
                            if 0 <= x + dx < text_surface.get_width() and 0 <= y + dy < text_surface.get_height():  
                                if not mask.get_at((x + dx, y + dy)):  
                                    is_edge = True  
                                    break                        if is_edge:  
                            break  
  
                    # 只绘制轮廓边缘(点状效果)  
                    if is_edge:  
                        # 按间隔绘制点(x+y的和对间隔取模,形成均匀点状)  
                        if (x + y) % (dot_spacing + 1) == 0:  
                            # 绘制点状轮廓(可控制厚度)  
                            for dx in range(-thickness // 2, thickness // 2 + 1):  
                                for dy in range(-thickness // 2, thickness // 2 + 1):  
                                    if 0 <= x + dx < hollow_surface.get_width() and 0 <= y + dy < hollow_surface.get_height():  
                                        # 额外随机点效果(可选)  
                                        # if random.random() > 0.2:  # 随机跳过一些点,更自然  
                                        hollow_surface.set_at((x + dx, y + dy), color)  
  
        return hollow_surface  
  
  
# 烟花粒子类  
class Particle:  
    def __init__(self, x, y, color, velocity_x, velocity_y, radius=2, gravity=0.1, decay=0.97):  
        self.x = x  
        self.y = y  
        self.color = color  
        self.velocity_x = velocity_x  
        self.velocity_y = velocity_y  
        self.radius = radius  
        self.gravity = gravity  
        self.decay = decay  
        self.lifetime = 255  
  
    def update(self):  
        self.x += self.velocity_x  
        self.y += self.velocity_y  
        self.velocity_y += self.gravity  
        self.velocity_x *= self.decay  
        self.velocity_y *= self.decay  
        self.lifetime -= 2  
  
    def draw(self, surface):  
        if self.lifetime > 0:  
            alpha = max(0, self.lifetime)  
            pygame.draw.circle(surface, self.color,  
                               (int(self.x), int(self.y)),  
                               max(1, int(self.radius * self.lifetime / 255)))  
  
    def is_dead(self):  
        return self.lifetime <= 0 or self.y > HEIGHT + 10  
  
  
# 烟花类  
class Firework:  
    def __init__(self, x, y):  
        self.x = x  
        self.y = y  
        self.color = random.choice(COLORS)  
        self.velocity_y = random.uniform(-12, -8)  
        self.velocity_x = random.uniform(-1, 1)  
        self.gravity = 0.1  
        self.particles = []  
        self.letter_particles = []  # 新增:字母粒子列表  
        self.exploded = False  
        self.explosion_height = random.randint(100, 200)  
        self.explosion_power = random.randint(80, 150)  
        self.has_letters = random.random() < 0.8  # 50%的几率包含字母  
        # self.has_letters =True  
  
    def update(self):  
        if not self.exploded:  
            self.velocity_y += self.gravity  
            self.y += self.velocity_y  
            self.x += self.velocity_x  
  
            if random.random() < 0.3:  
                self.particles.append(  
                    Particle(self.x, self.y, self.color,  
                             random.uniform(-0.5, 0.5),  
                             random.uniform(-0.5, 0.5),  
                             radius=1.5, gravity=0.05, decay=0.9)  
                )  
  
            if self.velocity_y >= 0 or self.y <= self.explosion_height:  
                self.explode()  
        else:  
            for particle in self.particles[:]:  
                particle.update()  
                if particle.is_dead():  
                    self.particles.remove(particle)  
  
            # 更新字母粒子  
            for letter_particle in self.letter_particles[:]:  
                letter_particle.update()  
                if letter_particle.is_dead():  
                    self.letter_particles.remove(letter_particle)  
  
    def explode(self):  
        self.exploded = True  
        num_particles = self.explosion_power  
  
        # 创建普通粒子  
        for _ in range(num_particles):  
            angle = random.uniform(0, math.pi * 2)  
            speed = random.uniform(1, 5)  
            velocity_x = math.cos(angle) * speed  
            velocity_y = math.sin(angle) * speed  
  
            color_variation = random.randint(-30, 30)  
            color = (  
                min(255, max(0, self.color[0] + color_variation)),  
                min(255, max(0, self.color[1] + color_variation)),  
                min(255, max(0, self.color[2] + color_variation))  
            )  
  
            self.particles.append(  
                Particle(self.x, self.y, color, velocity_x, velocity_y,  
                         radius=random.uniform(1.5, 3.5),  
                         gravity=0.1, decay=0.96)  
            )  
  
        # 创建字母粒子(如果启用)  
        if self.has_letters:  
            # num_letters = random.randint(3, 8)  
            num_letters = 1  
            for _ in range(num_letters):  
                angle = random.uniform(0, math.pi * 2)  
                speed = random.uniform(0.5, 3)  
                velocity_x = math.cos(angle) * speed  
                velocity_y = math.sin(angle) * speed  
  
                letter = random.choice(LETTERS)  
  
                # 字母颜色可以稍微不同  
                letter_color = (  
                    min(255, max(0, self.color[0] + random.randint(-50, 50))),  
                    min(255, max(0, self.color[1] + random.randint(-50, 50))),  
                    min(255, max(0, self.color[2] + random.randint(-50, 50)))  
                )  
  
                self.letter_particles.append(  
                    LetterParticle(self.x, self.y, letter, letter_color,  
                                   velocity_x, velocity_y,  
                                   gravity=0.08, decay=0.95)  
                )  
  
    def draw(self, surface):  
        if not self.exploded:  
            pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), 3)  
  
        # 绘制普通粒子  
        for particle in self.particles:  
            particle.draw(surface)  
  
        # 绘制字母粒子  
        for letter_particle in self.letter_particles:  
            letter_particle.draw(surface)  
  
    def is_dead(self):  
        return self.exploded and len(self.particles) == 0 and len(self.letter_particles) == 0  
  
  
# 星星背景类(保持不变)  
class Star:  
    def __init__(self):  
        self.x = random.randint(0, WIDTH)  
        self.y = random.randint(0, HEIGHT)  
        self.size = random.uniform(0.1, 1.5)  
        self.brightness = random.randint(100, 255)  
        self.twinkle_speed = random.uniform(0.01, 0.05)  
        self.twinkle_offset = random.uniform(0, math.pi * 2)  
  
    def draw(self, surface, time):  
        twinkle = (math.sin(time * self.twinkle_speed + self.twinkle_offset) + 1) / 2  
        current_brightness = int(self.brightness * (0.7 + 0.3 * twinkle))  
        color = (current_brightness, current_brightness, current_brightness)  
        pygame.draw.circle(surface, color, (int(self.x), int(self.y)), self.size)  
  
  
# 主函数  
def main():  
    clock = pygame.time.Clock()  
    fireworks = []  
    stars = [Star() for _ in range(150)]  
    time = 0  
    font = pygame.font.SysFont(None, 36)  
  
    # 添加初始烟花  
    for _ in range(3):  
        fireworks.append(Firework(random.randint(100, WIDTH - 100), HEIGHT))  
  
    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:  
                    running = False  
                elif event.key == pygame.K_SPACE:  
                    for _ in range(5):  
                        fireworks.append(Firework(random.randint(100, WIDTH - 100), HEIGHT))  
                elif event.key == pygame.K_l:  # L键:强制生成带字母的烟花  
                    for _ in range(3):  
                        fw = Firework(random.randint(100, WIDTH - 100), HEIGHT)  
                        fw.has_letters = True  # 强制包含字母  
                        fireworks.append(fw)  
            elif event.type == pygame.MOUSEBUTTONDOWN:  
                if event.button == 1:  
                    fireworks.append(Firework(event.pos[0], HEIGHT))  
                elif event.button == 3:  # 右键:生成带字母的烟花  
                    fw = Firework(event.pos[0], HEIGHT)  
                    fw.has_letters = True  
                    fireworks.append(fw)  
  
        # 随机添加新烟花  
        if random.random() < 0.03 and len(fireworks) < 20:  
            fireworks.append(Firework(random.randint(100, WIDTH - 100), HEIGHT))  
  
        # 更新烟花  
        for firework in fireworks[:]:  
            firework.update()  
            if firework.is_dead():  
                fireworks.remove(firework)  
  
        # 更新星星  
        time += 0.05  
        # ========== 修改:绘制背景图 ==========        # 先绘制背景图  
        screen.blit(background, (0, 0))  
        # 如果需要背景图半透明效果,可以添加:  
        # overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)  
        # overlay.fill((0, 0, 0, 100))  # 黑色半透明遮罩,最后一个值是透明度(0-255)  
        # screen.blit(overlay, (0, 0))  
        # 绘制背景  
        # screen.fill(BLACK)  
  
        # 绘制星星  
        for star in stars:  
            star.draw(screen, time)  
  
        # 绘制烟花  
        for firework in fireworks:  
            firework.draw(screen)  
  
        # 显示说明文字  
        instructions = [  
            "Left Click: Add Firework",  
            "Right Click: Add Firework with Letters",  
            "Space: Add 5 Fireworks",  
            "L: Add 3 Letter Fireworks",  
            "ESC: Exit"  
        ]  
  
        # for i, text in enumerate(instructions):  
        #     text_surface = font.render(text, True, WHITE)        #     screen.blit(text_surface, (10, 10 + i * 30))  
        # 显示烟花和字母数量  
        letter_count = sum(len(fw.letter_particles) for fw in fireworks)  
        count_text = f"Fireworks: {len(fireworks)}  Letters: {letter_count}"  
        count_surface = font.render(count_text, True, WHITE)  
        # screen.blit(count_surface, (WIDTH - 300, 10))  
  
        pygame.display.flip()  
        clock.tick(60)  
  
    pygame.quit()  
    sys.exit()  
  
  
if __name__ == "__main__":  
    main()