Python:动态粒子爱心

预览

在这里插入图片描述

代码结构概述

这段代码使用了 pygame 库来创建一个动态的图形窗口,绘制一个心形图案,并在其中显示闪烁的文本。代码主要分为以下几个部分:

  1. 初始化和设置
  2. 心形曲线的计算
  3. 粒子类的定义
  4. 生成粒子
  5. 文本设置
  6. 主循环

1. 初始化和设置

import pygame
import random
import math
import os# 初始化pygame
pygame.init()# 屏幕尺寸
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Dynamic Particle Heart")
  • 导入库:首先导入所需的库,pygame 用于图形处理,random 用于生成随机数,math 用于数学计算。
  • 初始化pygame:调用 pygame.init() 来初始化所有的 pygame 模块。
  • 设置屏幕尺寸:定义窗口的宽度和高度,并创建一个窗口。
  • 设置窗口标题:使用 set_caption 设置窗口的标题。

2. 颜色定义

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
PURPLE = (128, 0, 128)  # 紫色的RGB值
  • 定义颜色:使用 RGB 颜色模式定义了白色、黑色和紫色。

3. 心形曲线的计算

# 心形方程
def heart_curve(t):x = 16 * math.sin(t) ** 3y = 13 * math.cos(t) - 5 * math.cos(2 * t) - 2 * math.cos(3 * t) - math.cos(4 * t)return x, y
  • 心形方程:定义了一个函数 heart_curve,接受一个参数 t(角度),并计算心形曲线的 x 和 y 坐标。这个公式通过三角函数生成心形的坐标。

4. 计算心形的最大宽度和高度

def get_heart_dimensions():max_x, min_x, max_y, min_y = -float('inf'), float('inf'), -float('inf'), float('inf')for i in range(0, 360, 1):angle_rad = math.radians(i)x, y = heart_curve(angle_rad)if x > max_x: max_x = xif x < min_x: min_x = xif -y > max_y: max_y = -y  # 注意:这里取负是因为pygame坐标系y轴向下if -y < min_y: min_y = -ywidth = max_x - min_xheight = max_y - min_yreturn width, height
  • 计算心形的尺寸:这个函数遍历从 0 到 360 度的每个角度,计算心形的坐标,并找到心形的最大和最小 x、y 值,以便计算出心形的宽度和高度。

5. 粒子类的定义

class Particle:def __init__(self, x, y):self.x = xself.y = yself.size = random.randint(2, 5)self.color = PURPLEself.angle = random.uniform(0, math.pi * 2)self.speed = random.uniform(1, 3)self.lifetime = random.randint(50, 100)def move(self):self.x += math.sin(self.angle) * self.speedself.y -= math.cos(self.angle) * self.speedself.size -= 0.05self.lifetime -= 1if self.size <= 0 or self.lifetime <= 0:self.reset()def reset(self):angle_rad = random.uniform(0, math.pi * 2)x, y = heart_curve(angle_rad)self.x = x * scale_factor + WIDTH // 2self.y = -y * scale_factor + HEIGHT // 2self.size = random.randint(2, 5)self.angle = random.uniform(0, math.pi * 2)self.speed = random.uniform(1, 3)self.lifetime = random.randint(50, 100)def draw(self, screen):s = pygame.Surface((self.size * 2, self.size * 2), pygame.SRCALPHA)pygame.draw.circle(s, (*self.color[:3], self.lifetime * 2.55), (self.size, self.size), self.size)screen.blit(s, (self.x - self.size, self.y - self.size))
  • 粒子类:定义了一个 Particle 类,表示一个粒子。
    • 初始化方法:设置粒子的初始位置、大小、颜色、角度、速度和生命周期。
    • 移动方法:更新粒子的位置,减少大小和生命周期。如果粒子的大小或生命周期小于等于0,则重置粒子。
    • 重置方法:随机生成新的位置、大小、角度和速度。
    • 绘制方法:在屏幕上绘制粒子。

6. 生成粒子

# 生成初始粒子
particles = [Particle(random.uniform(-width/2, width/2) * scale_factor + WIDTH // 2,random.uniform(-height/2, height/2) * scale_factor + HEIGHT // 2) for _ in range(10000)]
  • 创建粒子:生成 10,000 个粒子,并将它们存储在 particles 列表中。每个粒子的位置是随机的,基于心形的尺寸和缩放因子。

7. 文本设置

# 字体设置
font_size = 48  # 字体大小
font_path = "./test.ttf"  # 确保字体文件在当前目录下
font = pygame.font.Font(font_path, font_size)  # 使用指定字体
text = "多想再见你 哪怕一眼匆匆就别离"
text_surface = font.render(text, True, WHITE)  # 渲染文本
text_rect = text_surface.get_rect(center=(WIDTH // 2, HEIGHT // 2))  # 文本居中
  • 设置字体:定义字体大小和路径,渲染文本并计算文本的矩形区域,以便后续居中显示。

8. 主循环

# 主循环
running = True
clock = pygame.time.Clock()
blink_counter = 0
blink_rate = 10  # 每10帧闪烁一次while running:for event in pygame.event.get():if event.type == pygame.QUIT:running = Falsescreen.fill(BLACK)# 绘制心形曲线points = []for i in range(0, 360, 1):angle_rad = math.radians(i)x, y = heart_curve(angle_rad)x = x * scale_factor + WIDTH // 2y = -y * scale_factor + HEIGHT // 2points.append((x, y))pygame.draw.lines(screen, PURPLE, False, points, 2)  # 使用lines代替polygon# 更新和绘制粒子for particle in particles:particle.move()particle.draw(screen)# 绘制闪烁的文本if blink_counter % blink_rate < blink_rate / 2:  # 每隔一段时间闪烁# 随机生成颜色random_color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))text_surface = font.render(text, True, random_color)  # 渲染文本screen.blit(text_surface, text_rect)  # 绘制文本blink_counter += 1pygame.display.flip()clock.tick(60)pygame.quit()
  • 主循环:程序的核心部分。
    • 事件处理:检查是否有退出事件。
    • 清屏:用黑色填充屏幕。
    • 绘制心形曲线:计算心形的每个点并绘制。
    • 更新和绘制粒子:让每个粒子移动并绘制在屏幕上。
    • 绘制闪烁的文本:每隔一定的帧数,随机生成文本颜色并绘制文本。
    • 更新显示:调用 pygame.display.flip() 更新屏幕,clock.tick(60) 控制帧率为 60 帧每秒。

9. 退出

pygame.quit()
  • 退出程序:当主循环结束后,调用 pygame.quit() 关闭窗口并清理资源。

总结

这段代码结合了图形绘制、动画效果和文本渲染,展示了如何使用 pygame 创建一个动态的视觉效果。通过理解每个部分的功能,你可以更好地掌握 pygame 的使用,并进行更复杂的项目开发。

完整代码

import pygame
import random
import math
import os# 初始化pygame
pygame.init()# 屏幕尺寸
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Dynamic Particle Heart")# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
PURPLE = (128, 0, 128)  # 紫色的RGB值# 心形方程
def heart_curve(t):x = 16 * math.sin(t) ** 3y = 13 * math.cos(t) - 5 * math.cos(2 * t) - 2 * math.cos(3 * t) - math.cos(4 * t)return x, y# 计算心形的最大宽度和高度
def get_heart_dimensions():max_x, min_x, max_y, min_y = -float('inf'), float('inf'), -float('inf'), float('inf')for i in range(0, 360, 1):angle_rad = math.radians(i)x, y = heart_curve(angle_rad)if x > max_x: max_x = xif x < min_x: min_x = xif -y > max_y: max_y = -y  # 注意:这里取负是因为pygame坐标系y轴向下if -y < min_y: min_y = -ywidth = max_x - min_xheight = max_y - min_yreturn width, heightwidth, height = get_heart_dimensions()
scale_factor = min(WIDTH / (width * 1.2), HEIGHT / (height * 1.2))  # 增加一点额外的空间# 粒子类
class Particle:def __init__(self, x, y):self.x = xself.y = yself.size = random.randint(2, 5)self.color = PURPLEself.angle = random.uniform(0, math.pi * 2)self.speed = random.uniform(1, 3)self.lifetime = random.randint(50, 100)def move(self):self.x += math.sin(self.angle) * self.speedself.y -= math.cos(self.angle) * self.speedself.size -= 0.05self.lifetime -= 1if self.size <= 0 or self.lifetime <= 0:self.reset()def reset(self):angle_rad = random.uniform(0, math.pi * 2)x, y = heart_curve(angle_rad)self.x = x * scale_factor + WIDTH // 2self.y = -y * scale_factor + HEIGHT // 2self.size = random.randint(2, 5)self.angle = random.uniform(0, math.pi * 2)self.speed = random.uniform(1, 3)self.lifetime = random.randint(50, 100)def draw(self, screen):s = pygame.Surface((self.size * 2, self.size * 2), pygame.SRCALPHA)pygame.draw.circle(s, (*self.color[:3], self.lifetime * 2.55), (self.size, self.size), self.size)screen.blit(s, (self.x - self.size, self.y - self.size))# 生成初始粒子
particles = [Particle(random.uniform(-width/2, width/2) * scale_factor + WIDTH // 2,random.uniform(-height/2, height/2) * scale_factor + HEIGHT // 2) for _ in range(10000)]# 字体设置
font_size = 48  # 字体大小
font_path = "./test.ttf"  # 确保字体文件在当前目录下
font = pygame.font.Font(font_path, font_size)  # 使用指定字体
text = "多想再见你 哪怕一眼匆匆就别离"
text_surface = font.render(text, True, WHITE)  # 渲染文本
text_rect = text_surface.get_rect(center=(WIDTH // 2, HEIGHT // 2))  # 文本居中# 主循环
running = True
clock = pygame.time.Clock()
blink_counter = 0
blink_rate = 10  # 每10帧闪烁一次while running:for event in pygame.event.get():if event.type == pygame.QUIT:running = Falsescreen.fill(BLACK)# 绘制心形曲线points = []for i in range(0, 360, 1):angle_rad = math.radians(i)x, y = heart_curve(angle_rad)x = x * scale_factor + WIDTH // 2y = -y * scale_factor + HEIGHT // 2points.append((x, y))pygame.draw.lines(screen, PURPLE, False, points, 2)  # 使用lines代替polygon# 更新和绘制粒子for particle in particles:particle.move()particle.draw(screen)# 绘制闪烁的文本if blink_counter % blink_rate < blink_rate / 2:  # 每隔一段时间闪烁# 随机生成颜色random_color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))text_surface = font.render(text, True, random_color)  # 渲染文本screen.blit(text_surface, text_rect)  # 绘制文本blink_counter += 1pygame.display.flip()clock.tick(60)pygame.quit()

补充解说

让我详细解释这个代码的运行逻辑:

  1. 初始化阶段
# 初始化基本设置
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))# 心形方程定义
def heart_curve(t):x = 16 * math.sin(t) ** 3y = 13 * math.cos(t) - 5 * math.cos(2 * t) - 2 * math.cos(3 * t) - math.cos(4 * t)return x, y
  1. 粒子系统
class Particle:def __init__(self, x, y):# 初始化粒子位置、大小、速度等属性self.x = xself.y = yself.size = random.randint(2, 5)self.angle = random.uniform(0, math.pi * 2)self.speed = random.uniform(1, 3)self.lifetime = random.randint(50, 100)
  1. 粒子移动和重置逻辑
def move(self):# 移动粒子self.x += math.sin(self.angle) * self.speedself.y -= math.cos(self.angle) * self.speedself.size -= 0.05self.lifetime -= 1# 当粒子生命周期结束时重置if self.size <= 0 or self.lifetime <= 0:self.reset()def reset(self):# 重置粒子到心形曲线上的随机位置angle_rad = random.uniform(0, math.pi * 2)x, y = heart_curve(angle_rad)self.x = x * scale_factor + WIDTH // 2self.y = -y * scale_factor + HEIGHT // 2# 重置其他属性

运行流程:

  1. 初始化

    • 创建10000个随机分布的粒子
    • 每个粒子有随机的位置、大小、速度和生命周期
  2. 主循环

while running:screen.fill(BLACK)  # 清空屏幕# 绘制心形轮廓# 更新和绘制所有粒子for particle in particles:particle.move()particle.draw(screen)
  1. 粒子运动机制
    • 每个粒子按照自己的角度和速度移动
    • 当粒子生命周期结束时,通过reset()函数重生在心形曲线上
    • 这创造了粒子似乎在"靠近"心形的视觉效果

关于"靠近"效果的实现:

  • 这个效果是通过粒子的生命周期系统实现的
  • 当粒子消失时,它们会在心形曲线上重生(reset()函数)
  • 随着时间推移,越来越多的粒子会重生在心形曲线上
  • 这创造了粒子群似乎在向心形聚集的视觉效果

核心实现在reset()函数:

def reset(self):angle_rad = random.uniform(0, math.pi * 2)x, y = heart_curve(angle_rad)  # 在心形曲线上选择新位置

这不是真正的"靠近"运动,而是通过粒子的死亡和重生机制,逐渐在心形轮廓上形成粒子群,创造出视觉上的聚集效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/63452.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React源码02 - 基础知识 React API 一览

1. JSX到JavaScript的转换 <div id"div" key"key"><span>1</span><span>2</span> </div>React.createElement("div", // 大写开头会当做原生dom标签的字符串&#xff0c;而组件使用大写开头时&#xff0c;这…

验证的分类及相关工具

目录 1.验证方法的分类1.1动态验证1.2.静态验证 2.动态验证及相关工具2.1.电路级仿真工具2.2.逻辑仿真工具 3.静态验证及相关工具3.1 形式验证工具3.2 静态时序分析工具 SOC设计中验证包含以下几个方面&#xff1a; 验证原始描述的正确性验证设计的逻辑功能是否符合设计规范的要…

【HarmonyOs学习日志(14)】计算机网络之域名系统DNS

域名系统DNS 域名系统DNS——从域名解析出IP地址 文章目录 域名系统DNS概述域名到IP地址的解析 互联网的域名结构命名标准 域名服务器域名的解析过程 概述 域名系统DNS&#xff08;Domain Name System&#xff09;是互联网使用的命名系统&#xff0c;用来把便于人们使用的机器…

【Python】pandas库---数据分析

大学毕业那年&#xff0c;你成了社会底层群众里&#xff0c;受教育程度最高的一批人。 前言 这是我自己学习Python的第四篇博客总结。后期我会继续把Python学习笔记开源至博客上。 上一期笔记有关Python的NumPy数据分析&#xff0c;没看过的同学可以去看看&#xff1a;【Pyt…

【人工智能学习之HDGCN18关键点修改】

【人工智能学习之HDGCN18关键点修改】 训练部分修改部分 训练部分 请参考文章&#xff1a;【人工智能学习之HDGCN训练自己的数据集】 修改部分 参考源码中25关键点的区域划分&#xff0c;我们将18关键点划分为&#xff1a; 头部&#xff1a; 鼻子左眼和左耳右眼和右耳 上肢…

ARCGIS国土超级工具集1.2更新说明

ARCGIS国土超级工具集V1.2版本&#xff0c;功能已增加至47 个。在V1.1的基础上修复了若干使用时发现的BUG&#xff0c;新增了"矢量分割工具"菜单&#xff0c;同时增加及更新了了若干功能&#xff0c;新工具使用说明如下&#xff1a; 一、勘测定界工具栏更新界址点成果…

华为OD --- 流浪地球

华为OD --- 流浪地球 题目独立实现基本思路代码实现 其他答案实现思路代码实现 题目 独立实现 基本思路 1、首先把题目给出的启动机器初始化成数组, 2、用for循环模拟每隔1s更新这个初始化数组的前后两个机器. (源码中的updateTimeCount函数) 3、for循环每次循环后会检查当前…

DataOps驱动数据集成创新:Apache DolphinScheduler SeaTunnel on Amazon Web Services

引言 在数字化转型的浪潮中&#xff0c;数据已成为企业最宝贵的资产之一。DataOps作为一种文化、流程和实践的集合&#xff0c;旨在提高数据管道的质量和效率&#xff0c;从而加速数据从源头到消费的过程。白鲸开源科技&#xff0c;作为DataOps领域的领先开源原生公司&#xf…

【硬件IIC】stm32单片机利用硬件IIC驱动OLED屏幕

之前操作OLED屏幕都是用GPIO模拟IIC去驱动&#xff0c;最近打算用硬件IIC去驱动&#xff0c;于是写下这个demo,在这个过程中遇到一点小坑&#xff0c;记录一下&#xff0c;本文章非小白教程&#xff0c;所以只突出踩到的坑点&#xff0c;文章中涉及到的OLED也是网上资料写烂的&…

python如何自动加空格

首先&#xff0c;需要进行打开的一个pycharm的软件&#xff0c;可进行双击的打开该软件。 可以看到的是在当前的打开的文件中&#xff0c;格式相对较乱一下。格式不对会格式错误。 然后点击菜单栏中的“code”。 在弹出的下拉菜单中选择“reformat code”选项。 可以看到的是在…

【开源免费】基于SpringBoot+Vue.JS网上订餐系统(JAVA毕业设计)

本文项目编号 T 018 &#xff0c;文末自助获取源码 \color{red}{T018&#xff0c;文末自助获取源码} T018&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 新…

答题考试系统v1.6.1高级版源码分享+uniapp+搭建测试环境

一.系统介绍 一款基于FastAdminThinkPHPUniapp开发的小程序答题考试系统&#xff0c;支持多种试题类型、多种试题难度、练题、考试、补考模式&#xff0c;提供全部前后台无加密源代码&#xff0c;支持私有化部署 二.测试环境 系统环境&#xff1a;CentOS、 运行环境&#x…

经典电荷泵/Charge pump——1998.JSSC

电路结构 工作原理 M3 and M4 are the series switches, and M5, M6 switch to the highest voltage. If M5 and M6 are missing, having a large capacitor is of absolute necessity, because must always stay between 2 Vin and 2Vin - Uj to avoid switching on the vert…

Swin transformer 论文阅读记录 代码分析

该篇文章&#xff0c;是我解析 Swin transformer 论文原理&#xff08;结合pytorch版本代码&#xff09;所记&#xff0c;图片来源于源paper或其他相应博客。 代码也非原始代码&#xff0c;而是从代码里摘出来的片段&#xff0c;配上简单数据&#xff0c;以便理解。 当然&…

GPT-Omni 与 Mini-Omni2:创新与性能的结合

近年来&#xff0c;随着人工智能技术的飞速发展&#xff0c;各种模型和平台应运而生&#xff0c;以满足从个人用户到企业级应用的多样化需求。在这一领域&#xff0c;GPT-Omni 和 Mini-Omni2 是两款备受瞩目的技术产品&#xff0c;它们凭借独特的设计和强大的功能&#xff0c;在…

龙迅#LT7911E适用于EDP/DP/TPYE-C转MIPIDSI应用,支持图像处理功能,内置I2C,主应用副屏显示,投屏领域!

1. 描述 LT7911E 是一款高性能 eDP 转 MIPI D-PHY 转换器&#xff0c;旨在将 eDP 源连接到 MIPI 显示面板。 LT7911E 集成了一个符合 eDP1.4 标准的接收器&#xff0c;支持 1.62Gbps 至 5.67Gbps 的输入数据&#xff0c;以 270Mbps 的递增步长&#xff0c;以及一个 2 端口 D…

C语言——实现求出最大值

问题描述&#xff1a;利用C语言自定义函数求出一维数组里边最大的数字 //利用函数找最大数#include<stdio.h>int search(int s[9]) //查找函数 {int i , max s[0] , max_xia 0;for(i0;i<9;i){if(s[i] > max){max_xia i;max s[max_xia];}}return max; } in…

解锁 draw.io 流程图制作工具Docker私有化部署(2/2)

一、draw.io 流程图制作工具简介 &#xff08;一&#xff09;基础介绍 draw.io 是一款备受青睐的开源流程图软件&#xff0c;它有着诸多优点。首先&#xff0c;其界面十分整洁有序&#xff0c;完全没有广告的干扰&#xff0c;并且所有功能都是免费向用户开放的&#xff0c;这一…

[HNCTF 2022 Week1]baby_rsa

源代码&#xff1a; from Crypto.Util.number import bytes_to_long, getPrime from gmpy2 import * from secret import flag m bytes_to_long(flag) p getPrime(128) q getPrime(128) n p * q e 65537 c pow(m,e,n) print(n,c) # 62193160459999883112594854240161159…

docker run命令大全

docker run命令大全 基本语法常用选项基础选项资源限制网络配置存储卷和挂载环境变量重启策略其他高级选项示例总结docker run 命令是 Docker 中最常用和强大的命令之一,用于创建并启动一个新的容器。该命令支持多种选项和参数,可以满足各种使用场景的需求。以下是 docker ru…