The Nature of Code閱讀心得與Python實作:4.5 A System of Systems

更新於 發佈於 閱讀時間約 12 分鐘

集合許多個別的粒子可以形成一個粒子系統,那集合許多粒子系統,是不是也能形成一個系統呢?

當然可以!

既然集合許多粒子系統可以形成一個系統,那集合許多由粒子系統形成的系統,可不可以又形成一個系統呢?

當然也可以!

接下來,我們會以同樣的思路來處理含有許多粒子系統的系統。

在上一節中,我們讓許多粒子形成一個發射器系統;在這一節中,我們會來處理由許多發射器所構成的系統。

在Example 4.3中,我們處理的是單一的粒子系統:畫面上就只有一個不斷冒出粒子的發射器粒子系統。程式的寫法,是把那個系統指定給一個變數emitter,然後不斷把新的粒子加進emitter中,並呼叫emitterrun()方法:

現在,如果我們希望一開始的時候畫面上沒有任何發射器粒子系統,然後每當按下滑鼠左鍵時,就會在滑鼠游標所在的地方放置一個發射器粒子系統,那程式要怎麼寫呢?在設計Emitter這個類別時,我們是把系統所含的粒子放在一個list中。現在的做法也一樣,就把粒子系統放在一個叫做emitterslist中來處理;當按下滑鼠左鍵時,就新增一個發射器粒子系統到list中,然後針對所有在list中的發射器粒子系統,逐一新增粒子,並呼叫run()方法。

Example 4.4: A System of Systems

# python version 3.10.9
import random
import sys

import pygame # version 2.3.0


pygame.init()

pygame.display.set_caption("Example 4.4: A System of Systems")

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)

# 一開始的時候,畫面上沒有任何粒子系統
emitters = []

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

screen.fill(WHITE)

# 當按下滑鼠左鍵時,就把粒子系統新增到list中
if pygame.mouse.get_pressed()[0]:
x, y = pygame.mouse.get_pos()
emitters.append(Emitter(x, y, 1))

# 針對所有在list中的粒子系統,逐一新增粒子,並呼叫run()方法
for emitter in emitters:
emitter.add_particle()
emitter.run()

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

Exercise 4.5

Emitter類別的__init__()加入紀錄粒子庫存數量的變數:

self.inventory = 100

修改add_particle()

def add_particle(self):
if self.inventory > 0:
self.particles.append(Particle(self.origin.x, self.origin.y, self.mass))
self.inventory -= 1

主程式如下:

# python version 3.10.9
import random
import sys

import pygame # version 2.3.0


pygame.init()

pygame.display.set_caption("Exercise 4.5")

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)

emitters = []

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

screen.fill(WHITE)

if pygame.mouse.get_pressed()[0]:
x, y = pygame.mouse.get_pos()
emitters.append(Emitter(x, y, 1))

for emitter in emitters:
emitter.add_particle()
emitter.run()

# 移除已經沒有粒子的粒子系統
emitters = list(filter(lambda emitter: bool(emitter.particles), emitters))

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

Exercise 4.6

一開始的時候,讓粒子系統的粒子聚在一起,形成一個大的團塊。這時候,僅在畫面上顯示粒子,而不更新其狀態,等偵測到滑鼠點擊團塊時,才開始更新粒子的狀態。

修改Emitter類別。

修改__init__()方法,讓粒子系統的粒子在一開始的時候,就在畫面上結成團塊,同時加入用來紀錄粒子系統狀態的變數,以便判斷粒子系統是否正碎裂四散。

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

# 一開始的粒子團塊
self.particles = [Particle(x+3*i, y+3*j, mass)
for i in range(10) for j in range(10)]

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

# 粒子系統是否正碎裂四散?
self.shattering = False

修改run()方法,加入判斷粒子系統是否正碎裂四散的功能

def run(self):
if not self.shattering:
for particle in self.particles:
particle.show()
else:
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()

新增check_click()方法,用來偵測滑鼠是否點擊粒子團塊。當滑鼠點擊任何團塊中的粒子時,即表示滑鼠正點擊該粒子團塊。

def check_click(self, x, y):
for particle in self.particles:
d = pygame.Vector2(x, y).distance_to(particle.position)
if d <= particle.radius:
self.shattering = True
break

主程式如下:

# python version 3.10.9
import random
import sys

import pygame # version 2.3.0


pygame.init()

pygame.display.set_caption("Exercise 4.6")

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)

emitters = [Emitter(100*i, 130, 1) for i in range(1, 6)]

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

screen.fill(WHITE)

for emitter in emitters:
if pygame.mouse.get_pressed()[0]:
x, y = pygame.mouse.get_pos()
emitter.check_click(x, y)

emitter.run()

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


留言
avatar-img
留言分享你的想法!
avatar-img
ysf的沙龍
18會員
149內容數
寫點東西自娛娛人
ysf的沙龍的其他內容
2025/04/04
基礎CA的規則集總共有256個,經由這些規則集所生成的圖案,大部分看起來都平平無奇;不過,還是有些圖案真的是會讓人驚嘆不已,因為實在是跟自然界中可以看到的圖案樣式很相像。根據這些圖案的樣式和特性,Wolfram把它們分成四大類,接下來就來看看,這四大類的圖案各有怎樣的樣式和特性。
Thumbnail
2025/04/04
基礎CA的規則集總共有256個,經由這些規則集所生成的圖案,大部分看起來都平平無奇;不過,還是有些圖案真的是會讓人驚嘆不已,因為實在是跟自然界中可以看到的圖案樣式很相像。根據這些圖案的樣式和特性,Wolfram把它們分成四大類,接下來就來看看,這四大類的圖案各有怎樣的樣式和特性。
Thumbnail
2025/03/31
這節介紹Wolfram的基礎CA (elementary CA)設計方式,以及其迭代過程所構成的圖案。
Thumbnail
2025/03/31
這節介紹Wolfram的基礎CA (elementary CA)設計方式,以及其迭代過程所構成的圖案。
Thumbnail
2025/03/21
細胞自動機的英文是cellular automaton,複數型態為cellular automata,簡稱CA,是一種由細胞物件所組成的系統模型。
Thumbnail
2025/03/21
細胞自動機的英文是cellular automaton,複數型態為cellular automata,簡稱CA,是一種由細胞物件所組成的系統模型。
Thumbnail
看更多
你可能也想看
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
模擬世界是我們寫程式造出來的,我們就是模擬世界的主宰,所以各種作用力要長什麼樣子、要怎麼個作用法,都由我們決定。不過,如果希望這些作用力看起來像真實世界的作用力一樣,那在寫程式的時候,套用這些作用力在真實世界中的物理公式,會是比較省時省力的做法。
Thumbnail
模擬世界是我們寫程式造出來的,我們就是模擬世界的主宰,所以各種作用力要長什麼樣子、要怎麼個作用法,都由我們決定。不過,如果希望這些作用力看起來像真實世界的作用力一樣,那在寫程式的時候,套用這些作用力在真實世界中的物理公式,會是比較省時省力的做法。
Thumbnail
這一節談的是向量的定義,以及如何運用向量來建立模擬物體運動時,關於位置和速度間的關係式。
Thumbnail
這一節談的是向量的定義,以及如何運用向量來建立模擬物體運動時,關於位置和速度間的關係式。
Thumbnail
我們常說要有「系統思維」,看事情不能只看局部,要有系統觀、全局觀。什麼是系統?劉潤在他的《底層邏輯》一書中,用一個很簡單的描述:「系統=要素* 連結關係」,也就是說,把要素間的關係釐清,就能夠看到系統。這跟學術上所說的「理論」是一樣的,所謂的理論就是在說明變數之間的關係,舉例而言,最簡單的供需理論說
Thumbnail
我們常說要有「系統思維」,看事情不能只看局部,要有系統觀、全局觀。什麼是系統?劉潤在他的《底層邏輯》一書中,用一個很簡單的描述:「系統=要素* 連結關係」,也就是說,把要素間的關係釐清,就能夠看到系統。這跟學術上所說的「理論」是一樣的,所謂的理論就是在說明變數之間的關係,舉例而言,最簡單的供需理論說
Thumbnail
1 引言 微分方程是描述一個系統的狀態隨時間和空間演化的最基本的數學工具之一,其在物理、經濟、工程、社會等各方面都有及其重要的應用。 然而,只有很少的微分方程式可以解析求解,尤其對於偏微分方程,能解析求解的種類更是寥寥可數。 更多的微分方程式可以用數值法來求解,只要精確度夠高,就可以滿足科學和工程
Thumbnail
1 引言 微分方程是描述一個系統的狀態隨時間和空間演化的最基本的數學工具之一,其在物理、經濟、工程、社會等各方面都有及其重要的應用。 然而,只有很少的微分方程式可以解析求解,尤其對於偏微分方程,能解析求解的種類更是寥寥可數。 更多的微分方程式可以用數值法來求解,只要精確度夠高,就可以滿足科學和工程
Thumbnail
資料型態-變數概念 上面這張圖片傳傳達了三個概念, 常值:可以是數值、浮點數、字串、布林等資料, 變數名稱:這邊也很好理解,就是好記得名稱,這邊使用中文是方便初學者入門, 盒子:代表在Python底層運作的狀況,Python創建變數時,會先在記憶體創建型態物件,這邊是數字型態,所以創建數字物件。
Thumbnail
資料型態-變數概念 上面這張圖片傳傳達了三個概念, 常值:可以是數值、浮點數、字串、布林等資料, 變數名稱:這邊也很好理解,就是好記得名稱,這邊使用中文是方便初學者入門, 盒子:代表在Python底層運作的狀況,Python創建變數時,會先在記憶體創建型態物件,這邊是數字型態,所以創建數字物件。
Thumbnail
介紹邏輯運算的觀念,包含布林值、運算子與運算式的介紹。並說明如何使用 Python 撰寫這些觀念。
Thumbnail
介紹邏輯運算的觀念,包含布林值、運算子與運算式的介紹。並說明如何使用 Python 撰寫這些觀念。
Thumbnail
學習資料科學的過程中相信最熱門的目前應該是Python程式語言了,而Python的世界裡再進行資料科學時最常用的有「Pandas」、「SciPy」、「Scikit-learn」...等,而這些的基礎幾乎都與「NumPy」離不開關係,因為「NumPy」就是地基,這些較為高階的套件則是基於地基發展而起。
Thumbnail
學習資料科學的過程中相信最熱門的目前應該是Python程式語言了,而Python的世界裡再進行資料科學時最常用的有「Pandas」、「SciPy」、「Scikit-learn」...等,而這些的基礎幾乎都與「NumPy」離不開關係,因為「NumPy」就是地基,這些較為高階的套件則是基於地基發展而起。
Thumbnail
「什麼時候才能用數學歸納法?」 數學歸納法的哲學意義是,當1代入時關係成立,且n成立時發現n+1時成立,那豈不是1成立2就成立,接著3也成立,因此到∞也成立? 所有數學歸納法適用的時機是: 1. 該命題要證明的範圍在自然數系中 2. 能透過「被歸納的訊息」找到「n和n+1 or n和n-1的關係」
Thumbnail
「什麼時候才能用數學歸納法?」 數學歸納法的哲學意義是,當1代入時關係成立,且n成立時發現n+1時成立,那豈不是1成立2就成立,接著3也成立,因此到∞也成立? 所有數學歸納法適用的時機是: 1. 該命題要證明的範圍在自然數系中 2. 能透過「被歸納的訊息」找到「n和n+1 or n和n-1的關係」
Thumbnail
偶然在新聞上看到一到數學題 50+50+25*0+2+2=? 終於有數學系一展長才的地方了 首先我們要明白四則運算之中 加減是一套系統 乘除又是一套系統 為什麼呢? 因為他們的計算具有互補性質 2*2=4 4/2=2 2+2=4 4-2=2 再者 乘法具有交換性 加法也有 但減法與除法沒有 這裡就可
Thumbnail
偶然在新聞上看到一到數學題 50+50+25*0+2+2=? 終於有數學系一展長才的地方了 首先我們要明白四則運算之中 加減是一套系統 乘除又是一套系統 為什麼呢? 因為他們的計算具有互補性質 2*2=4 4/2=2 2+2=4 4-2=2 再者 乘法具有交換性 加法也有 但減法與除法沒有 這裡就可
Thumbnail
當您寫了一段 Python 的原始程式碼按下 Enter 鍵執行出結果後,您是否會好奇您寫的程式是如何被電腦認識且執行的呢?畢竟電腦只認得 0 與  1 兩個符號,而您寫的 Python 程式是英文字母組成的。這中間是如何從英文字母,轉換成 0 與 1 的呢?
Thumbnail
當您寫了一段 Python 的原始程式碼按下 Enter 鍵執行出結果後,您是否會好奇您寫的程式是如何被電腦認識且執行的呢?畢竟電腦只認得 0 與  1 兩個符號,而您寫的 Python 程式是英文字母組成的。這中間是如何從英文字母,轉換成 0 與 1 的呢?
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News