Pygame基本介紹

日期: 2019/07/04(四)

講者: 土豆

大綱

  • 教學目標
  • 何謂遊戲
  • Pygame介紹
  • 遊戲程式結構介紹
  • Pygame基本架構
  • 繪製長方形、圓形、線條
  • 圓球掉落
  • 圓球反彈
  • 作業 - 模仿DVD螢幕保護動畫

教學目標

  1. 了解遊戲程式邏輯
    • 躲石頭小遊戲
    • 太空戰機
  2. 增進物件導向程式設計能力
  3. 練習閱讀文件
  4. 練習閱讀程式碼
  5. 從教學內容延伸,開發出完整的遊戲

何謂遊戲

輸出

輸入

邏輯

聲音

影像

鍵盤

滑鼠

搖桿

座標在哪,

怎麼移動座標

碰撞判斷

數值計算

事件判斷

按下向上了,y座標減少

Pygame介紹

Pygame is a Python wrapper module for the SDL multimedia library

Pygame是將SDL多媒體函式庫幫裝起來讓你易於使用的模組

  • SDL: Simple DirectMedia Layer,以C語言撰寫
  • multimedia: 多媒體

所以Pygame不只可以用來做遊戲,跟多媒體有關的東西它都可以做

來看看Pygame做出來的遊戲吧

遊戲程式結構介紹

遊戲開始畫面
遊戲主迴圈
        確認使用者輸入
        更新座標
        碰撞判斷
        繪製圖像
        播放音效
遊戲結束畫面

Pygame基本架構

先安裝好Pygame的Package

pip install pygame

請Trace這段程式,並跑起來看看效果

initial_screen.py

初始化視窗

import pygame

pygame.init()

DISPLAY_WIDTH = 800
DISPLAY_HEIGHT = 600

gameDisplay = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
pygame.display.set_caption("Hello World")
# ...下面還有喔...

init()會測試所有用到的Pygame模組

設定視窗寬高

設定視窗標題

定義顏色

# ...接著上面的寫...
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# ...下面還有喔...

Pygame使用Tuple來定義顏色

裡面包含R, G, B三個值

新增clock物件

# ...接著上面的寫...
clock = pygame.time.Clock()
# ...下面還有喔...

將time模組中的Clock類別實例化成物件

我們可以用這個物件控制幀數

遊戲主迴圈

# ...接著上面的寫...
playing = True
while playing:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            playing = False
    clock.tick(30)
# ...下面還有喔...

這個迴圈只做一件事情

判斷使用者有沒有按下X,如果有就停止迴圈

clock.tick(30),會使這個迴圈控制在每秒跑30次

結束遊戲

# ...接著上面的寫...
pygame.quit()
quit()

一旦跳出迴圈就馬上執行這行,結束pygame與python

繪製長方形、圓形、線條

請Trace這段程式,並跑起來看看效果

draw_shape.py

繪製長方形

先來看看文件怎麼說

繪製長方形

rect(Surface, color, Rect, width=0)
  • Surface: 要畫在哪張畫布上
  • color: 顏色,用一個Tuple表示
  • Rect: 邊框物件,可使用pygame.Rect()進行初始化,需傳入四個參數,top、left、width、height
  • width: 邊框,預設為0

繪製長方形

# 將此行加入遊戲主迴圈
pygame.draw.rect(gameDisplay, RED, pygame.Rect(100, 100, 50, 50))

畫出正方形,左上角位於100, 100,長寬皆為50

繪製圓形

一樣,讓我們看看文件

circle(Surface, color, pos, radius, width=0)
  • pos: 圓心的x, y座標,一個Tuple
  • radius: 半徑

繪製圓形

# 將此行加入遊戲主迴圈
pygame.draw.circle(gameDisplay, GREEN, (200, 100), 25)

圓心在200, 100,半徑為25的圓形

繪製線條

不用我說了吧,請看文件

繪製線條

line(Surface, color, start_pos, end_pos, width=1)
  • start_pos: 線開始的點
  • end_pos: 線結束的點
# 將這兩行加入遊戲主迴圈
pygame.draw.line(gameDisplay, BLUE, (300, 100), (300, 400))
pygame.draw.line(gameDisplay, BLUE, (350, 100), (350, 400), 5)

兩條線,長300,中間間隔50,第二條線粗度為5

都畫完後,要執行pygame.display.update()

圖形才會真正的更新到畫布上

練習題

請用半小時畫出小叮噹

使用圓形、直線、橢圓形即可

請自行查找如何畫出橢圓形

google搜尋color picker可以幫你產生色碼

參考範例

圓球掉落

請Trace這段程式,並跑起來看看效果

ball_drop.py

每跑一次迴圈,就更新一次圓球的y座標

讓它數值稍微變大一點,然後再將圓球畫出

原理

import pygame

pygame.init()

DISPLAY_WIDTH = 800
DISPLAY_HEIGHT = 600

gameDisplay = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
pygame.display.set_caption("Ball Drop")

WHITE = (255, 255, 255)
GREEN = (0, 255, 0)

ball_x = 400
ball_y = 0

clock = pygame.time.Clock()
# ...下面還有...

設定視窗、標題、顏色、clock,並初始化球的x, y座標

# ...接著上面的寫喔...
playing = True
while playing:
    for event in pygame.event.get():
	if event.type == pygame.QUIT:
	    playing = False
    ball_y += 5
    pygame.draw.circle(gameDisplay, GREEN, (ball_x, ball_y), 25)
    pygame.display.update()
    clock.tick(30)

pygame.quit()
quit()

每一次迴圈都將ball_y的值加上5之後才畫出

然後你就會看到一個很奇怪的畫面

這是因為上次畫的圓還留在原地沒有消失

每次畫圓之前先將畫面清空即可解決

# ...接著上面的寫喔...
playing = True
while playing:
for event in pygame.event.get():
    if event.type == pygame.QUIT:
        playing = False
    ball_y += 5
    gameDisplay.fill(WHITE) # 使用fill()將畫面填入白色,以清空畫面
    pygame.draw.circle(gameDisplay, GREEN, (ball_x, ball_y), 25)
    pygame.display.update()
    clock.tick(30)

pygame.quit()
quit()

圓球反彈

請Trace這段程式,並跑起來看看效果

ball_rebound.py

沿用ball_drop的程式碼,但是這次我們希望球碰到上邊框或是下邊框時會回彈,形成來回彈動的效果。

import pygame

pygame.init()

# ...上面都不變喔...
ball_x = 400
ball_y = 0
direction = 1 # 新增direction變數
# ...下面還有...

新增一個direction的變數,用來控制方向

# ...前面都不變...
while playing:
	# ...前面都不變...
	ball_y += 10 * direction # 更新y座標前先乘以direction
    # ...後面也不變...
# ...後面也不變...

更新座標時我們要乘以direction變數

direction為1,y值增加,往下移動

反之,direction為-1則y值減少,往上移動

# ...
while playing:
    # ...
    ball_y += 10 * direction
    # ...新增這段...
    if ball_y <= 0:
        direction = 1
    elif ball_y >= 600:
        direction = -1
    # ...新增這段...
    # ...
# ...

每次更新完座標後,確認目前座標

如果小於等於零(超出上邊界),或是大於等於600(超出下邊界)

就改變direction的值,讓它往反方向跑

然後就出現一個問題

球並不是在一碰到邊邊的時候就回彈

而是中心點的位置碰到時才會回彈

# ...
while playing:
    # ...
    ball_y += 10 * direction
    # ...改成這樣...
    if ball_y - 25 <= 0:
        direction = 1
    elif ball_y + 25 >= 600:
        direction = -1
    # ...改成這樣...
    # ...
# ...

因為判斷時,使用圓心作為座標基準點,當圓心超出範圍時才會回彈

解決這個問題,需考慮圓的半徑值

假設減去半徑之後小於等於0,或是加上半徑之後大於等於600

則改變方向

作業 - 模仿DVD螢幕保護動畫

期限

7/11晚上八點前

如果你不是我那個年代的人,請看這個影片

要求如下

  1. 要有一個橢圓形(裡面不用有字,字做得出來請你吃東西),可以參考文件看看怎麼畫出橢圓形,大小隨意,適中即可
  2. 這個橢圓形要能夠往八個方向移動(上、右上、右、右下、下、左下、左、左上)
  3. 一開始從畫面上半部出發,往任意方向移動
  4. 碰到邊界時要進行反彈,如影片那樣
  5. Bonus: 如果能做到每次反彈都變更顏色,合宿時我請你25塊內的飲料(如果是夜貓只有10塊錢麥香)

參考範例

謝謝大家的聆聽

下課

Made with Slides.com