使用Pygame制作“圣诞树”

1. 前言

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

2. 环境准备

  1. Python 3.x

  2. Pygame 库:如果尚未安装,可以在命令行执行:

    bash 复制代码
    pip install pygame
  3. 支持图形界面的系统环境:Windows、macOS、Linux 桌面都可行。

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


3. 实现思路

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

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

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


4. 示例代码

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

python 复制代码
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. 运行效果


6. 总结

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

相关推荐
用户83562907805111 小时前
Python 实现 PDF 文件加密与解密方法
后端·python
用户83562907805111 小时前
使用 Python 冻结与拆分 Excel 窗格教程
后端·python
你好潘先生19 小时前
别再记命令了,用 yeero do 说句人话就能跑脚本,而且不烧 token
服务器·python·命令行
Agent_大师20 小时前
WebSocket 行情重连成功,K线缺口不会自动消失
python
荣码20 小时前
LLM结构化输出:让AI返回JSON而不是废话,我踩了4个坑
java·python
copyer_xyf20 小时前
FastAPI 如何连接 MySQL
后端·python
apocelipes1 天前
常用编程语言和库的正则表达式性能对比
c语言·c++·python·性能优化·golang·开发工具和环境
用户8356290780511 天前
使用 Python 在 PDF 中创建与管理书签
后端·python
MeixianAgent2 天前
Python 回测数据入口怎么验?历史 K 线入库前先做 5 个检查
后端·python
咕白m6252 天前
用 Python 实现一键批量查找与替换 Excel 数据
后端·python