使用 Pygame 制作圣诞树

举报
Damon小智 发表于 2025/01/31 13:44:12 2025/01/31
205 0 0
【摘要】 圣诞节到来之际,来给自己写一个圣诞树小动画吧!我们可以利用 Pygame 的绘图功能,轻松地在 2D 屏幕上绘制各种几何形状,并为圣诞树加上灯光闪烁、装饰品等效果。本篇将带领你实现一个简易版本的“屏幕圣诞树”,效果虽然比较基础,但足以体验使用 Python 进行可视化和动画开发的乐趣。

1. 前言

圣诞节到来之际,来给自己写一个圣诞树小动画吧!我们可以利用 Pygame 的绘图功能,轻松地在 2D 屏幕上绘制各种几何形状,并为圣诞树加上灯光闪烁、装饰品等效果。本篇将带领你实现一个简易版本的“屏幕圣诞树”,效果虽然比较基础,但足以体验使用 Python 进行可视化和动画开发的乐趣。

2. 环境准备

  1. Python 3.x
  2. Pygame 库:如果尚未安装,可以在命令行执行:
    pip install pygame
    
  3. 支持图形界面的系统环境:Windows、macOS、Linux 桌面都可行。

安装完成后,先简单测试一下 import pygame,没有报错则说明安装成功。


3. 实现思路

为了在屏幕中呈现一棵“圣诞树”并进行简单的动画,可以按照下列思路:

  1. 背景:设置一个符合圣诞氛围的背景色或背景图。
  2. 树干与树冠
    • 树干通常是一个棕色矩形;
    • 树冠可以由多个叠加的绿色三角形或梯形组成,或者干脆用一个多边形/贝塞尔曲线模拟松针形状。
  3. 装饰品与灯光
    • 在树上随机/固定位置放置一些圆形或小图标,模拟彩球、雪花、铃铛、礼物等等。
    • 对于灯光,可以让它们随时间闪烁,时亮时暗。
  4. 顶端星星:在树冠顶端放一个闪亮的五角星。
  5. 动画循环
    • 每帧刷新时,重绘树和装饰;
    • 通过简单计时或随机函数让灯光闪烁,使其呈现动感效果。
  6. 事件监听
    • 监听关闭窗口事件,当用户点击关闭按钮时,退出游戏循环。

接下来进入实际的示例代码环节。


4. 示例代码

将以下代码保存为 christmas_tree.py 并运行,即可看到效果。你可以根据自己的需求进行修改和美化。

import pygame
import random
import math

# 屏幕大小
WIDTH, HEIGHT = 800, 600

# 一些颜色定义
WHITE  = (255, 255, 255)
BLACK  = (0, 0, 0)
GREEN  = (34, 139, 34)
BROWN  = (139, 69, 19)
YELLOW = (255, 215, 0)
RED    = (255, 0, 0)
BLUE   = (0, 0, 255)

# 初始化 Pygame
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("圣诞树 - Pygame 示例")
clock = pygame.time.Clock()

# 定义装饰灯光类
class Light:
    """
    树上的一盏小灯
    """
    def __init__(self, x, y, color, radius=5):
        self.x = x
        self.y = y
        self.color = color
        self.radius = radius
        # 初始亮度状态
        self.blink_state = True

    def update(self, frame_count):
        """
        让灯每隔若干帧闪烁一次,可根据 frame_count 或随机数来控制频率
        """
        if frame_count % 30 == 0:
            self.blink_state = not self.blink_state

    def draw(self, surface):
        if self.blink_state:
            pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), self.radius)
        else:
            # 暗灯时可以换成暗色 / 或者不画
            dark_color = (self.color[0] // 3, self.color[1] // 3, self.color[2] // 3)
            pygame.draw.circle(surface, dark_color, (int(self.x), int(self.y)), self.radius)
def draw_tree(surface):
    """
    绘制静态部分:树干与树冠
    你可以根据喜好更改树的形状。
    """
    # 1) 树干
    trunk_width = 40
    trunk_height = 80
    trunk_x = WIDTH // 2 - trunk_width // 2
    trunk_y = HEIGHT - 100
    pygame.draw.rect(surface, BROWN, (trunk_x, trunk_y, trunk_width, trunk_height))

    # 2) 树冠(用多个绿色三角叠加)
    # 顶层小三角
    pygame.draw.polygon(surface, GREEN, [
        (WIDTH//2, 80),    # 树顶
        (WIDTH//2 - 50, 180),
        (WIDTH//2 + 50, 180)
    ])
    # 中层中三角
    pygame.draw.polygon(surface, GREEN, [
        (WIDTH//2, 140),
        (WIDTH//2 - 80, 260),
        (WIDTH//2 + 80, 260)
    ])
    # 底层大三角
    pygame.draw.polygon(surface, GREEN, [
        (WIDTH//2, 200),
        (WIDTH//2 - 110, 360),
        (WIDTH//2 + 110, 360)
    ])

    # 3) 在树顶绘制一颗星星
    draw_star(surface, (WIDTH//2, 70), 20, 10, YELLOW)
def draw_star(surface, center, outer_radius, inner_radius, color):
    """
    绘制一个五角星。outer_radius 控制外顶点距离中心的半径,
    inner_radius 控制内凹点距离中心的半径。
    """
    cx, cy = center
    points = []
    # 五角星通常有10个点:外点、内点交替
    for i in range(10):
        angle = math.radians(36 * i - 90)  # -90 为了让星星尖朝上
        if i % 2 == 0:
            r = outer_radius
        else:
            r = inner_radius
        x = cx + r * math.cos(angle)
        y = cy + r * math.sin(angle)
        points.append((x, y))
    pygame.draw.polygon(surface, color, points)
def main():
    # 背景色
    bg_color = (30, 30, 60)

    # 随机生成若干灯光装饰在树上
    # 例如在三角区域内或自定义坐标范围
    lights = []
    # 简化做法:我们手动给定一个大概的三角区域范围
    # 当然你可以根据多边形逻辑来更精确地分布
    for _ in range(30):
        # 随机 x, y 范围要在大三角区内
        x = random.randint(WIDTH//2 - 100, WIDTH//2 + 100)
        y = random.randint(140, 360)
        # 随机挑选一个鲜艳颜色
        color_choice = random.choice([RED, BLUE, YELLOW, (0, 255, 0)])
        lights.append(Light(x, y, color_choice, radius=5))

    running = True
    frame_count = 0
    while running:
        clock.tick(30)
        frame_count += 1

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        # 更新灯光闪烁
        for light in lights:
            light.update(frame_count)

        # 绘制
        screen.fill(bg_color)
        # 先画树
        draw_tree(screen)
        # 再画灯光(在树身上,保证不被后续覆盖)
        for light in lights:
            light.draw(screen)

        pygame.display.flip()

    pygame.quit()

if __name__ == "__main__":
    main()

  • draw_tree(surface)
    • 先用 pygame.draw.rect 画树干;
    • 然后依次画几个绿色三角形叠加,简单地模拟圣诞树的层层枝叶;
    • 最后用 draw_star 函数在顶部绘制一颗五角星。
  • draw_star(surface, center, outer_radius, inner_radius, color)
    • 使用数学方法,在 360° 范围内定位五角星的 10 个顶点,偶数点半径为外圆半径、奇数点半径为内圆半径。
    • 使用 pygame.draw.polygon 一次性绘制多边形即可形成五角星。
  • Light 类
    • 用于表示树上的一盏灯,含有位置、颜色、半径,以及 blink_state(灯是否点亮)。
    • 每隔一定帧数(在本示例中是 30 帧)就进行一次 self.blink_state = not self.blink_state 切换,造成闪烁效果。
  • 随机灯光生成
    • 简易写法:在大三角下部使用一定范围的随机 x、y 坐标放置彩灯;
    • 可扩展的写法:可以根据树的多边形形状进行“点在多边形内”的计算,将彩灯更准确地贴合树形。
  • 动画循环
    • 不断刷新帧(while running),更新灯光状态,绘制背景、树和灯光。
    • 用户点击关闭后退出循环,调用 pygame.quit() 清理资源。

5. 运行效果

image.png


6. 总结

通过本篇示例,你已经见识了使用 Pygame 绘制 2D 圣诞树并实现简单灯光闪烁的流程。从基础的多边形绘制开始,到为灯光加上动画闪烁,都是 Pygame 里常见的 游戏循环图形绘制 技巧。你可以自由发挥想象,对圣诞树进行更多装饰和功能扩展,让这个节日小作品更加绚丽夺目。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。