1. 前言
圣诞节到来之际,来给自己写一个圣诞树小动画吧!我们可以利用 Pygame 的绘图功能,轻松地在 2D 屏幕上绘制各种几何形状,并为圣诞树加上灯光闪烁、装饰品等效果。本篇将带领你实现一个简易版本的“屏幕圣诞树”,效果虽然比较基础,但足以体验使用 Python 进行可视化和动画开发的乐趣。
2. 环境准备
- Python 3.x
- Pygame 库:如果尚未安装,可以在命令行执行:
pip install pygame
- 支持图形界面的系统环境:Windows、macOS、Linux 桌面都可行。
安装完成后,先简单测试一下 import pygame
,没有报错则说明安装成功。
3. 实现思路
为了在屏幕中呈现一棵“圣诞树”并进行简单的动画,可以按照下列思路:
- 背景:设置一个符合圣诞氛围的背景色或背景图。
- 树干与树冠:
- 树干通常是一个棕色矩形;
- 树冠可以由多个叠加的绿色三角形或梯形组成,或者干脆用一个多边形/贝塞尔曲线模拟松针形状。
- 装饰品与灯光:
- 在树上随机/固定位置放置一些圆形或小图标,模拟彩球、雪花、铃铛、礼物等等。
- 对于灯光,可以让它们随时间闪烁,时亮时暗。
- 顶端星星:在树冠顶端放一个闪亮的五角星。
- 动画循环:
- 每帧刷新时,重绘树和装饰;
- 通过简单计时或随机函数让灯光闪烁,使其呈现动感效果。
- 事件监听:
- 监听关闭窗口事件,当用户点击关闭按钮时,退出游戏循环。
接下来进入实际的示例代码环节。
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. 运行效果
6. 总结
通过本篇示例,你已经见识了使用 Pygame 绘制 2D 圣诞树并实现简单灯光闪烁的流程。从基础的多边形绘制开始,到为灯光加上动画闪烁,都是 Pygame 里常见的 游戏循环 与 图形绘制 技巧。你可以自由发挥想象,对圣诞树进行更多装饰和功能扩展,让这个节日小作品更加绚丽夺目。