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)這個大家耳熟能詳的物理量。


avatar-img
15會員
131內容數
寫點東西自娛娛人
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
ysf的沙龍 的其他內容
介紹如何在模擬物體運動時,引入加速度這個物理量。
介紹pygame支援的向量運算,以及向量的減法、乘法、除法實際上是怎麼計算的。
這一節談的是向量的定義,以及如何運用向量來建立模擬物體運動時,關於位置和速度間的關係式。
介紹如何在模擬物體運動時,引入加速度這個物理量。
介紹pygame支援的向量運算,以及向量的減法、乘法、除法實際上是怎麼計算的。
這一節談的是向量的定義,以及如何運用向量來建立模擬物體運動時,關於位置和速度間的關係式。
你可能也想看
Google News 追蹤
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這篇內容,將會講解什麼是變數,以及與變數相關的知識。包括變數、資料型態、變數賦值、變數的命名規則、變數的作用區域、變數的可重複性、內建變數。
Thumbnail
這篇內容,將透過實戰教學,來講解「滑鼠點方塊」的程式碼。包括如何測試遊戲、座標系統、自訂參數和內建參數、if else、and、遊戲的邏輯設計、程式碼解析。
Thumbnail
直觀理解 導數:考慮的是單一變數的函數,描述的是函數在某點的斜率或變化率。 偏導數:考慮的是多變數函數,描述的是函數在某個變數變化時的變化率,其他變數保持不變。  (針對各維度的調整 或者稱變化 你要調多少) 應用 導數:在物理學中應用廣泛,例如描述速度和加速度。 偏導數:在多變量分析、優
Thumbnail
建立幾個變數如下,最上面兩個變數值為清單值 接下來分別設定球1位置到左上角落、設定球2位置到右上角落、設定球3位置到左下角落、設定球4位置到右下角落 當螢幕初始化的時候,設定玩家球的X、Y座標和大小,並將玩家球的初始顏色,設定成(變數_顏色清單)中.....
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這篇內容,將會講解什麼是變數,以及與變數相關的知識。包括變數、資料型態、變數賦值、變數的命名規則、變數的作用區域、變數的可重複性、內建變數。
Thumbnail
這篇內容,將透過實戰教學,來講解「滑鼠點方塊」的程式碼。包括如何測試遊戲、座標系統、自訂參數和內建參數、if else、and、遊戲的邏輯設計、程式碼解析。
Thumbnail
直觀理解 導數:考慮的是單一變數的函數,描述的是函數在某點的斜率或變化率。 偏導數:考慮的是多變數函數,描述的是函數在某個變數變化時的變化率,其他變數保持不變。  (針對各維度的調整 或者稱變化 你要調多少) 應用 導數:在物理學中應用廣泛,例如描述速度和加速度。 偏導數:在多變量分析、優
Thumbnail
建立幾個變數如下,最上面兩個變數值為清單值 接下來分別設定球1位置到左上角落、設定球2位置到右上角落、設定球3位置到左下角落、設定球4位置到右下角落 當螢幕初始化的時候,設定玩家球的X、Y座標和大小,並將玩家球的初始顏色,設定成(變數_顏色清單)中.....