python煙花表白_python炫酷煙花表白源代碼

詳細內容

天天敲代碼的朋友,有沒有想過代碼也可以變得很酷炫又浪漫?今天就教大家用Python模擬出綻放的煙花,工作之余也可以隨時讓程序為自己放一場煙花秀。

python炫酷煙花表白源代碼

這個有趣的小項目并不復雜,只需一點可視化技巧,100余行Python代碼和程序庫Tkinter,最后我們就能達到下面這個效果:

學完本教程后,你也能做出這樣的煙花秀。

整體概念梳理

我們的整個理念比較簡單。

如上圖示,我們這里通過讓畫面上一個粒子分裂為X數量的粒子來模擬爆炸效果。粒子會發生“膨脹”,意思是它們會以恒速移動且相互之間的角度相等。這樣就能讓我們以一個向外膨脹的圓圈形式模擬出煙花綻放的畫面。經過一定時間后,粒子會進入“自由落體”階段,也就是由于重力因素它們開始墜落到地面,仿若綻放后熄滅的煙花。

(推薦學習:編程學習課程)

基本知識:用Python和Tkinter設計煙花

這里不再一股腦把數學知識全丟出來,我們邊寫代碼邊說理論。首先,確保你安裝和導入了Tkinter,它是Python的標準 GUI 庫,廣泛應用于各種各樣的項目和程序開發,在Python中使用 Tkinter 可以快速的創建 GUI 應用程序。import tkinter as tk

from PIL import Image, ImageTk

from time import time, sleep

from random import choice, uniform, randint

from math import sin, cos, radians

除了Tkinter之外,為了能讓界面有漂亮的背景,我們也導入PIL用于圖像處理,以及導入其它一些包,比如time,random和math。它們能讓我們更容易的控制煙花粒子的運動軌跡。

Tkinter應用的基本設置如下:root = tk.Tk()

為了能初始化Tkinter,我們必須創建一個Tk()根部件(root widget),它是一個窗口,帶有標題欄和由窗口管理器提供的其它裝飾物。該根部件必須在我們創建其它小部件之前就創建完畢,而且只能有一個根部件。w = tk.Label(root, text="Hello Tkinter!")

這一行代碼包含了Label部件。該Label調用中的第一個參數就是父窗口的名字,即我們這里用的“根”。關鍵字參數“text”指明顯示的文字內容。你也可以調用其它小部件:Button,Canvas等等。w.pack()

root.mainloop()

接下來的這兩行代碼很重要。這里的打包方法是告訴Tkinter調整窗口大小以適應所用的小部件。窗口直到我們進入Tkinter事件循環,被root.mainloop()調用時才會出現。在我們關閉窗口前,腳本會一直在停留在事件循環。

將煙花綻放轉譯成代碼

現在我們設計一個對象,表示煙花事件中的每個粒子。每個粒子都會有一些重要的屬性,支配了它的外觀和移動狀況:大小,顏色,位置,速度等等。'''

particles 類

粒子在空中隨機生成隨機,變成一個圈、下墜、消失

屬性:

- id: 粒子的id

- x, y: 粒子的坐標

- vx, vy: 在坐標的變化速度

- total: 總數

- age: 粒子存在的時長

- color: 顏色

- cv: 畫布

- lifespan: 最高存在時長

'''

class part:

def __init__(self, cv, idx, total, explosion_speed, x=0., y=0., vx = 0., vy = 0., size=2., color = 'red', lifespan = 2, **kwargs):

self.id = idx

self.x = x

self.y = y

self.initial_speed = explosion_speed

self.vx = vx

self.vy = vy

self.total = total

self.age = 0self.color = color

self.cv = cv

self.cid = self.cv.create_oval(

x - size, y - size, x + size,

y + size, fill=self.color)

self.lifespan = lifespan

如果我們回過頭想想最開始的想法,就會意識到必須確保每個煙花綻放的所有粒子必須經過3個不同的階段,即“膨脹”“墜落”和“消失”。 所以我們向粒子類中再添加一些運動函數,如下所示:def update(self, dt):

# 粒子膨脹if self.alive() and self.expand():

move_x = cos(radians(self.id*360/self.total))*self.initial_speed

move_y = sin(radians(self.id*360/self.total))*self.initial_speed

self.vx = move_x/(float(dt)*1000)

self.vy = move_y/(float(dt)*1000)

self.cv.move(self.cid, move_x, move_y)

# 以自由落體墜落

elif self.alive():

move_x = cos(radians(self.id*360/self.total))

# we technically don't need to update x, y because move will do the job

self.cv.move(self.cid, self.vx + move_x, self.vy+GRAVITY*dt)

self.vy += GRAVITY*dt

# 如果粒子的生命周期已過,就將其移除

elif self.cid is not None:

cv.delete(self.cid)

self.cid = None

當然,這也意味著我們必須定義每個粒子綻放多久、墜落多久。這部分需要我們多嘗試一些參數,才能達到最佳視覺效果。# 定義膨脹效果的時間幀

def expand (self):

return self.age <= 1.2

# 檢查粒子是否仍在生命周期內

def alive(self):

return self.age <= self.lifespan

使用Tkinter模擬

現在我們將粒子的移動概念化,不過很明顯,一個煙花不能只有一個粒子,一場煙花秀也不能只有一個煙花。我們下一步就是讓Python和Tkinter以我們可控的方式向天上連續“發射”粒子。

到了這里,我們需要從操作一個粒子升級為在屏幕上展現多個煙花及每個煙花中的多個粒子。

我們的解決思路如下:創建一列列表,每個子列表是一個煙花,其包含一列粒子。每個列表中的例子有相同的x,y坐標、大小、顏色、初始速度。numb_explode = randint(6,10)

# 為所有模擬煙花綻放的全部粒子創建一列列表

for point in range(numb_explode):

objects = []

x_cordi = randint(50,550)

y_cordi = randint(50, 150)

size = uniform (0.5,3)

color = choice(colors)

explosion_speed = uniform(0.2, 1)

total_particles = randint(10,50)

for i in range(1,total_particles):

r = part(cv, idx = i, total = total_particles, explosion_speed = explosion_speed, x = x_cordi, y = y_cordi,

color=color, size = size, lifespan = uniform(0.6,1.75))

objects.append(r)

explode_points.append(objects)

我們下一步就是確保定期更新粒子的屬性。這里我們設置讓粒子每0.01秒更新它們的狀態,在1.8秒之后停止更新(這意味著每個粒子的存在時間為1.6秒,其中1.2秒為“綻放”狀態,0.4秒為“墜落”狀態,0.2秒處于Tkinter將其完全移除前的邊緣狀態)。total_time = .0

# 在1.8秒時間幀內保持更新

while total_time < 1.8:

sleep(0.01)

tnew = time()

t, dt = tnew, tnew - t

for point in explode_points:

for part in point:

part.update(dt)

cv.update()

total_time += dt

現在,我們只需將最后兩個gist合并為一個能被Tkinter調用的函數,就叫它simulate()吧。該函數會展示所有的數據項,并根據我們設置的時間更新每個數據項的屬性。在我們的主代碼中,我們會用一個alarm處理模塊after()調用此函數,after()會等待一定的時間,然后再調用函數。

我們這里設置讓Tkinter等待100個單位(1秒鐘)再調取simulate。if __name__ == '__main__':

root = tk.Tk()

cv = tk.Canvas(root, height=600, width=600)

# 繪制一個黑色背景

cv.create_rectangle(0, 0, 600, 600, fill="black")

cv.pack()

root.protocol("WM_DELETE_WINDOW", close)

# 在1秒后才開始調用stimulate()

root.after(100, simulate, cv)

root.mainloop()

好了,這樣我們就用Python代碼放了一場煙花秀:

本文只一個簡單版本,等進一步熟悉Tkinter后,還可以添加更多顏色更漂亮的背景照片,讓代碼為你綻放更美的煙花!

以下是全部代碼:import tkinter as tk

from PIL import Image, ImageTk

from time import time, sleep

from random import choice, uniform, randint

from math import sin, cos, radians

# 模擬重力

GRAVITY = 0.05

# 顏色選項(隨機或者按順序)

colors = ['red', 'blue', 'yellow', 'white', 'green', 'orange', 'purple', 'seagreen', 'indigo', 'cornflowerblue']

'''

particles 類

粒子在空中隨機生成隨機,變成一個圈、下墜、消失

屬性:

- id: 粒子的id

- x, y: 粒子的坐標

- vx, vy: 在坐標的變化速度

- total: 總數

- age: 粒子存在的時長

- color: 顏色

- cv: 畫布

- lifespan: 最高存在時長

'''

class Particle:

def __init__(self, cv, idx, total, explosion_speed, x=0., y=0., vx=0., vy=0., size=2., color='red', lifespan=2,

**kwargs):

self.id = idx

self.x = x

self.y = y

self.initial_speed = explosion_speed

self.vx = vx

self.vy = vy

self.total = total

self.age = 0self.color = color

self.cv = cv

self.cid = self.cv.create_oval(

x - size, y - size, x + size,

y + size, fill=self.color)

self.lifespan = lifespan

def update(self, dt):

self.age += dt

# 粒子范圍擴大

if self.alive() and self.expand():

move_x = cos(radians(self.id * 360 / self.total)) * self.initial_speed

move_y = sin(radians(self.id * 360 / self.total)) * self.initial_speed

self.cv.move(self.cid, move_x, move_y)

self.vx = move_x / (float(dt) * 1000)

# 以自由落體墜落

elif self.alive():

move_x = cos(radians(self.id * 360 / self.total))

# we technically don't need to update x, y because move will do the job

self.cv.move(self.cid, self.vx + move_x, self.vy + GRAVITY * dt)

self.vy += GRAVITY * dt

# 移除超過最高時長的粒子

elif self.cid is not None:

cv.delete(self.cid)

self.cid = None

# 擴大的時間

def expand (self):

return self.age <= 1.2

# 粒子是否在最高存在時長內

def alive(self):

return self.age <= self.lifespan

'''

循環調用保持不停

'''

def simulate(cv):

t = time()

explode_points = []

wait_time = randint(10, 100)

numb_explode = randint(6, 10)

# 創建一個所有粒子同時擴大的二維列表

for point in range(numb_explode):

objects = []

x_cordi = randint(50, 550)

y_cordi = randint(50, 150)

speed = uniform(0.5, 1.5)

size = uniform(0.5, 3)

color = choice(colors)

explosion_speed = uniform(0.2, 1)

total_particles = randint(10, 50)

for i in range(1, total_particles):

r = Particle(cv, idx=i, total=total_particles, explosion_speed=explosion_speed, x=x_cordi, y=y_cordi,

vx=speed, vy=speed, color=color, size=size, lifespan=uniform(0.6, 1.75))

objects.append(r)

explode_points.append(objects)

total_time = .0

# 1.8s內一直擴大

while total_time < 1.8:

sleep(0.01)

tnew = time()

t, dt = tnew, tnew - t

for point in explode_points:

for item in point:

item.update(dt)

cv.update()

total_time += dt

# 循環調用

root.after(wait_time, simulate, cv)

def close(*ignore):

"""退出程序、關閉窗口"""

global root

root.quit()

if __name__ == '__main__':

root = tk.Tk()

cv = tk.Canvas(root, height=400, width=600)

# 選一個好看的背景會讓效果更驚艷!

image = Image.open("./image.jpg")

photo = ImageTk.PhotoImage(image)

cv.create_image(0, 0, image=photo, anchor='nw')

cv.pack()

root.protocol("WM_DELETE_WINDOW", close)

root.after(100, simulate, cv)

root.mainloop()

眾多python培訓視頻,盡在python學習網,歡迎在線學習!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385976.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385976.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385976.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【面試總結】2021Java春招面試經歷

三、堆空間 基本描述 JVM啟動時創建堆區&#xff0c;是內存管理的核心區&#xff0c;通常情況下也是最大的內存空間&#xff0c;是被所有線程共享的&#xff0c;幾乎所有的對象實例都要在堆中分配內存&#xff0c;所以這里也是垃圾回收的重點空間。 堆棧關系 棧是JVM運行時的…

tableau地圖城市數據_Tableau 地圖 | 無法識別的城市

Tableau自帶的地圖功能很強大&#xff0c;也很簡單只要雙擊具有地理位置角色的字段&#xff0c;即可生成地圖不過有的時候在你部署地圖的時候總會發現有些城市或地名無法識別&#xff0c;提示如下&#xff1a;這篇post就來簡單聊聊為啥今天直說處理方法&#xff0c;不談后臺原理…

【高級Java架構師系統學習】最新Java高級面試題匯

性能調優 影響MySQLServer 性能的相關因素 商業需求對性能的影響系統架構及實現對性能的影響Query語句對系統性能的影響Schema設計對系統的性能影響硬件環境對系統性能的影響 MySQL 數據庫鎖定機制 MySQL鎖定機制簡介各種鎖定機制分析合理利用鎖機制優化MySQL MySQL數據庫Qu…

vue 安裝指定版本swiper_Vue中的runtime-only和runtime-compiler

在我們使用vue-cli的時候&#xff0c;會提示你安裝的版本可以看到有兩種版本&#xff1a;Routime Only和Runtime Compiler版本1.Runtime Only - 代碼中不可以有任何template 性能更高在該版本下&#xff0c;通常需要借助如webpack的vue-loader發工具把.vue文件編譯成js因為是在…

一文搞懂JVM架構:入職3個月的Java程序員面臨轉正

Java基礎 1.JAVA 中的幾種數據類型是什么&#xff0c;各自占用多少字節。 2.String 類能被繼承嗎&#xff0c;為什么。 3. 兩個對象的 hashCode() 相同&#xff0c;則 equals() 也一定為 true&#xff0c;對嗎&#xff1f; 4. String 屬于基礎的數據類型嗎&#xff1f; 5.…

不顯示調用super_讓不懂編程的人愛上iPhone開發(2017秋iOS11+Swift4+Xcode9版)-第11篇

歡迎回到我們的iPhone開發教程系列&#xff0c;讓我們繼續前進吧。重新來過別害怕&#xff0c;哥不是讓你拋棄之前所有的源代碼&#xff0c;從零開始重新構建這個項目&#xff01;這里說的是游戲界面里面的“Start over”按鈕。在我們的to-do清單里面曾經提到過&#xff0c;這個…

一文搞懂JVM架構:跳槽面試大廠被拒

正文 在實際的工作項目中&#xff0c; 緩存成為高并發、高性能架構的關鍵組件 &#xff0c;那么Redis為什么可以作為緩存使用呢&#xff1f;首先可以作為緩存的兩個主要特征&#xff1a; 在分層系統中處于內存/CPU具有訪問性能良好&#xff0c;緩存數據飽和&#xff0c;有良好…

全局變量_Python函數中的全局變量與局部變量

# a,b變量是全局變量,在整個py文件中都可以訪問a 11b 12# 定義一個函數def first():# 這個變量是函數內部定義的變量,屬于局部變量,只能在函數中使用c "Hello"# 大括號{} 是format()函數的用法,格式化print("c {}".format(c))# 如果局部變量定義的名稱…

一文詳解:字節面試官必問的Mysql鎖機制

一面 1 自我介紹和項目 2 Java的內存分區 3 Java對象的回收方式&#xff0c;回收算法。 4 CMS和G1了解么&#xff0c;CMS解決什么問題&#xff0c;說一下回收的過程。 5 CMS回收停頓了幾次&#xff0c;為什么要停頓兩次。 6 Java棧什么時候會發生內存溢出&#xff0c;Jav…

install npm 到某個文件下執行_你可能不知道的 npm 依賴管理那些事

點擊上方藍字關注我們npm 是 Node.js 默認的、以 JavaScript 編寫的包管理工具&#xff0c;如今&#xff0c;它已經成為世界上最大的包管理工具&#xff0c;是每個前端開發者必備的工具。不知你是否遇到過下面問題&#xff1a;哎&#xff1f;我本地明明是好的&#xff0c;線上的…

萬字總結!騰訊、字節跳動面經已發

二、常見的并發問題 1、臟讀 一個事務讀取了另一個事務未提交的數據 2、不可重復讀 一個事務對同一數據的讀取結果前后不一致。兩次讀取中間被其他事務修改了 3、幻讀 幻讀是指事務讀取某個范圍的數據時&#xff0c;因為其他事務的操作導致前后兩次讀取的結果不一致。幻讀…

ncbi查找目的基因序列_NCBI大搜索之目的基因尋蹤

NCBI大搜索之目的基因尋蹤最近經常碰到查找目的基因的問題&#xff0c;那今天就講一下如何利用NCBI數據庫查找目的基因&#xff01;NCBI(National Center For Biotechnology Information),美國國家生物技術信息中心&#xff0c;分子生物學&#xff0c;生物化學及遺傳學領域常用…

萬字長文!2020-2021京東Java面試真題解析

我整理的spring學習筆記&#xff1a; 像spring這種知識點我們不能盲目的學習&#xff0c;首先我們得有一套學習路線&#xff0c;我總結了一套spring的學習思維導圖&#xff0c;今天通過我整理的Spring學習路線.xmind給大家分析spring需要掌握的一些核心知識點。 spring的特點&…

echarts label固定位置_ECharts+百度地圖網絡拓撲應用

前一篇談及到了ECharts整合HT for Web的網絡拓撲圖應用&#xff0c;后來在ECharts的Demo中看到了有關空氣質量的相關報表應用&#xff0c;就想將百度地圖、ECharts和HT for Web三者結合起來也做一個類似空氣質量報告的報表拓撲圖應用&#xff0c;于是有了下面的Demo&#xff1a…

三年Java開發,你連基礎的JVM運行時內存布局都忘了

面&#xff1a;為什么要使用雙親委派機制去加載類&#xff1f; 答&#xff1a;避免多份同樣字節碼的加載&#xff0c;浪費內存。 類的加載方式 隱式加載&#xff1a;new顯示加載&#xff1a;loadClass、forName等 類的裝載過程如下圖&#xff1a; 面&#xff1a;loadClass和…

vue實現可編輯的文字_蘋果還自帶文字轉語音,只要一鍵按下便可實現,今天分享給大家...

如果想將文字轉成語音&#xff0c;那大家平時都是怎么操作&#xff1f;下面小編就為大家介紹手機&#xff0c;電腦上都可以使用的方法&#xff0c;讓我們一起來看看吧&#xff01;一、手機端操作1、蘋果手機其實蘋果手機就自帶了文字轉語音功能&#xff0c;只要打開手機&#x…

三面美團Java崗,面試竟然被這31道Java基礎題難倒了

01 分布式限流&#xff1a;NginxZooKeeper 1.1 分布式限流之Nginx 請解釋一下什么是 Nginx? 請列舉 x Nginx 的一些特性。 請列舉 x Nginx 和 和 Apache 之間的不同點 請解釋 x Nginx 如何處理 P HTTP 請求。 在 x Nginx 中&#xff0c;如何使用未定義的服務器名稱來阻止…

海龜繪圖小動物_震驚!被塑料繩勒成兩半的海龜

海洋&#xff0c;其實離人類很近&#xff0c;我們在追逐沙灘和日落&#xff0c;享受美味的海鮮的時候&#xff0c;可曾想到我們平時的一些很隨意的行為&#xff0c;會給一些海洋生物帶來無法恢復的傷害&#xff0c;甚至奪取它們的生命。或許人們的冷漠無知尚未得到懲罰&#xf…

上海大廠Java面試經歷:初步理解類加載運行機制和類加載過程

volatile相關經典面試題 談談volatile的特性volatile的內存語義說說并發編程的3大特性什么是內存可見性&#xff0c;什么是指令重排序&#xff1f;volatile是如何解決java并發中可見性的問題volatile如何防止指令重排volatile可以解決原子性嘛&#xff1f;為什么&#xff1f;v…

python生成泊松分布隨機數_泊松分布隨機數

一、功能產生泊松分布的隨機數。二、方法簡介泊松分布的概率密度函數為\[f(x)\frac{\lambda ^{x}e^{-\lambda }}{x!} \qquad x\in \left \{ 0,1,...,\lambda \right \}\]用\(P(\lambda)\)表示。泊松分布的均值為\(\lambda\)&#xff0c;方差為\(\lambda\)。定理 若\(\lambda &g…