用 Python 模拟下雨效果

article/2025/9/5 9:53:45

用 Python 模拟下雨效果

雨天别有一番浪漫情怀:淅淅沥沥的雨滴、湿润的空气、朦胧的光影……在屏幕上也能感受下雨的美妙。本文将带你用一份简单的 Python 脚本,手把手实现「下雨效果」动画。文章深入浅出,零基础也能快速上手,完整代码仅需一个脚本文件即可运行。
在这里插入图片描述


目录

  1. 前言
  2. 环境准备
  3. 雨滴模拟原理
  4. 实现思路
  5. 完整脚本讲解
  6. 完整脚本代码
  7. 运行效果
  8. 拓展思考
  9. 结语

前言

在图形编程中,常见的视觉特效之一就是雨滴下落动画。无论是游戏背景、界面装饰,还是演示特效,模拟下雨都能增添生动氛围。本示例使用 Python 结合 Pygame 库,在窗口中绘制无数条雨线,并让它们以不同速度、位置、长度滑落,形成自然的雨幕效果。整个过程非常直观,适合刚接触 Python GUI 或图形编程的新手。


环境准备

  • Python 版本:建议 3.6 及以上
  • 依赖库:Pygame

在命令行中执行:

pip install pygame

若出现安装问题,可尝试升级 pip:

pip install --upgrade pip

雨滴模拟原理

要模拟下雨效果,核心思想是:

  1. 雨滴属性

    • 位置 (x, y):雨滴当前坐标。
    • 长度 length:模拟不同距离或速度导致的雨滴长短差异。
    • 速度 speed:决定雨滴下落的快慢,可与 length 相关。
  2. 下落逻辑

    • 每帧 (frame) 更新时,让 y += speed
    • y 超出窗口底部,高度加上 length 后重置到顶部(y = -length),并随机生成新的 xlengthspeed
  3. 绘制方法

    • 在 Pygame 窗口中,用 draw.line() 绘制一条短线来代表雨滴。
    • 背景每帧需重绘为深色,以清除上一帧的残影。

实现思路

  1. 初始化

    • 导入模块、初始化 Pygame,设置窗口宽高与帧率 (FPS)。
  2. 创建雨滴列表

    • 根据需求生成多个 Raindrop 实例,存放于列表中。
  3. 主循环

    • 处理退出事件。
    • 填充背景色。
    • 遍历雨滴列表,更新位置并绘制。
    • 刷新显示并控制帧率。
  4. 优雅退出

    • 当检测到窗口关闭事件,退出循环并调用 pygame.quit()

完整脚本讲解

下面逐段讲解脚本中关键部分。

import pygame, random, sys
  • pygame:图形窗口与绘图操作。
  • random:生成随机位置与属性。
  • sys:退出程序使用。
class Raindrop:def __init__(self, screen_width, screen_height):self.screen_width  = screen_widthself.screen_height = screen_heightself.reset()
  • Raindrop 类用于封装单个雨滴。传入屏幕尺寸以便重置时随机生成坐标。
    def reset(self):self.x      = random.randint(0, self.screen_width)self.y      = random.randint(-self.screen_height, 0)self.length = random.randint(5, 15)self.speed  = random.uniform(4, 10) * (self.length / 10)
  • reset() 随机分配 xylengthspeed
  • y[-screen_height, 0] 范围随机初始,保证雨幕一开始就满屏。
  • 速度与长度挂钩,长雨滴下落更快,增强透视感。
    def fall(self):self.y += self.speedif self.y > self.screen_height:self.reset()
  • fall() 更新 y 坐标,若超出底部则重置回顶部。
    def draw(self, surface):end_y = self.y + self.lengthpygame.draw.line(surface, (180, 180, 255), (self.x, self.y), (self.x, end_y), 1)
  • 用浅蓝色 (180,180,255) 绘制细线代表雨滴。

接着是主程序部分,负责窗口创建、循环与事件处理。


完整脚本代码

请将以下代码保存为 rain.py,然后在命令行执行 python rain.py 即可查看下雨效果。

import pygame, random, sysclass Raindrop:def __init__(self, screen_width, screen_height):self.screen_width  = screen_widthself.screen_height = screen_heightself.reset()def reset(self):self.x      = random.randint(0, self.screen_width)self.y      = random.randint(-self.screen_height, 0)self.length = random.randint(5, 15)self.speed  = random.uniform(4, 10) * (self.length / 10)def fall(self):self.y += self.speedif self.y > self.screen_height:self.reset()def draw(self, surface):end_y = self.y + self.lengthpygame.draw.line(surface, (180, 180, 255), (self.x, self.y), (self.x, end_y), 1)def main():pygame.init()screen_width, screen_height = 800, 600screen = pygame.display.set_mode((screen_width, screen_height))pygame.display.set_caption("Python 雨滴模拟")clock = pygame.time.Clock()# 初始化雨滴raindrops = [Raindrop(screen_width, screen_height) for _ in range(300)]# 主循环running = Truewhile running:for event in pygame.event.get():if event.type == pygame.QUIT:running = False# 填充背景screen.fill((10, 10, 30))# 更新并绘制每个雨滴for drop in raindrops:drop.fall()drop.draw(screen)# 刷新显示pygame.display.flip()clock.tick(60)pygame.quit()sys.exit()if __name__ == "__main__":main()

运行效果

运行后,你将看到一个 800×600 的深色窗口,无数细细的浅蓝色雨滴以不同速度从顶部滑落,形成层次分明的雨幕。若想更贴近真实,可以:

  • 调整颜色:将 (180,180,255) 改为其他色值。
  • 改变雨滴数量:修改 raindrops 列表长度(300 可增可减)。
  • 添加风向:在 fall() 中改变 x 坐标,模拟风吹雨打效果。

拓展思考

  1. 视差效果
    将雨滴分为「前景」「中景」「远景」三组,分别使用不同速度、颜色与透明度,营造深度感。
  2. 撞击水面
    当雨滴落到预设的“地面”高度,可在底部绘制一圈淡淡的水花动画。
  3. 粒子系统
    为水花使用粒子系统,让每个水花粒子具有衰减、弹跳特性,更真实。

结语

本文以最简单的 Pygame 用例,向你展示如何在 Python 中模拟下雨特效。核心思路就是不断重置和重绘雨滴坐标,通过随机属性让画面更具丰富性。动手运行一下,相信你会对图形编程更加感兴趣。后续可以在此基础上加入更多效果,打造属于自己的雨天场景。祝学习愉快!


http://www.hkcw.cn/article/KXWuNYhFdY.shtml

相关文章

[PyTest-案例]

接口对象封装 1.requests和pymysql实现ihrm登录接口缺点 : 代码冗余度高,耦合度高,维护成本大 核心思想 : 代码分层 按代码功能划分 : 接口对象层 : 负责发送http请求,访问待测接口,返回响应数据测试用例层 : 调用接口,按照响应数据,断言完成测试 封装tpshop商城 普通方式…

25 字符数组与字符串及多维数组详解:定义与初始化、访问与遍历、%s 格式符、内存剖析、编程实战

1 字符数组与字符串 1.1 字符数组 字符数组是 C 语言中用于存储一系列字符的基本数据结构。其定义方式与其他类型的数组类似,使用 char 类型来指定数组的元素类型。例如: char arr[10]; // 定义一个可存储 10 个字符的数组 此数组 arr 能够存储 10 个字…

IEEE旗下2区所有SCI汇总!

本期小编统计了【IEEE旗下】2区所有期刊的最新影响因子,分区、年发文量以及投稿经验,供大家参考! 1 IEEE Journal of Selected Topics in Applied Earth Observations and Remote Sensing 【影响因子】4.7 【期刊分区】JCR1区,中…

论文略读: STREAMLINING REDUNDANT LAYERS TO COMPRESS LARGE LANGUAGE MODELS

2025 ICLR 判断模型层的重要性->剪去不重要的层(用轻量网络代替) 这种方法只减少了层数量,所以可以用常用的方法加载模型 层剪枝阶段 通过输入与输出的余弦相似度来判断各个层的重要性 具有高余弦相似度的层倾向于聚集在一起&#xff0c…

Geoserver修行记--点击geoserver服务的WMTS能力(GetCapabilities)文档显示400 null

项目场景 在进行geoserver的项目部署过程中再次遇到的问题,这里再记录一下: 我在前端调用WMTS服务的时候,我需要查看图层的能力文档,点击下图出现如下所示的情况: 点击以后出现 400:null,如下…

Codeforces Round 1027 (Div. 3)(A-E)

题面链接&#xff1a;Dashboard - Codeforces Round 1027 (Div. 3) - Codeforces A. Square Year 思路 先看数字能否被开方&#xff0c;如果能输出0 即可 代码 #include<bits/stdc.h> using namespace std;#define vcoistnt ios_base::sync_with_stdio(false); ci…

在MDK中自动部署LVGL,在stm32f407ZGT6移植LVGL-8.3,运行demo,显示label

在MDK中自动部署LVGL&#xff0c;在stm32f407ZGT6移植LVGL-8.3 一、硬件平台二、实现功能三、移植步骤1、下载LVGL-8.42、MDK中安装LVGL-8.43、配置RTE4、配置头文件 lv_conf_cmsis.h5、配置lv_port_disp_template 四、添加心跳相关文件1、在STM32CubeMX中配置TIM7的参数2、使能…

数据结构数组总结

给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0 。 示例 1&#xff1a; 输入&#xff1a;…

集成均衡功能电池保护芯片在大功率移动电源的应用,创芯微CM1341-DAT、杰华特JW3312、赛微微电CW1244、中颖SH366006

一文了解集成均衡功能电池保护IC在大功率移动电源的应用 创芯微CM1341-DAT 创芯微CM1341-DAT是一款专用于4串锂离子/磷酸铁锂电池的保护芯片&#xff0c;内置有高精度电压检测电路和电流检测电路。通过检测各节电池的电压、充放电电流及温度等信息&#xff0c;实现电池过充电…

2025年机电一体化与自动化系统国际会议(ICMAS 2025)

2025年机电一体化与自动化系统国际会议&#xff08;ICMAS 2025&#xff09; 2025 International Conference on Mechatronics and Automation Systems 一、大会信息 会议简称&#xff1a;ICMAS 2025 大会地点&#xff1a;中国南京 审稿通知&#xff1a;投稿后2-3日内通知 投稿…

Linux多线程(四)之Linux线程控制2【线程等待和线程终止】

文章目录 线程等待线程终止return退出线程pthread_exit退出线程pthread_cancel取消线程 线程等待 哪个线程先运行&#xff1f;由调度器说的算。 但是主线程一定要是最后退出&#xff01; 为什么需要线程等待&#xff1f; 已经退出的线程&#xff0c;其空间没有被释放&#…

Python自动化之selenium语句——浏览器设置显示尺寸、截图、刷新网页

目录 一、浏览器设置最大化、最小化 1.浏览器最大化 2.浏览器最小化 二、浏览器打开的位置、尺寸 1.浏览器打开位置 2.浏览器打开尺寸 三、浏览器截图 1.截图语句 2.运行成功后查看 四、刷新网页 上一节实现了打开浏览器、打开指定网址、关闭浏览器的操作&#xff0c…

Selenium的第三天打卡——Selenium应用(selenium元素选取以及浏览器操作)

Selenium 4 应用示例解析 目录 Selenium 4 应用示例解析 一、基本配置 二、浏览器设置&#xff08;这之前没有html基础的朋友可以先去了解一下html哦&#xff09; 三、元素定位方法 1.Selenium 4 元素的选中 ①开发者模式 ②观察代码 2.Selenium 4 元素抓取的核心内容…

智能仓储落地:机器人如何通过自动化减少仓库操作失误?

仓库作业的速度和准确性至关重要&#xff0c;尤其是在当前对无差错、高效作业的要求达到前所未有的环境下。每一个错误&#xff0c;无论是物品放错位置还是库存差异&#xff0c;都会在供应链中产生连锁反应&#xff0c;造成延误、增加成本&#xff0c;并最终影响客户满意度。 …

【Linux系统移植】Cortex-A8 Linux系统移植(超详细)

目录 前言 一、ARM开发板ARM简介RISC和CISCARM产品分布核心板S5pv210 SOC嵌入式系统开发方式 二、嵌入式系统组成为什么要系统移植内核移植框图 三、嵌入式开发环境搭建搭建开发环境总流程设置ubuntu与windows共享目录修改用户为root用户安装NFS服务器安装tftp服务器安装交叉编…

如何通过数据分析优化项目决策

通过数据分析优化项目决策需从明确数据分析目标、选择适当的数据分析工具、确保数据质量、建立数据驱动文化等方面入手&#xff0c;其中&#xff0c;明确数据分析目标是优化决策过程的基础&#xff0c;只有清晰明确的数据分析目标才能指导有效的数据采集与分析&#xff0c;避免…

纯前端实现图片伪3D视差效果

作者&#xff1a;vivo 互联网前端团队- Su Ning 本文通过depth-anything获取图片的深度图&#xff0c;同时基于pixi.js&#xff0c;通过着色器编程&#xff0c;实现了通过深度图驱动的伪3D效果。该方案支持鼠标/手势与手机陀螺仪双模式交互&#xff0c;在保证性能的同时&#x…

在ROS2(humble)+Gazebo+rqt下,实时显示仿真无人机的相机图像

文章目录 前言一、版本检查检查ROS2版本 二、步骤1.下载对应版本的PX4(1)检查PX4版本(2)修改文件名(3)下载正确的PX4版本 2.下载对应版本的Gazebo(1)检查Gazebo版本(2)卸载不正确的Gazebo版本(3)下载正确的Gazebo版本 3.安装bridge包4.启动 总结 前言 在ROS2的环境下&#xff…

Git的三种合并方式

在 Gitee&#xff08;码云&#xff09;中合并分支主要有三种方式&#xff1a;​普通合并&#xff08;Merge Commit&#xff09;、压缩合并&#xff08;Squash Merge&#xff09;​和变基合并&#xff08;Rebase Merge&#xff09;​。每种方式适用于不同的场景&#xff0c;各有…

微机系统-汇编语言入门

汇编语言及其程序设计 -1:汇编语言的语句格式 [名字] 操作符 操作数&#xff1b; [注释] 名字: 1. 是一种标识符。 2. 组成&#xff1a;A&#xff5e;Z&#xff0c;a&#xff5e;z&#xff1b; 0&#xff5e;9&#xff1b; 专用符号 &#xff1f;&#xff0e; _$ 3. 限制&…