The Nature of Code閱讀心得與Python實作:1.7 Motion with Vectors

閱讀時間約 8 分鐘

在Example 1.2中,我們利用向量來寫模擬物體運動的程式。在程式中,我們先算出球的位置,然後在那個位置畫出球:

position += velocity
pygame.draw.circle(screen, BLACK, position, RADIUS)

這就是模擬物體運動的最基本做法,這個做法,可以歸納為如下的演算法:

Motion 101
1. 將位置向量加上速度以得到新的位置向量
2. 在新位置畫出物體

題外話。看到101這個數字,大概可以猜到代表的意思。不過,實在很好奇,為什麼是101,不是100或123?網上搜尋了一下,在維基百科:101 (number)找到了答案。

言歸正傳。在那個例子中,是把Motion 101相關的程式直接寫在主程式中,但這並不是個好做法。比較好的做法,是把這部分的程式封裝在一個類別中,以發揮物件導向設計的優勢。接下來,就來設計一個叫做Mover的類別,把這部分的程式封裝在其中。

在設計Mover這個類別時,必須考慮兩個問題:

  1. Mover的物件裡頭包含了哪些資料?
  2. Mover的物件具有哪些功能?

這兩個問題的答案就在Motion 101這個演算法中。

一個Mover的物件,應該含有兩份資料:位置及速度,也就是positionvelocity這兩個向量。至於它應具備的功能,其實也很簡單,就是移動及現身被看見。我們會把移動相關的程式碼寫在update()這個方法中;而現身被看見,其實也就是在畫面上畫出物件樣貌,這部分的程式碼,則寫在show()這個方法中。程式碼如下:

def update(self):
    self.position += self.velocity

def show(self):
    pygame.draw.circle(self.screen, (0, 0, 0), self.position, 24)

在建立Mover的物件時,需要先設定,也就是初始化(initialize)的東西,如起始位置、初始速度等,就寫在__init__()中:

def __init__(self):
# 取得顯示畫面的大小
self.screen = pygame.display.get_surface()
self.width, self.height = self.screen.get_size()

# 設定物件的起始位置
x = random.uniform(0, self.width)
y = random.uniform(0, self.height)
self.position = pygame.Vector2(x, y)

# 設定物件的初始速度
vx = random.uniform(-2, 2)
vy = random.uniform(-2, 2)
self.velocity = pygame.Vector2(vx, vy)

最後,我們要決定物件碰到邊界時,會怎麼反應。假設我們希望碰到邊界時,物件會繞一圈從另一邊跑出來,程式的寫法如下:

def check_edges(self):
if self.position.x > self.width:
self.position.x = 0
elif self.position.x < 0:
self.position.x = self.width

if self.position.y > self.height:
self.position.y = 0
elif self.position.y < 0:
self.position.y = self.height

這樣就完成了Mover這個類別的設計。

下面的例子,就是使用Mover這個類別產生一個物件mover,然後讓這個mover在畫面上移動。程式如下:

Example 1.7: Motion 101 (Velocity)

class Mover:
def __init__(self):
# 取得顯示畫面的大小
self.screen = pygame.display.get_surface()
self.width, self.height = self.screen.get_size()

# 設定物件的起始位置
x = random.uniform(0, self.width)
y = random.uniform(0, self.height)
self.position = pygame.Vector2(x, y)

# 設定物件的初始速度
vx = random.uniform(-2, 2)
vy = random.uniform(-2, 2)
self.velocity = pygame.Vector2(vx, vy)

def update(self):
self.position += self.velocity

def show(self):
pygame.draw.circle(self.screen, (0, 0, 0), self.position, 24)

def check_edges(self):
if self.position.x > self.width:
self.position.x = 0
elif self.position.x < 0:
self.position.x = self.width

if self.position.y > self.height:
self.position.y = 0
elif self.position.y < 0:
self.position.y = self.height


# python version 3.10.9
import random
import sys

import pygame # version 2.3.0

pygame.init()

pygame.display.set_caption("Example 1.7: Motion 101 (Velocity)")

WHITE = (255, 255, 255)

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

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

mover = Mover()

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

screen.fill(WHITE)

mover.update()
mover.check_edges()
mover.show()

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

Motion 101這個例子其實挺單調的,因為那顆球永遠都是氣定神閒地以相同的速度移動著,既不會加速,也不會減速。想要讓球的移動方式更多變、更真實一些,就必須引入加速度(acceleration)這個大家耳熟能詳的物理量。


15會員
129內容數
寫點東西自娛娛人
留言0
查看全部
發表第一個留言支持創作者!
ysf的沙龍 的其他內容
介紹如何在模擬物體運動時,引入加速度這個物理量。
介紹pygame支援的向量運算,以及向量的減法、乘法、除法實際上是怎麼計算的。
這一節談的是向量的定義,以及如何運用向量來建立模擬物體運動時,關於位置和速度間的關係式。
介紹如何在模擬物體運動時,引入加速度這個物理量。
介紹pygame支援的向量運算,以及向量的減法、乘法、除法實際上是怎麼計算的。
這一節談的是向量的定義,以及如何運用向量來建立模擬物體運動時,關於位置和速度間的關係式。
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
As we navigate through 2024, the mobile app development landscape continues to evolve, driven by changing consumer behaviors...
Thumbnail
"You live for yourselves, not for humans." About trees and their feelings of sadness due to human interference.
Now I understand: there is no need for futile treatment or ineffective care, allowing our mother nature to take over may be the kindest approach for t
Thumbnail
  簡直像站在球場中看著真實的比賽讓人目不轉睛,呼吸為之屏息——傳說中灌籃高手動畫版的遺珠之憾:湘北對山王之戰終於出世。當年所有人期盼卻沒盼得的最重要的一場比賽,在生父手下脫胎而出,讓這部作品畫下奇蹟的句點。  
Thumbnail
《The Writer And Her Story》是香港漫畫家智海在1999年的作品,黑白色調的漫畫,描寫一個抑鬱的作者,被自己腦袋裡沉重的想法壓駝了背,寫下作品想為腦袋「減重」,卻被各種瑣碎問題所困,就連繪者也彷彿以上帝之手,延伸再延伸,給他沒有盡頭的樓梯和前路...
Thumbnail
在海上看美景,也不忘笑話別人的英語口音👉「It's gorgis, ain't it?」一起來領略一世紀前馬克•吐溫的不倒幽默!
Thumbnail
英文有一些慣用的句子,字面上怎麼讀都參不透,因為不知道背後隱含的思考邏輯。「給他懷疑的好處(give him the benefit of the doubt)」這種話在中文的邏輯中根本不成文也說不通,到底是在講什麼鬼?你只能用外國人的邏輯來想!
Thumbnail
《Queen’s Gambit》第一眼看會以為又是另一個關於天才兒童戰無不勝或者自甘墮落的故事。其實這一套劇集,講的是一個高敏感又內向的女生,如何在女權崛起之前的冷戰年代,以人生輸家之姿,晉身頂級棋手的故事,同時講述一個女孩子的前半生。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
As we navigate through 2024, the mobile app development landscape continues to evolve, driven by changing consumer behaviors...
Thumbnail
"You live for yourselves, not for humans." About trees and their feelings of sadness due to human interference.
Now I understand: there is no need for futile treatment or ineffective care, allowing our mother nature to take over may be the kindest approach for t
Thumbnail
  簡直像站在球場中看著真實的比賽讓人目不轉睛,呼吸為之屏息——傳說中灌籃高手動畫版的遺珠之憾:湘北對山王之戰終於出世。當年所有人期盼卻沒盼得的最重要的一場比賽,在生父手下脫胎而出,讓這部作品畫下奇蹟的句點。  
Thumbnail
《The Writer And Her Story》是香港漫畫家智海在1999年的作品,黑白色調的漫畫,描寫一個抑鬱的作者,被自己腦袋裡沉重的想法壓駝了背,寫下作品想為腦袋「減重」,卻被各種瑣碎問題所困,就連繪者也彷彿以上帝之手,延伸再延伸,給他沒有盡頭的樓梯和前路...
Thumbnail
在海上看美景,也不忘笑話別人的英語口音👉「It's gorgis, ain't it?」一起來領略一世紀前馬克•吐溫的不倒幽默!
Thumbnail
英文有一些慣用的句子,字面上怎麼讀都參不透,因為不知道背後隱含的思考邏輯。「給他懷疑的好處(give him the benefit of the doubt)」這種話在中文的邏輯中根本不成文也說不通,到底是在講什麼鬼?你只能用外國人的邏輯來想!
Thumbnail
《Queen’s Gambit》第一眼看會以為又是另一個關於天才兒童戰無不勝或者自甘墮落的故事。其實這一套劇集,講的是一個高敏感又內向的女生,如何在女權崛起之前的冷戰年代,以人生輸家之姿,晉身頂級棋手的故事,同時講述一個女孩子的前半生。