0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何用Python放煙花

麥辣雞腿堡 ? 來(lái)源:CSDN博客 ? 作者:Leleprogrammer ? 2023-01-14 11:34 ? 次閱讀

首先,需要的外置庫(kù):pygame,pymunk

導(dǎo)入

import pygame

from pygame.locals import *

import pymunk

from pymunk import pygame_util

import sys

import random as rd

import time

import math

然后寫(xiě)一個(gè)主程序類(lèi),對(duì)pygame進(jìn)行初始化,設(shè)置屏幕寬高,設(shè)置標(biāo)題,創(chuàng)建pymunk空間,然后設(shè)置空間的重力為(0,300),然后設(shè)置collision_persistence參數(shù)為0,表示沒(méi)有碰撞,畢竟倆煙花也不會(huì)撞一起......然后設(shè)置煙花半徑(可以自行修改),創(chuàng)建兩個(gè)列表,用于存放煙花爆炸形成的火球和發(fā)射到天空中還沒(méi)爆炸的煙花,創(chuàng)建一個(gè)colors列表,存放煙花的顏色

class Firework:

def init (self):

pygame.init()

self.W,self.H=800,1000

self.screen=pygame.display.set_mode((self.W,self.H))

self.draw_options=pygame_util.DrawOptions(self.screen)

pygame.display.set_caption("2023元旦煙花")

self.space=pymunk.Space()

self.space.gravity=(0,300)

self.space.collision_persistence=0

self.fireball_radius=2

self.fire_radius=2

self.fireballs=[]

self.colors=[

(255,0,0),(255,127,80),(255,140,0),(255,160,122),(240,128,128),(255,99,71),(255,69,0),

(255,105,180),(255,20,147),(208,32,144),(176,48,96),(153,50,204),(255,48,48),

(238,44,44),(205,38,38),(255,255,0),(255,215,0),(255,185,15),(238,201,0),

(34,139,34),(46,139,87),(60,179,113),(0,255,127)

]

self.fires=[]

接下來(lái),進(jìn)行事件監(jiān)聽(tīng),按下鼠標(biāo)就可以創(chuàng)建火球

def listen(self):

for event in pygame.event.get():

if event.type==QUIT:

sys.exit()

if event.type==MOUSEBUTTONDOWN:

self.create_firework(x=pygame.mouse.get_pos()[0])

然后寫(xiě)個(gè)創(chuàng)建煙花的方法,首先要有個(gè)body,設(shè)置body_type為DYNAMIC,因?yàn)闊熁ㄊ莿?dòng)態(tài)的。然后設(shè)置body的位置,x坐標(biāo)為傳參的x坐標(biāo),y坐標(biāo)為屏幕最底部,接下來(lái)創(chuàng)建一個(gè)shape,形狀為circle,body對(duì)應(yīng)的fireball_body傳進(jìn)去就好了,然后設(shè)置radius(半徑),設(shè)置shape的彈性(這個(gè)不設(shè)置也可以,沒(méi)多大影響),將body和shape添加到空間中,用add添加,然后將煙花對(duì)應(yīng)的shape對(duì)象、顏色、創(chuàng)建時(shí)間、爆炸前持續(xù)時(shí)間這四個(gè)參數(shù)歸在一個(gè)列表,將這個(gè)列表添加到fireballs中,最后就是要賦予body沖擊力了,使用apply_impulse_at_local_point方法

def create_firework(self,x):

fireball_body=pymunk.Body(mass=1,moment=100,body_type=pymunk.Body.DYNAMIC)

fireball_body.position=x,self.H

fireball_shape=pymunk.Circle(fireball_body,self.fireball_radius)

fireball_shape.elasticity=0.5

self.space.add(fireball_body,fireball_shape)

self.fireballs.append([fireball_shape,rd.choice(self.colors),time.time(),rd.uniform(1,2.2)]) # shape,color,startTime,lastTime

fireball_body.apply_impulse_at_local_point((0,rd.randint(-730,-500)),(0,0))

然后是draw的代碼(比較多),先是填充背景為黑色,然后使用while循環(huán)遍歷fireballs,將煙花繪制出來(lái),檢查是否到達(dá)了爆炸時(shí)間,如果已經(jīng)到達(dá)爆炸時(shí)間,那么將這個(gè)火球從煙花的列表中刪掉。接下來(lái)就要?jiǎng)?chuàng)建炸開(kāi)來(lái)的火花,火花是向不同方向散開(kāi)的,所以用for循環(huán)遍歷一圈的度數(shù),每隔10°就有一個(gè),length是斜邊長(zhǎng)度,然后定義bias偏移量,因?yàn)榛鸹ㄉl(fā)力量和距離并不是固定的,所以每一次length都會(huì)浮動(dòng)一點(diǎn),但始終控制在25~100之間(maximum和minimum),因?yàn)閍pply_impulse_at_local_point發(fā)射出去時(shí)傳參是x軸的力量和y軸的力量,所以要使用三角函數(shù)計(jì)算臨邊和對(duì)邊的長(zhǎng)度從而得到apply_impulse_at_local_point傳參的數(shù)值,又因?yàn)槲覀儽闅v的是度數(shù)(degree),sin和cos計(jì)算的是弧度(radians),所以要先把度數(shù)通過(guò)math.radians轉(zhuǎn)化為弧度,再傳參到sin和cos中。計(jì)算出來(lái)之后,還是創(chuàng)建body和shape并設(shè)置一些基本的參數(shù),添加到空間中,并添加到fires列表中,最后刪除已爆炸的煙花,別忘了變量i需要減1。

上面是對(duì)未爆炸的煙花進(jìn)行遍歷,下面我們還需要對(duì)爆炸后形成的火花進(jìn)行遍歷,如果超出范圍或已到達(dá)刪除時(shí)間就進(jìn)行刪除的操作,邏輯差不多

draw的代碼如下

def draw(self):
   self.screen.fill((0,0,0))
   i=0
   while i<len(self.fireballs):
       fireball,color,startTime,lastTime=self.fireballs[i]
       pygame.draw.circle(self.screen,color,fireball.body.position,self.fireball_radius)
       nowTime=time.time()
       boomTime=startTime+lastTime
       if nowTime>boomTime:
           popball=self.fireballs.pop(i)
           length=50
           for degree in range(90,450,10):
               bias=1
               length+=rd.randint(-bias,bias)
               maximum,minimum=100,25
               if length>maximum:
                   length=maximum
               elif lengthmath.radians(degree)
               x_force=math.sin(radians)*length
               y_force=math.cos(radians)*length
               body=pymunk.Body(mass=1,moment=100,body_type=pymunk.Body.DYNAMIC)
               body.position=popball[0].body.position
               shape=pymunk.Circle(body,self.fire_radius)
               self.space.add(body,shape)
               self.fires.append([shape,popball[1],time.time(),rd.uniform(0.5,1.5)]) # shape,color,startTime,lastTime
               body.apply_impulse_at_local_point((x_force,y_force),(0,0))
           self.space.remove(popball[0])
           i-=1
       i+=1
   i=0
   while i<len(self.fires):
       fire,color,startTime,lastTime=self.fires[i]
       pos=fire.body.position
       pygame.draw.circle(self.screen,color,pos,self.fire_radius)
       nowTime=time.time()
       deleteTime=startTime+lastTime
       if nowTime>deleteTime:
           self.fires.pop(i)
           self.space.remove(fire)
           i-=1
       elif pos[0]<0 or pos[0]>self.W or pos[1]>self.H:
           self.fires.pop(i)
           self.space.remove(fire)
           i-=1
       i+=1

寫(xiě)到這兒,我們的煙花就差不多完成了,最后寫(xiě)個(gè)run

def run(self):

clock=pygame.time.Clock()

FPS=60

while True:

clock.tick(FPS)

self.listen()

self.draw()

self.space.step(1/FPS)

pygame.display.update()

運(yùn)行

if name ==" main ":

firework=Firework()

firework.run()

這樣就好啦!

最終代碼:

import pygame

from pygame.locals import *

import pymunk

from pymunk import pygame_util

import sys

import random as rd

import time

import math

class Firework:

def init (self):

pygame.init()

self.W,self.H=800,1000

self.screen=pygame.display.set_mode((self.W,self.H))

self.draw_options=pygame_util.DrawOptions(self.screen)

pygame.display.set_caption("2023元旦煙花")

self.space=pymunk.Space()

self.space.gravity=(0,300)

self.space.collision_persistence=0

self.fireball_radius=2

self.fire_radius=2

self.fireballs=[]

self.colors=[

(255,0,0),(255,127,80),(255,140,0),(255,160,122),(240,128,128),(255,99,71),(255,69,0),

(255,105,180),(255,20,147),(208,32,144),(176,48,96),(153,50,204),(255,48,48),

(238,44,44),(205,38,38),(255,255,0),(255,215,0),(255,185,15),(238,201,0),

(34,139,34),(46,139,87),(60,179,113),(0,255,127)

]

self.fires=[]

def listen(self):

for event in pygame.event.get():

if event.type==QUIT:

sys.exit()

if event.type==MOUSEBUTTONDOWN:

self.create_firework(x=pygame.mouse.get_pos()[0])

def create_firework(self,x):

fireball_body=pymunk.Body(mass=1,moment=100,body_type=pymunk.Body.DYNAMIC)

fireball_body.position=x,self.H

fireball_shape=pymunk.Circle(fireball_body,self.fireball_radius)

fireball_shape.elasticity=0.5

self.space.add(fireball_body,fireball_shape)

self.fireballs.append([fireball_shape,rd.choice(self.colors),time.time(),rd.uniform(1,2.2)]) # shape,color,startTime,lastTime

fireball_body.apply_impulse_at_local_point((0,rd.randint(-730,-500)),(0,0))

def draw(self):

self.screen.fill((0,0,0))

i=0

while i

fireball,color,startTime,lastTime=self.fireballs[i]

pygame.draw.circle(self.screen,color,fireball.body.position,self.fireball_radius)

nowTime=time.time()

boomTime=startTime+lastTime

if nowTime>boomTime:

popball=self.fireballs.pop(i)

length=50

for degree in range(90,450,10):

bias=1

length+=rd.randint(-bias,bias)

maximum,minimum=100,25

if length>maximum:

length=maximum

elif length

length=minimum

radians=math.radians(degree)

x_force=math.sin(radians)*length

y_force=math.cos(radians)*length

body=pymunk.Body(mass=1,moment=100,body_type=pymunk.Body.DYNAMIC)

body.position=popball[0].body.position

shape=pymunk.Circle(body,self.fire_radius)

self.space.add(body,shape)

self.fires.append([shape,popball[1],time.time(),rd.uniform(0.5,1.5)]) # shape,color,startTime,lastTime

body.apply_impulse_at_local_point((x_force,y_force),(0,0))

self.space.remove(popball[0])

i-=1

i+=1

i=0

while i

fire,color,startTime,lastTime=self.fires[i]

pos=fire.body.position

pygame.draw.circle(self.screen,color,pos,self.fire_radius)

nowTime=time.time()

deleteTime=startTime+lastTime

if nowTime>deleteTime:

self.fires.pop(i)

self.space.remove(fire)

i-=1

elif pos[0]<0 or pos[0]>self.W or pos[1]>self.H:

self.fires.pop(i)

self.space.remove(fire)

i-=1

i+=1

def run(self):

clock=pygame.time.Clock()

FPS=60

while True:

clock.tick(FPS)

self.listen()

self.draw()

self.space.step(1/FPS)

pygame.display.update()

if name ==" main ":

firework=Firework()

firework.run()

此時(shí)我仿佛聽(tīng)見(jiàn)你說(shuō):一直按鼠標(biāo)手好酸啊!

那沒(méi)事,我們改成自動(dòng)就好啦!

只需要修改一部分內(nèi)容就好

首先需要一個(gè)自定義事件(全局變量)

CREATE_FIREBALL=USEREVENT+1

run中while循環(huán)前添加這一行,用來(lái)啟動(dòng)事件循環(huán),第二個(gè)參數(shù)是間隔時(shí)間,單位是毫秒,可以自己修改

pygame.time.set_timer(CREATE_FIREBALL,120)

將listen改成這樣

def listen(self):

for event in pygame.event.get():

if event.type==QUIT:

sys.exit()

if event.type==CREATE_FIREBALL:

self.create_firework(x=rd.randint(0,self.W))

這樣就大功告成啦!

原文鏈接:https://blog.csdn.net/leleprogrammer/article/details/128510460

編輯:何安

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 開(kāi)發(fā)
    +關(guān)注

    關(guān)注

    0

    文章

    357

    瀏覽量

    40737
  • python
    +關(guān)注

    關(guān)注

    53

    文章

    4753

    瀏覽量

    84081
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    請(qǐng)問(wèn)如何用Python來(lái)寫(xiě)單片機(jī)?

    請(qǐng)問(wèn)如何用Python來(lái)寫(xiě)單片機(jī)?
    發(fā)表于 06-15 09:29

    何用Python語(yǔ)言控制單片機(jī)?

    何用Python語(yǔ)言控制單片機(jī)?
    發(fā)表于 11-12 06:00

    何用python中的serial向串口發(fā)送和接收數(shù)據(jù)?

    何用python中的serial向串口發(fā)送和接收數(shù)據(jù)?
    發(fā)表于 11-22 06:35

    CH32V307評(píng)估板如何用Python開(kāi)發(fā)?

    CH32V307評(píng)估板如何用Python開(kāi)發(fā)?
    發(fā)表于 03-28 20:44

    智能RFID倉(cāng)庫(kù)管理系統(tǒng)之煙花倉(cāng)庫(kù)智能管理

    每到春節(jié),燃放煙花是中國(guó)人的傳統(tǒng)習(xí)俗。為加強(qiáng)煙花安全管理,加強(qiáng)對(duì)煙花生產(chǎn)、儲(chǔ)存、運(yùn)輸、銷(xiāo)售和燃放的監(jiān)督檢查,每年元旦、春節(jié)期間是煙花生產(chǎn)、銷(xiāo)售、運(yùn)輸?shù)耐?,無(wú)證生產(chǎn)、運(yùn)輸、存儲(chǔ)販賣(mài)
    發(fā)表于 12-16 15:18 ?492次閱讀

    RFID在易燃易爆品行業(yè)的應(yīng)用——以煙花倉(cāng)庫(kù)為例

    。影視作品中的很多靈感就是來(lái)源于實(shí)際生活,可想而知在實(shí)際生活中一旦發(fā)生這樣的安全事故,要付出的代價(jià)可能過(guò)之不及。 中國(guó)人的節(jié)日是歷來(lái)要放煙花爆炸來(lái)慶祝的,春節(jié)則是煙花行業(yè)的旺季。無(wú)論是生產(chǎn)還是運(yùn)輸銷(xiāo)售,都有可
    發(fā)表于 11-08 14:17 ?395次閱讀

    何用python爬取抖音app數(shù)據(jù)

    記錄一下如何用python爬取app數(shù)據(jù),本文以爬取抖音視頻app為例。
    的頭像 發(fā)表于 03-16 09:07 ?5030次閱讀

    何用Python計(jì)算提高機(jī)器學(xué)習(xí)算法和結(jié)果

    本文將簡(jiǎn)要介紹常用的距離度量方法、它們的工作原理、如何用Python計(jì)算它們以及何時(shí)使用它們。這樣可以加深知識(shí)和理解,提高機(jī)器學(xué)習(xí)算法和結(jié)果。
    發(fā)表于 10-31 10:58 ?584次閱讀

    python有什么用 如何用python創(chuàng)建數(shù)據(jù)庫(kù)

    python有什么用 如何用python創(chuàng)建數(shù)據(jù)庫(kù) Python是一種高級(jí)編程語(yǔ)言,可以用于開(kāi)發(fā)各種類(lèi)型的應(yīng)用程序和工具。它的廣泛應(yīng)用使它在編程領(lǐng)域中極為受歡迎。
    的頭像 發(fā)表于 08-28 16:41 ?1060次閱讀

    何用Python自動(dòng)套用模板批量生成PDF文檔

    今天就給大家講講如何用Python自動(dòng)套用模板批量生成的PDF文檔。 1.準(zhǔn)備 開(kāi)始之前,你要確保Python和pip已經(jīng)成功安裝在電腦上噢,如果沒(méi)有,請(qǐng)?jiān)L問(wèn)這篇文章: 超詳細(xì)Python
    的頭像 發(fā)表于 10-17 10:54 ?793次閱讀
    如<b class='flag-5'>何用</b><b class='flag-5'>Python</b>自動(dòng)套用模板批量生成PDF文檔

    何用Python來(lái)實(shí)現(xiàn)文件系統(tǒng)的操作功能

    就來(lái)介紹一下如何用 Python 來(lái)實(shí)現(xiàn)這些功能 輸出當(dāng)前的路徑 我們可以通過(guò) Python 當(dāng)中的 OS 庫(kù)來(lái)獲取當(dāng)前文件所在的位置 import os os .getcwd() 路徑的拼接 我們
    的頭像 發(fā)表于 10-30 14:27 ?321次閱讀
    如<b class='flag-5'>何用</b><b class='flag-5'>Python</b>來(lái)實(shí)現(xiàn)文件系統(tǒng)的操作功能

    何用Python自動(dòng)套用模板批量生成PDF文檔

    辦最高效的事。 今天就給大家講講如何用Python自動(dòng)套用模板批量生成下方這樣的PDF文檔。 1.準(zhǔn)備 開(kāi)始之前,你要確保Python和pip已經(jīng)成功安裝在電腦上噢,如果沒(méi)有,請(qǐng)?jiān)L問(wèn)這篇文章: 超詳細(xì)
    的頭像 發(fā)表于 10-31 10:56 ?1246次閱讀
    如<b class='flag-5'>何用</b><b class='flag-5'>Python</b>自動(dòng)套用模板批量生成PDF文檔

    何用python實(shí)現(xiàn)RFM建模

    今天給大家分享的是如何用python實(shí)現(xiàn)RFM建模。 RFM模型的含義 RFM模型是衡量客戶價(jià)值和客戶創(chuàng)利能力的重要工具和手段。在眾多的客戶關(guān)系管理(CRM)的分析模式中,RFM模型是被廣泛提到
    的頭像 發(fā)表于 11-02 10:36 ?669次閱讀
    如<b class='flag-5'>何用</b><b class='flag-5'>python</b>實(shí)現(xiàn)RFM建模

    過(guò)年DIY了個(gè)煙花給女朋友,誰(shuí)說(shuō)程序員不懂浪漫?

    千百年來(lái),煙花爆竹被看作是中國(guó)人春節(jié)的底色,絢爛彌漫的煙花,搭配噼里啪啦的爆竹聲,人們?cè)谀晡稘u濃中享受團(tuán)聚的歡樂(lè)。而近期煙花大師蔡國(guó)強(qiáng)的新作品--《海市蜃樓》,也讓放煙花一時(shí)成為爆款視
    的頭像 發(fā)表于 02-06 15:03 ?354次閱讀
    過(guò)年DIY了個(gè)<b class='flag-5'>煙花</b>給女朋友,誰(shuí)說(shuō)程序員不懂浪漫?

    涂鴉手把手教你DIY超炫酷的龍年煙花!效果超豐富、可玩度更強(qiáng)

    千百年來(lái),煙花爆竹被看作是中國(guó)人春節(jié)的底色,絢爛彌漫的煙花,搭配噼里啪啦的爆竹聲,人們?cè)谀晡稘u濃中享受團(tuán)聚的歡樂(lè)。而近期煙花大師蔡國(guó)強(qiáng)的新作品--《海市蜃樓》,也讓放煙花一時(shí)成為爆款視
    的頭像 發(fā)表于 02-19 12:59 ?580次閱讀
    涂鴉手把手教你DIY超炫酷的龍年<b class='flag-5'>煙花</b>!效果超豐富、可玩度更強(qiáng)