使用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 里常见的 游戏循环图形绘制 技巧。你可以自由发挥想象,对圣诞树进行更多装饰和功能扩展,让这个节日小作品更加绚丽夺目。

相关推荐
mosquito_lover1几秒前
Python在线编辑器
python
winrisef10 分钟前
YOLOv11实时目标检测 | 摄像头视频图片文件检测
人工智能·python·深度学习·yolo·目标检测·音视频
c+猿辅导11 分钟前
python实现多路视频,多窗口播放功能
python·音视频·lua
weixin_3077791323 分钟前
在AWS上设计与实现个人财务助理的Web应用程序
人工智能·python·flask·云计算·aws
weixin_3077791329 分钟前
AWS上设计可图形化创建处理逻辑的智能电话语音客服程序的流程和关键代码
人工智能·python·自然语言处理·音视频·aws
ACGkaka_1 小时前
Java 如何覆盖第三方 jar 包中的类
java·python·jar
西农小陈1 小时前
Python-基于PyQt5,wordcloud,pillow,numpy,os,sys等的智能词云生成器
开发语言·python·小程序·pycharm·numpy·pyqt·pillow
q567315232 小时前
如何在 Canopy 中导入 scikit-learn
开发语言·python
菜狗woc2 小时前
作业二.自定义数据集使用scikit-learn中的包实现线性回归方法对其进行拟合
开发语言·python·机器学习
汤姆和佩琦2 小时前
2025-2-3-sklearn学习(50) & (51) 完结篇 零落成泥碾作尘,只有香如故。
人工智能·python·学习·机器学习·sklearn