The Nature of Code閱讀心得與Python實作:4.7 Particle Systems with...

更新於 發佈於 閱讀時間約 8 分鐘
這一節的標題是
4.7 Particle Systems with Forces
因為方格子標題字數限制,所以沒完整顯現

到目前為止,我們所設計的粒子系統,都只有受到重力的作用。那如果作用力是風力呢?又該怎麼設計?

原書在處理作用在粒子系統上的重力時,是在Particle類別中設計一個run()方法,並把重力的作用寫死在裡頭,像這樣:

def run(self):
gravity = pygame.Vector2(0, 0.05)
self.apply_force(gravity)

self.update()
self.show()

當粒子系統中的粒子呼叫這個方法時,就能把重力作用在粒子上。

這個寫法的主要缺點,就是太沒彈性了。如果現在作用力要改成風力,那就得去改run()裡頭的東西。除此之外,另一個缺點是,在主程式裡頭,是看不到重力存在的。

因為覺得原書的寫法不是很好,所以改成在主程式中設定gravity,然後在Emitter類別的run()方法中處理重力:

def run(self):
for particle in self.particles:
particle.apply_force(gravity)
particle.update()

# 移除壽命已到的粒子
self.particles = list(filter(lambda particle: not particle.is_dead(), self.particles))

for particle in self.particles:
particle.show()

這樣子gravity就會以全域變數的身份出現在run()這個方法中。這樣寫的好處是,可以清楚的在主程式中看到有個作用力存在,而且可以進行設定、調整。

雖然讓gravity以全域變數的身份出現在Emitter類別的run()方法中有些好處,但是也有些缺點;最大的缺點是,在主程式中可以看到有個作用力,但卻看不出這個作用力是作用在哪裡。另外,眾所周知,使用全域變數,始終就不是個好主意,除了程式比較雜亂難以閱讀之外,在除錯時也比較難以找到bug。

既然兩種寫法都不是那麼的好,那有沒有比較好的寫法呢?

這個問題沒有標準答案,不同的情境可能會有各自比較好的寫法。下面介紹的是原書提供的寫法,可以避免前面提到的那兩種寫法的一些問題,但要注意的是,並非在所有的情境下,都一定要這樣寫。

既然粒子系統的頭頭是Emitter這個類別,所有粒子都歸它管,那就幫它加個apply_force()方法,用來讓作用力作用在系統內的所有粒子上:

def apply_force(self, force):
for particle in self.particles:
particle.apply_force(force)

當在主程式中要讓作用力作用在粒子系統上時,只要呼叫這個方法就可以了:

gravity = pygame.Vector2(0, 0.05)
:
:
emitter.add_particle()
emitter.apply_force(gravity)
emitter.run()

當然,這時候run()方法裡頭對粒子施加重力的部分,也就是

particle.apply_force(gravity)

就必須拿掉。

Emitter類別處理作用力的部分改成這樣寫,不僅主程式清楚明瞭,而且寫起來彈性也比較大,下面這個例子就是採用這樣子的寫法。

Example 4.6: A Particle System with Force

因為Particle類別並沒有任何更動,所以就只列出Emitter類別和主程式。

class Emitter:
def __init__(self, x, y, mass):
self.mass = mass
self.size = 16*self.mass

self.particles = []

# 發射器位置
self.origin = pygame.Vector2(x, y)

def add_particle(self):
self.particles.append(Particle(self.origin.x, self.origin.y, self.mass))

def apply_force(self, force):
for particle in self.particles:
particle.apply_force(force)

def run(self):
for particle in self.particles:
particle.apply_force(gravity)
particle.update()

# 移除壽命已到的粒子
self.particles = list(filter(lambda particle: not particle.is_dead(), self.particles))

for particle in self.particles:
particle.show()


# python version 3.10.9
import random
import sys

import pygame # version 2.3.0


pygame.init()

pygame.display.set_caption("Example 4.6: A Particle System with Forces")

WHITE = (255, 255, 255)

screen_size = 640, 360
screen = pygame.display.set_mode(screen_size)

FPS = 60
frame_rate = pygame.time.Clock()

gravity = pygame.Vector2(0, 0.05)

emitter = Emitter(320, 50, 1)

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

screen.fill(WHITE)

emitter.add_particle()
emitter.apply_force(gravity)
emitter.run()

pygame.display.update()
frame_rate.tick(FPS)


留言
avatar-img
留言分享你的想法!
avatar-img
ysf的沙龍
15會員
142內容數
寫點東西自娛娛人
ysf的沙龍的其他內容
2024/10/25
粒子系統可以用來製作視覺特效(visual effect, VFX),而粒子外觀的呈現方式,以及粒子具有怎樣的紋理(texture),都會影響特效所展現出來的效果。本節介紹如何利用不同紋理的粒子圖片,以不同的混色模式(blending mode),透過粒子系統來製作模擬煙霧的特效。
Thumbnail
2024/10/25
粒子系統可以用來製作視覺特效(visual effect, VFX),而粒子外觀的呈現方式,以及粒子具有怎樣的紋理(texture),都會影響特效所展現出來的效果。本節介紹如何利用不同紋理的粒子圖片,以不同的混色模式(blending mode),透過粒子系統來製作模擬煙霧的特效。
Thumbnail
2024/10/21
在第二章模擬萬有引力時,曾經利用它來設計會吸引物體的吸子(attractor)。現在,如果想要在模擬粒子系統時,加入會排斥物體的斥子(repeller),那要怎麼做呢?
Thumbnail
2024/10/21
在第二章模擬萬有引力時,曾經利用它來設計會吸引物體的吸子(attractor)。現在,如果想要在模擬粒子系統時,加入會排斥物體的斥子(repeller),那要怎麼做呢?
Thumbnail
2024/10/14
接下來,我們會藉由繼承(inheritance)和多型(polymorphism)這兩個物件導向程式設計的技術,來製作更多樣化、更有趣的粒子系統。
Thumbnail
2024/10/14
接下來,我們會藉由繼承(inheritance)和多型(polymorphism)這兩個物件導向程式設計的技術,來製作更多樣化、更有趣的粒子系統。
Thumbnail
看更多
你可能也想看
Thumbnail
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
Thumbnail
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
Thumbnail
模擬世界是我們寫程式造出來的,我們就是模擬世界的主宰,所以各種作用力要長什麼樣子、要怎麼個作用法,都由我們決定。不過,如果希望這些作用力看起來像真實世界的作用力一樣,那在寫程式的時候,套用這些作用力在真實世界中的物理公式,會是比較省時省力的做法。
Thumbnail
模擬世界是我們寫程式造出來的,我們就是模擬世界的主宰,所以各種作用力要長什麼樣子、要怎麼個作用法,都由我們決定。不過,如果希望這些作用力看起來像真實世界的作用力一樣,那在寫程式的時候,套用這些作用力在真實世界中的物理公式,會是比較省時省力的做法。
Thumbnail
這一節談的是向量的定義,以及如何運用向量來建立模擬物體運動時,關於位置和速度間的關係式。
Thumbnail
這一節談的是向量的定義,以及如何運用向量來建立模擬物體運動時,關於位置和速度間的關係式。
Thumbnail
目錄 Ch. 1 科學態度方法與緒論 =>物理學的簡介、科學態度是新教材 Ch. 2 物質的組成+交互作用 =>物質組成=>分子=>原子=>原子核+電子(基本粒子)=>質子+中子(夸克:基本粒子) =>四大交互作用=>長程力(電+重)+短程力(強+弱) Ch. 3 物體的運動 =>慣性的思辨(亞里斯
Thumbnail
目錄 Ch. 1 科學態度方法與緒論 =>物理學的簡介、科學態度是新教材 Ch. 2 物質的組成+交互作用 =>物質組成=>分子=>原子=>原子核+電子(基本粒子)=>質子+中子(夸克:基本粒子) =>四大交互作用=>長程力(電+重)+短程力(強+弱) Ch. 3 物體的運動 =>慣性的思辨(亞里斯
Thumbnail
接下來討論力與運動,這其實就是牛頓運動學的基礎,關鍵在於「力」,一定要先把力弄懂,不能只關注運動。學生要打開牛頓運動學的門,就要知道本章節力與運動的標題,不是在唬你,而真在講施力與產生運動的關係。
Thumbnail
接下來討論力與運動,這其實就是牛頓運動學的基礎,關鍵在於「力」,一定要先把力弄懂,不能只關注運動。學生要打開牛頓運動學的門,就要知道本章節力與運動的標題,不是在唬你,而真在講施力與產生運動的關係。
Thumbnail
這篇文章將會講述圓形波的設計思路、製作流程和應用方向。
Thumbnail
這篇文章將會講述圓形波的設計思路、製作流程和應用方向。
Thumbnail
從上次課程,我們知道生活中到處都是力的存在,人們用各種方式去使用力,小到手提重物,大到火箭升空。 藉由精準的測量力,人們得以較精準地預測物體會怎麼被改變、被移動,也因此我們可以做出各式各樣的模擬,減少實際測驗時產生的錯誤......
Thumbnail
從上次課程,我們知道生活中到處都是力的存在,人們用各種方式去使用力,小到手提重物,大到火箭升空。 藉由精準的測量力,人們得以較精準地預測物體會怎麼被改變、被移動,也因此我們可以做出各式各樣的模擬,減少實際測驗時產生的錯誤......
Thumbnail
呼,今天教學設計有個突破,自己感覺像是終於能從深深的海底回到海面換氣,突破那層分界從海回到空氣中的感受真實地不可思議,有種鬆一口氣的感覺。 這次在力學單元的概念確立上,花的時間可是數以月計(還只是第一部分而已)。但只要概念確立,教學活動就只是繞著它運作而已了,一切都是值得的。
Thumbnail
呼,今天教學設計有個突破,自己感覺像是終於能從深深的海底回到海面換氣,突破那層分界從海回到空氣中的感受真實地不可思議,有種鬆一口氣的感覺。 這次在力學單元的概念確立上,花的時間可是數以月計(還只是第一部分而已)。但只要概念確立,教學活動就只是繞著它運作而已了,一切都是值得的。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News