欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python實現(xiàn)跨年煙花動態(tài)效果

 更新時間:2023年01月03日 10:38:12   作者:阿玥的小東東  
這篇文章主要介紹了python實現(xiàn)跨年煙花的動態(tài)效果,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧

朋友們,有多久沒放煙花了?今年你所在的地方允許放煙花么?既然我們不能線下放,那么我們就在線上放個夠吧(還是那句話:你~有~對~象~了~嘛~)

一下是動態(tài)圖(圖片我使用的我上幾次的背景圖,大家也可以換成別的哦~但是呢阿玥還是建議用暗色的背景圖,會更好看的喲~~~)

Pygame 繪制煙花的基本原理

1、發(fā)射階段:在這一階段煙花的形狀是線性向上,通過設(shè)定一組大小不同、顏色不同的點來模擬“向上發(fā)射” 的運動運動,運動過程中 5個點被賦予不同大小的加速度,隨著時間推移,后面的點會趕上前面的點,最終所有點會匯聚在一起,處于綻放準備階段。

2、煙花綻放:煙花綻放這個階段,是由一個點分散多個點向不同方向發(fā)散,并且每個點的移動軌跡可需要被記錄,目的是為了追蹤整個綻放軌跡。

3、煙花凋零,此階段負責(zé)描繪綻放后煙花的效果,綻放后的煙花,而在每一時刻點的下降速度和亮度(代碼中也叫透明度)是不一樣的,因此在代碼里,將煙花綻放后將每個點賦予兩個屬性:分別為重力向量和生命周期,來模擬煙花在不同時期時不同的展現(xiàn)效果。

首先設(shè)置全局變量,例如重力向量,窗口大小,Trail 的顏色列表(多為灰色或白色)以及不同狀態(tài)下 Trail 之間間隔,gravity設(shè)置重力變量,DISPLAY_width和heigh控制窗口的長和寬

用Python和Tkinter設(shè)計煙花

這里不再一股腦把數(shù)學(xué)知識全丟出來,我們邊寫代碼邊說理論。首先,確保你安裝和導(dǎo)入了Tkinter,它是Python的標準 GUI 庫,廣泛應(yīng)用于各種各樣的項目和程序開發(fā),在Python中使用 Tkinter 可以快速的創(chuàng)建 GUI 應(yīng)用程序。

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之外,為了能讓界面有漂亮的背景,

w = tk.Label(root, text="Hello Tkinter!")

我們也導(dǎo)入PIL用于圖像處理,以及導(dǎo)入其它一些包,比如time,random和math。它們能讓我們更容易的控制煙花粒子的運動軌跡。

Tkinter應(yīng)用的基本設(shè)置如下:

root = tk.Tk()

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

w = tk.Label(root, text="Hello Tkinter!")

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

w.pack()
root.mainloop()

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

將煙花綻放轉(zhuǎn)譯成代碼

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

particles 類
粒子在空中隨機生成隨機,變成一個圈、下墜、消失
屬性:
    - id: 粒子的id
    - x, y: 粒子的坐標
    - vx, vy: 在坐標的變化速度
    - total: 總數(shù)
    - 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

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

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

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

# 定義膨脹效果的時間幀
def expand (self):
    return self.age <= 1.2
# 檢查粒子是否仍在生命周期內(nèi)
def alive(self):
    return self.age <= self.lifespan

使用Tkinter模擬

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

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

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

numb_explode = randint(6,10)
# 為所有模擬煙花綻放的全部粒子創(chuàng)建一列列表
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)

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

total_time = .0
# 在1.8秒時間幀內(nèi)保持更新
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

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

我們這里設(shè)置讓Tkinter等待100個單位(大約1秒鐘左右)再調(diào)取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秒后才開始調(diào)用stimulate()
    root.after(100, simulate, cv)
    root.mainloop()

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

可以換個背景哦

以下是全部代碼:

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: 總數(shù)
    - 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
    # 粒子是否在最高存在時長內(nèi)
    def alive(self):
        return self.age <= self.lifespan
'''
循環(huán)調(diào)用保持不停
'''
def simulate(cv):
    t = time()
    explode_points = []
    wait_time = randint(10, 100)
    numb_explode = randint(6, 10)
    # 創(chuàng)建一個所有粒子同時擴大的二維列表
    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內(nèi)一直擴大
    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
    # 循環(huán)調(diào)用
    root.after(wait_time, simulate, cv)
def close(*ignore):
    """退出程序、關(guān)閉窗口"""
    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()

到此這篇關(guān)于python實現(xiàn)跨年煙花動態(tài)效果的文章就介紹到這了,更多相關(guān)python實現(xiàn)煙花內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • TensorFlow索引與切片的實現(xiàn)方法

    TensorFlow索引與切片的實現(xiàn)方法

    這篇文章主要介紹了TensorFlow索引與切片的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • NumPy內(nèi)存布局的實現(xiàn)

    NumPy內(nèi)存布局的實現(xiàn)

    本文主要介紹了NumPy內(nèi)存布局的實現(xiàn),括連續(xù)內(nèi)存布局(C順序)和分散內(nèi)存布局(Fortran順序),并通過實例演示如何操作數(shù)組的內(nèi)存布局,感興趣的可以了解一下
    2024-01-01
  • 決策樹的python實現(xiàn)方法

    決策樹的python實現(xiàn)方法

    這篇文章主要介紹了決策樹的python實現(xiàn)方法,詳細分析了決策樹的優(yōu)缺點及算法思想并以完整實例形式講述了Python實現(xiàn)決策樹的方法,具有一定的借鑒價值,需要的朋友可以參考下
    2014-11-11
  • python郵件中附加文字、html、圖片、附件實現(xiàn)方法

    python郵件中附加文字、html、圖片、附件實現(xiàn)方法

    在本篇文章里小編給大家整理了一篇關(guān)于python郵件中附加文字、html、圖片、附件實現(xiàn)方法,有興趣的朋友們跟著學(xué)習(xí)下。
    2021-01-01
  • Python的子線程和子進程是如何手動結(jié)束的?

    Python的子線程和子進程是如何手動結(jié)束的?

    今天給大家?guī)淼氖顷P(guān)于Python的相關(guān)知識,文章圍繞著如何手動結(jié)束Python的子線程和子進程展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • 詳解Python 調(diào)用C# dll庫最簡方法

    詳解Python 調(diào)用C# dll庫最簡方法

    這篇文章主要介紹了詳解Python 調(diào)用C# dll庫最簡方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • 使用Python、TensorFlow和Keras來進行垃圾分類的操作方法

    使用Python、TensorFlow和Keras來進行垃圾分類的操作方法

    這篇文章主要介紹了如何使用Python、TensorFlow和Keras來進行垃圾分類,這個模型在測試集上可以達到約80%的準確率,可以作為一個基礎(chǔ)模型進行后續(xù)的優(yōu)化,需要的朋友可以參考下
    2023-05-05
  • python獲取字符串中的email

    python獲取字符串中的email

    這篇文章主要介紹了python獲取字符串中的email,通過調(diào)用re庫,通過使用compile、findall獲取字符串中的email,下文詳細實現(xiàn)過程需要的小伙伴可以參考一下
    2022-03-03
  • python 去除二維數(shù)組/二維列表中的重復(fù)行方法

    python 去除二維數(shù)組/二維列表中的重復(fù)行方法

    今天小編就為大家分享一篇python 去除二維數(shù)組/二維列表中的重復(fù)行方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • 淺談Python如何獲取excel數(shù)據(jù)

    淺談Python如何獲取excel數(shù)據(jù)

    這篇文章主要介紹了Python如何獲取excel數(shù)據(jù),本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-10-10

最新評論