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.pswp.cn/web/63452.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/63452.shtml
英文地址,請注明出處:http://en.pswp.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;這…

使用DynadotAPI購買域名清倉列表中的過期域名

前言 Dynadot是通過ICANN認證的域名注冊商&#xff0c;自2002年成立以來&#xff0c;服務于全球108個國家和地區的客戶&#xff0c;為數以萬計的客戶提供簡潔&#xff0c;優惠&#xff0c;安全的域名注冊以及管理服務。 Dynadot平臺操作教程索引&#xff08;包括域名郵箱&…

js分頁功能

先聲明些全局變量方便我們在下面的代碼中使用 //一頁有多少條數據 let num 10; //頁碼 let k 0; //總頁數 let divide; // 用來判斷顯示哪幾頁的頁數 let page_num 0; // 聲明一個用于接數據的變量 let datas; // 聲明一個用于接數據的變量 let data; //一頁有多少條數據 l…

CMake Do‘s and Don‘ts (行為準則)

CMake Dos and Donts {行為準則} 1. General2. Modules3. ProjectsReferences Effective Modern CMake https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1 Do’s and Don’ts https://cliutils.gitlab.io/modern-cmake/chapters/intro/dodonot.html dos and …

驗證的分類及相關工具

目錄 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 新…

串口通信和SPI通信詳解

0、背景 在現代嵌入式系統中&#xff0c;通信是不同模塊之間交換數據的核心。串口通信和 SPI&#xff08;串行外設接口&#xff09;是兩種常見的通信方式&#xff0c;它們各自有獨特的優勢和適用場景。 1、串口通信 1.1、串口通信概念 串口通信是一種常見的異步串行通信協議…

javase-17、API.數學相關

一、Math類 Math類提供了大量的靜態方法來便于我們實現數學計算&#xff0c;如求絕對值、取最大或最小值等。 https://doc.qzxdp.cn/jdk/17/zh/api/java.base/java/lang/Math.html 所在模塊&#xff1a;java.base所在包&#xff1a; java.lang static double abs(double a)…

答題考試系統v1.6.1高級版源碼分享+uniapp+搭建測試環境

一.系統介紹 一款基于FastAdminThinkPHPUniapp開發的小程序答題考試系統&#xff0c;支持多種試題類型、多種試題難度、練題、考試、補考模式&#xff0c;提供全部前后臺無加密源代碼&#xff0c;支持私有化部署 二.測試環境 系統環境&#xff1a;CentOS、 運行環境&#x…

淺談倉頡語言的優劣

倉頡語言&#xff0c;作為華為自研的新一代編程語言&#xff0c;以其高效、安全、現代化的特點&#xff0c;引起了廣泛的關注。 倉頡語言的優勢 高效并發 倉頡語言的一大亮點是其輕松并發的能力。它實現了輕量化用戶態線程和并發對象庫&#xff0c;使得高效并發變得輕松。倉頡…

Sass系統數據隔離的三種方式

1.完全獨立的數據庫 為每一個租戶單獨部署一個數據庫 優點&#xff1a;達到了真正的按租戶進行隔離&#xff0c;不同租戶之間相互沒有影響&#xff0c;可以針對一些特殊租戶例如大客戶做一些定制化的開發&#xff0c;計費相對簡單&#xff0c;按照資源使用進行計費。 缺點&…

FFmpeg 主要結構體剖析

FFmpeg 探索之旅 FFmpeg 主要結構體剖析 FFmpeg 探索之旅前言1、AVFormatContext2、AVCodecContext3、AVCodec4、AVStream5、AVPacket6、AVFrame7、AVCodecParameters7、SwsContext8、AVIOContext9、AVRational 總結 前言 嘿&#xff0c;各位小伙伴&#xff01;在如今這個多媒…