iT邦幫忙

2

【pygame初體驗】學習用pygame來打造自己的遊戲

哈囉~ 大家好,
可以用程式寫出一個自己的遊戲,
大概是很多人學習程式的夢想

pygame是python語言中一個專門用來開發遊戲的模組,
來嘗試用用看吧

一、開發環境

我用的開發環境是用anaconda來寫python程式,
不會安裝的可以參考【Python 超入門】(1) 心原一馬從零開始帶你學程式安裝看看,
這篇安裝anaconda的教學是一年前寫的,
細節可能有變動,大家在自己舉一反三

二、在anaconda安裝pygame

【步驟一】
到網站https://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame
然後選擇適用自己電腦的python版本:
例如: 64位元電腦,python版本3.7,
選取塗螢光筆的那個:
https://ithelp.ithome.com.tw/upload/images/20200701/20117114Uhl3tlnCow.png

【步驟二】
然後把載下來的檔案放到跟「Anaconda prompt」同一個目錄的位置,
輸入「pip install xxx.whl(檔案名稱)」就可以裝好囉~

【舉例說明】
在Anaconda prompt環境下,
先用「cd C:\Program Files」切換到C槽Program Files這個資料夾(你也可以選其它的資料夾),
然後把檔案放到自己電腦上C槽Program Files這個資料夾的位置上:
https://ithelp.ithome.com.tw/upload/images/20200701/20117114v5O6AHWc9f.png

輸入「pip install pygame-1.9.6-cp37-cp37m-win_amd64.whl」(注意要輸入附檔名.whl)
因為小馬的電腦上已安裝,顯示「Requirement already satisfied」,
若還沒安裝則顯示「Successfully installed pygame」
https://ithelp.ithome.com.tw/upload/images/20200701/20117114HbEU1LC5PD.png

舉一反三一下(不想看的話可略過此部分),
這個安裝方法很實用,
假設未來想要安裝pyOpenGL模組,安裝方法雷同,
變成到https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyopengl
例如: 64位元電腦,python版本3.7,
就選底下兩個
https://ithelp.ithome.com.tw/upload/images/20200701/20117114N0r6Scjuhd.png
一樣把檔案放到跟「Anaconda prompt」同一個目錄的位置,
輸入「pip install xxx.whl(檔案名稱)」就可以裝好囉~

三、基礎架構

我覺得pygame的基礎架構相對複雜的多,
「繪圖視窗」和「畫布」是分開的,
通常不會直接在繪圖視窗畫圖,
而會先畫在「畫布」上,再把畫布貼到「繪圖視窗」上,
我在想這樣做可能是為了方便切換不同的遊戲場景吧

底下是基礎架構,
小馬加上註解方便理解

import pygame
pygame.init()  #pygame初始化

# 設定視窗
width, height = 640, 320
screen = pygame.display.set_mode((width, height))  #建立繪圖視窗
pygame.display.set_caption("基本架構")  #繪圖視窗標題

#建立畫布 (書上說通常不會直接在繪圖視窗畫圖)
background = pygame.Surface(screen.get_size())  
background = background.convert() #為畫布建立副本,加快顯示速度
background.fill((255,255,255))  #畫布為白色(三個參數為RGB)
screen.blit(background, (0,0))  #在繪圖視窗繪製畫布

running = True
while running:  #無窮迴圈
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  #使用者按右上角的關閉鈕
            running = False
    pygame.display.update()  #更新繪圖視窗
    
pygame.quit()  #關閉繪圖視窗

成功的話,會出現這樣的空白視窗:
https://ithelp.ithome.com.tw/upload/images/20200701/20117114GjaGXi8zvY.png

這邊記錄一個腦袋小打結的地方,
自己想說為什麼while迴圈那段不乾脆直接寫break看起來更簡潔呢?
還要多設一個running = True的變數

# 錯誤示範
while True:  #無窮迴圈
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  #使用者按右上角的關閉鈕
            break
    pygame.display.update()  #更新繪圖視窗

後來想到,break只會跳出迴圈for event in pygame.event.get()
並不會跳出while迴圈啊

四、顯示文字

關於如何在pygame裡面顯示中文,
小馬研究了非常久

根據<python初學特訓班>電子書附錄B的做法,
使用內建字型SysFont裡的"simhei"便能顯示中文,
例如:
pygame.font.SysFont("simhei", 32)
但小馬用了這個方法怎樣寫顯示不出來。

小馬查了該書用的環境是anaconda-> Spyder, python3.6,
推測或許是python版本不相容的問題。
上網查了可以自己載中文字體,副檔名為.ttf(我忘記載點了,大家可以自己找找看,另外,不一定下載的每個字體都能用,要看運氣),
將檔案放在跟程式碼相同根目錄的地方(例如將檔案名稱改為sung.ttf表示「正宋體」),
利用pygame.font.Font("sung.ttf", 32)才可顯示中文

程式碼範例:

import pygame
pygame.init()  #pygame初始化

# 設定視窗
width, height = 640, 320
screen = pygame.display.set_mode((width, height))  #建立繪圖視窗
pygame.display.set_caption("繪製文字")  #繪圖視窗標題

# 創建顏色(三個參數為RGB)
GREEN = (0,255,0) # 綠色
RED = (255,0,0) # 紅色
BLUE = (0,0,255) # 藍色
WHITE = (255,255,255) # 白色

# 建立畫布 (書上說通常不會直接在繪圖視窗畫圖)
background = pygame.Surface(screen.get_size())  
background = background.convert() #為畫布建立副本,加快顯示速度
background.fill(GREEN)


# 創建文字
font1 = pygame.font.Font("sung.ttf", 32) #若你沒有下載字體,可以用系統內建的 pygame.font.SysFont("simhei", 32),但我測試不能顯示中文
text1 = font1.render("顯示中文", True, RED, WHITE)  #紅字白底
background.blit(text1, (20,10))
text2 = font1.render("Show english.", True, BLUE, GREEN)  #藍字綠底
background.blit(text2, (20,50))

# 遊戲主要無窮迴圈
running = True
while running:  
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  #使用者按右上角的關閉鈕
            running = False
    screen.blit(background, (0,0)) #在繪圖視窗繪製畫布
    pygame.display.update()  #更新繪圖視窗

del font1 # 十分必要,確保第二次執行程式能夠正確執行
pygame.quit()  # 關閉繪圖視窗

效果:
https://ithelp.ithome.com.tw/upload/images/20200702/20117114ZEGiaDsS5w.png

這邊注意我的倒數第二行寫了del font1
因為我發現在anaconda的spyder底下執行程式,
若沒有這一行,再次執行程式就當掉了,
推測可能是視窗關掉了但有些必要的東西沒有跟著關掉導致的資料錯誤。

五、基礎圖形繪製

pygame裡面可以繪制簡單的幾何圖形,
你可以將它們組成你的遊戲角色
常見的基礎指令如下:

函數名稱 功能
pygame.draw.rect(畫布, 顏色, [x座標, y座標, 寬, 高], 線寬) 矩形
pygame.draw.circle(畫布, 顏色, (x座標, y座標), 線寬) 圓形
pygame.draw.ellipse(畫布, 顏色, [x座標, y座標, x直徑, y直徑], 線寬) 橢圓
pygame.draw.arc(畫布, 顏色, [x座標, y座標, x直徑, y直徑], 起始角(單位為弧度), 結束角, 線寬) 圓弧
pygame.draw.line(畫布, 顏色, (x座標1, y座標1), (x座標2, y座標2), 線寬) 直線
pygame.draw.polygon(畫布, 顏色, 點座標列表, 線寬) 多邊形

畫形狀時,若線寬=0,則會畫出實心圖形,否則為空心。

範例- 畫簡易人臉

import pygame
pygame.init()  #pygame初始化

# 設定視窗
width, height = 320, 320
screen = pygame.display.set_mode((width, height))  #建立繪圖視窗
pygame.display.set_caption("繪製基本圖形")  #繪圖視窗標題

# 創建顏色(三個參數為RGB)
GREEN = (0,255,0) # 綠色
RED = (255,0,0) # 紅色
BLUE = (0,0,255) # 藍色
WHITE = (255,255,255) # 白色
BLACK = (0,0,0) # 黑色

# 建立畫布 (書上說通常不會直接在繪圖視窗畫圖)
background = pygame.Surface(screen.get_size())  
background = background.convert() #為畫布建立副本,加快顯示速度
background.fill(WHITE)

# 繪製基本圖形
pygame.draw.circle(background, BLACK, (150,150), 130, 4)
pygame.draw.circle(background, BLUE, (100,120), 25, 0)
pygame.draw.circle(background, BLUE, (200,120), 25, 0)
pygame.draw.ellipse(background, GREEN,[135, 130, 30, 80], 0)
pygame.draw.arc(background, RED, [80, 130, 150, 120], 3.4, 6.1, 9)

# 遊戲主要無窮迴圈
running = True
while running:  
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  #使用者按右上角的關閉鈕
            running = False
    screen.blit(background, (0,0)) #在繪圖視窗繪製畫布
    pygame.display.update()  #更新繪圖視窗

pygame.quit()  # 關閉繪圖視窗

效果:
https://ithelp.ithome.com.tw/upload/images/20200702/20117114hvqKi1qDD4.png

六、動畫基礎

能夠讓遊戲角色起來,是遊戲中的靈魂,
主要會用到clock = pygame.time.Clock()clock.tick(次數)指令設定每秒重繪的次數

這邊示範一個讓藍球左右移動的小例子,
每一行程式我都儘量註解說明了:

import pygame
pygame.init()  #pygame初始化

# 設定視窗
width, height = 640, 70
screen = pygame.display.set_mode((width, height))  #建立繪圖視窗
pygame.display.set_caption("水平移動")  #繪圖視窗標題

# 創建顏色(三個參數為RGB)
GREEN = (0,255,0) # 綠色
RED = (255,0,0) # 紅色
BLUE = (0,0,255) # 藍色
WHITE = (255,255,255) # 白色
BLACK = (0,0,0) # 黑色
YELLOW = (255,255,0) #黃色

# 建立畫布 (書上說通常不會直接在繪圖視窗畫圖)
background = pygame.Surface(screen.get_size())  
background = background.convert() #為畫布建立副本,加快顯示速度
background.fill(WHITE)

# 創建藍色小球(它也有自己的畫布,移動球即等於移動它的畫布)
ball = pygame.Surface((30,30))  #建立球矩形繪圖區
ball.fill((255,255,0))  #這邊我故意將球的背景色設為黃色,以清楚看到球的畫布
pygame.draw.circle(ball, (0,0,255), (15,15), 15, 0)  #畫藍色球
rect1 = ball.get_rect()  #取得球矩形區塊
rect1.center = (320,45)  #球起始中心位置
x, y = rect1.topleft  #球左上角坐標
dx = 3  #球運動速度


# 遊戲主要無窮迴圈
clock = pygame.time.Clock() #重要,計時物件
running = True
while running:  
    clock.tick(30)  #每秒執行30次
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  #使用者按右上角的關閉鈕
            running = False
    
    # 藍色小球動畫
    x += dx  #改變水平位置
    rect1.center = (x,y)
    if rect1.left <= 0 or rect1.right >= screen.get_width():  #若到達左右邊界,往反向移動
        dx *= -1
        
    screen.blit(background, (0,0)) # 在繪圖視窗繪製畫布
    screen.blit(ball, rect1.topleft) # 繪製藍色小球
    pygame.display.update()  #更新繪圖視窗

pygame.quit()  # 關閉繪圖視窗

效果(球是會左右移動的,建議自己執行程式較有感覺):
https://ithelp.ithome.com.tw/upload/images/20200702/20117114XUoJ6crS1Q.png

<自我學習>
請嘗試更改
dx = 3 #球運動速度
clock.tick(30) #每秒執行30次
感受這兩個參數對控制球速的方式有什麼差異?

(試試改dx = 30clock.tick(3)?)

以上便是pygame的基礎了,希望大家也能發揮創意,
做出自己的遊戲哦

小馬之後也會嘗試做遊戲試試看

參考資料

  1. python遊戲編程之旅(共九篇)
  2. 書本- Python初學特訓班/ 出版社:碁峰

1 則留言

1
s23699
iT邦新手 5 級 ‧ 2020-07-02 16:16:41
心原一馬 iT邦研究生 5 級 ‧ 2020-07-02 20:05:26 檢舉

謝謝~ 也祝你學習順利~

我要留言

立即登入留言