PyGame快速入門

来源:https://www.cnblogs.com/JcrLive/archive/2020/01/27/12235715.html
-Advertisement-
Play Games

pygame 快速入門 目標 1. 項目準備 2. 使用 創建圖形視窗 3. 理解 圖像 並實現圖像繪製 4. 理解 游戲迴圈 和 游戲時鐘 5. 理解 精靈 和 精靈組 項目準備 1. 新建 飛機大戰 項目 2. 新建一個 3. 導入 游戲素材圖片 游戲的第一印象 把一些 靜止的圖像 繪製到 游戲 ...


pygame 快速入門

目標

  1. 項目準備
  2. 使用 pygame 創建圖形視窗
  3. 理解 圖像 並實現圖像繪製
  4. 理解 游戲迴圈游戲時鐘
  5. 理解 精靈精靈組

項目準備

  1. 新建 飛機大戰 項目
  2. 新建一個 hm_01_pygame入門.py
  3. 導入 游戲素材圖片

游戲的第一印象

  • 把一些 靜止的圖像 繪製到 游戲視窗
  • 根據 用戶的交互 或其他情況,移動 這些圖像,產生動畫效果
  • 根據 圖像之間 是否發生重疊,判斷 敵機是否被摧毀 等其他情況

01. 使用 pygame 創建圖形視窗

小節目標

  1. 游戲的初始化和退出
  2. 理解游戲中的坐標系
  3. 創建游戲主視窗
  4. 簡單的游戲迴圈

可以將圖片素材 繪製游戲的視窗 上,開發游戲之前需要先知道 如何建立游戲視窗

1.1 游戲的初始化和退出

  • 要使用 pygame 提供的所有功能之前,需要調用 init 方法
  • 在游戲結束前需要調用一下 quit 方法
方法 說明
pygame.init() 導入並初始化所有 pygame 模塊,使用其他模塊之前,必須先調用 init 方法
pygame.quit() 卸載所有 pygame 模塊,在游戲結束之前調用!

import pygame

pygame.init()

# 游戲代碼...

pygame.quit()

1.2 理解游戲中的坐標系

  • 坐標系
    • 原點左上角 (0, 0)
    • x 軸 水平方向向 ,逐漸增加
    • y 軸 垂直方向向 ,逐漸增加

  • 在游戲中,所有可見的元素 都是以 矩形區域 來描述位置的
    • 要描述一個矩形區域有四個要素:(x, y) (width, height)
  • pygame 專門提供了一個類 pygame.Rect 用於描述 矩形區域
Rect(x, y, width, height) -> Rect

提示

  • pygame.Rect 是一個比較特殊的類,內部只是封裝了一些數字計算
  • 不執行 pygame.init() 方法同樣能夠直接使用

案例演練

需求

  1. 定義 hero_rect 矩形描述 英雄的位置和大小
  2. 輸出英雄的 坐標原點xy
  3. 輸出英雄的 尺寸寬度高度
hero_rect = pygame.Rect(100, 500, 120, 126)

print("坐標原點 %d %d" % (hero_rect.x, hero_rect.y))
print("英雄大小 %d %d" % (hero_rect.width, hero_rect.height))
# size 屬性會返回矩形區域的 (寬, 高) 元組
print("英雄大小 %d %d" % hero_rect.size)

1.3 創建游戲主視窗

  • pygame 專門提供了一個 模塊 pygame.display 用於創建、管理 游戲視窗
方法 說明
pygame.display.set_mode() 初始化游戲顯示視窗
pygame.display.update() 刷新屏幕內容顯示,稍後使用

set_mode 方法

set_mode(resolution=(0,0), flags=0, depth=0) -> Surface
  • 作用 —— 創建游戲顯示視窗
  • 參數
    • resolution 指定屏幕的 ,預設創建的視窗大小和屏幕大小一致
    • flags 參數指定屏幕的附加選項,例如是否全屏等等,預設不需要傳遞
    • depth 參數表示顏色的位數,預設自動匹配
  • 返回值
    • 暫時 可以理解為 游戲的屏幕游戲的元素 都需要被繪製到 游戲的屏幕
  • 註意:必須使用變數記錄 set_mode 方法的返回結果!因為:後續所有的圖像繪製都基於這個返回結果
# 創建游戲主視窗
screen = pygame.display.set_mode((480, 700))

1.4 簡單的游戲迴圈

  • 為了做到游戲程式啟動後,不會立即退出,通常會在游戲程式中增加一個 游戲迴圈
  • 所謂 游戲迴圈 就是一個 無限迴圈
  • 創建游戲視窗 代碼下方,增加一個無限迴圈
    • 註意:游戲視窗不需要重覆創建
# 創建游戲主視窗
screen = pygame.display.set_mode((480, 700))

# 游戲迴圈
while True:
    pass

02. 理解 圖像 並實現圖像繪製

  • 在游戲中,能夠看到的 游戲元素 大多都是 圖像
    • 圖像文件 初始是保存在磁碟上的,如果需要使用,第一步 就需要 被載入到記憶體
  • 要在屏幕上 看到某一個圖像的內容,需要按照三個步驟:
    1. 使用 pygame.image.load() 載入圖像的數據
    2. 使用 游戲屏幕 對象,調用 blit 方法 將圖像繪製到指定位置
    3. 調用 pygame.display.update() 方法更新整個屏幕的顯示

提示:要想在屏幕上看到繪製的結果,就一定要調用 pygame.display.update() 方法

代碼演練 I —— 繪製背景圖像

需求

  1. 載入 background.png 創建背景
  2. 背景 繪製在屏幕的 (0, 0) 位置
  3. 調用屏幕更新顯示背景圖像
# 繪製背景圖像
# 1> 載入圖像
bg = pygame.image.load("./images/background.png")

# 2> 繪製在屏幕
screen.blit(bg, (0, 0))

# 3> 更新顯示
pygame.display.update()

代碼演練 II —— 繪製英雄圖像

需求

  1. 載入 me1.png 創建英雄飛機
  2. 英雄飛機 繪製在屏幕的 (200, 500) 位置
  3. 調用屏幕更新顯示飛機圖像
# 1> 載入圖像
hero = pygame.image.load("./images/me1.png")

# 2> 繪製在屏幕
screen.blit(hero, (200, 500))

# 3> 更新顯示
pygame.display.update()

透明圖像

  • png 格式的圖像是支持 透明
  • 在繪製圖像時,透明區域 不會顯示任何內容
  • 但是如果下方已經有內容,會 透過 透明區域 顯示出來

理解 update() 方法的作用

可以在 screen 對象完成 所有 blit 方法之後,統一調用一次 display.update 方法,同樣可以在屏幕上 看到最終的繪製結果

  • 使用 display.set_mode() 創建的 screen 對象 是一個 記憶體中的屏幕數據對象
    • 可以理解成是 油畫畫布
  • screen.blit 方法可以在 畫布 上繪製很多 圖像
    • 例如:英雄敵機子彈...
    • 這些圖像 有可能 會彼此 重疊或者覆蓋
  • display.update() 會將 畫布最終結果 繪製在屏幕上,這樣可以 提高屏幕繪製效率增加游戲的流暢度

案例調整

# 繪製背景圖像
# 1> 載入圖像
bg = pygame.image.load("./images/background.png")

# 2> 繪製在屏幕
screen.blit(bg, (0, 0))

# 繪製英雄圖像
# 1> 載入圖像
hero = pygame.image.load("./images/me1.png")

# 2> 繪製在屏幕
screen.blit(hero, (200, 500))

# 3> 更新顯示 - update 方法會把之前所有繪製的結果,一次性更新到屏幕視窗上
pygame.display.update()

03. 理解 游戲迴圈游戲時鐘

現在 英雄飛機 已經被繪製到屏幕上了,怎麼能夠讓飛機移動呢

3.1 游戲中的動畫實現原理

  • 電影 的原理類似,游戲中的動畫效果,本質上是 快速 的在屏幕上繪製 圖像
    • 電影是將多張 靜止的電影膠片 連續、快速的播放,產生連貫的視覺效果!
  • 一般在電腦上 每秒繪製 60 次,就能夠達到非常 連續 高品質 的動畫效果
    • 每次繪製的結果被稱為 幀 Frame

3.2 游戲迴圈

游戲的兩個組成部分

游戲迴圈的開始 就意味著 游戲的正式開始

游戲迴圈的作用

  1. 保證游戲 不會直接退出
  2. 變化圖像位置 —— 動畫效果
    • 每隔 1 / 60 秒 移動一下所有圖像的位置
    • 調用 pygame.display.update() 更新屏幕顯示
  3. 檢測用戶交互 —— 按鍵、滑鼠等...

3.3 游戲時鐘

  • pygame 專門提供了一個類 pygame.time.Clock 可以非常方便的設置屏幕繪製速度 —— 刷新幀率
  • 要使用 時鐘對象 需要兩步:
    • 1)在 游戲初始化 創建一個 時鐘對象
    • 2)在 游戲迴圈 中讓時鐘對象調用 tick(幀率) 方法
  • tick 方法會根據 上次被調用的時間,自動設置 游戲迴圈 中的延時
# 3. 創建游戲時鐘對象
clock = pygame.time.Clock()
i = 0

# 游戲迴圈
while True:

    # 設置屏幕刷新幀率
    clock.tick(60)

    print(i)
    i += 1

3.4 英雄的簡單動畫實現

需求

  1. 游戲初始化 定義一個 pygame.Rect 的變數記錄英雄的初始位置
  2. 游戲迴圈 中每次讓 英雄y - 1 —— 向上移動
  3. y <= 0 將英雄移動到屏幕的底部

提示:

  • 每一次調用 update() 方法之前,需要把 所有的游戲圖像都重新繪製一遍
  • 而且應該 最先 重新繪製 背景圖像
# 4. 定義英雄的初始位置
hero_rect = pygame.Rect(150, 500, 102, 126)

while True:

    # 可以指定迴圈體內部的代碼執行的頻率
    clock.tick(60)

    # 更新英雄位置
    hero_rect.y -= 1

    # 如果移出屏幕,則將英雄的頂部移動到屏幕底部
    if hero_rect.y <= 0:
        hero_rect.y = 700

    # 繪製背景圖片
    screen.blit(bg, (0, 0))
    # 繪製英雄圖像
    screen.blit(hero, hero_rect)

    # 更新顯示
    pygame.display.update()

作業

  1. 英雄向上飛行,當 英雄完全從上方飛出屏幕後
  2. 將飛機移動到屏幕的底部
if hero_rect.y + hero_rect.height <= 0:
    hero_rect.y = 700

提示

  • Rect 的屬性 bottom = y + height
if hero_rect.bottom <= 0:
    hero_rect.y = 700

3.5 在游戲迴圈中 監聽 事件

事件 event

  • 就是游戲啟動後,用戶針對游戲所做的操作
  • 例如:點擊關閉按鈕點擊滑鼠按下鍵盤...

監聽

  • 游戲迴圈 中,判斷用戶 具體的操作

只有 捕獲 到用戶具體的操作,才能有針對性的做出響應

代碼實現

  • pygame 中通過 pygame.event.get() 可以獲得 用戶當前所做動作事件列表
    • 用戶可以同一時間做很多事情
  • 提示:這段代碼非常的固定,幾乎所有的 pygame 游戲都 大同小異
# 游戲迴圈
while True:

    # 設置屏幕刷新幀率
    clock.tick(60)

    # 事件監聽
    for event in pygame.event.get():

        # 判斷用戶是否點擊了關閉按鈕
        if event.type == pygame.QUIT:
            print("退出游戲...")

            pygame.quit()

            # 直接退出系統
            exit()

04. 理解 精靈精靈組

4.1 精靈 和 精靈組

  • 在剛剛完成的案例中,圖像載入位置變化繪製圖像 都需要程式員編寫代碼分別處理
  • 為了簡化開發步驟,pygame 提供了兩個類
    • pygame.sprite.Sprite —— 存儲 圖像數據 image位置 rect對象
    • pygame.sprite.Group

精靈

  • 在游戲開發中,通常把 顯示圖像的對象 叫做精靈 Sprite
  • 精靈 需要 有 兩個重要的屬性
    • image 要顯示的圖像
    • rect 圖像要顯示在屏幕的位置
  • 預設的 update() 方法什麼事情也沒做
    • 子類可以重寫此方法,在每次刷新屏幕時,更新精靈位置
  • 註意pygame.sprite.Sprite 並沒有提供 imagerect 兩個屬性
    • 需要程式員從 pygame.sprite.Sprite 派生子類
    • 併在 子類初始化方法 中,設置 imagerect 屬性

精靈組

  • 一個 精靈組 可以包含多個 精靈 對象
  • 調用 精靈組 對象的 update() 方法
    • 可以 自動 調用 組內每一個精靈update() 方法
  • 調用 精靈組 對象的 draw(屏幕對象) 方法
    • 可以將 組內每一個精靈image 繪製在 rect 位置
Group(*sprites) -> Group

註意:仍然需要調用 pygame.display.update() 才能在屏幕看到最終結果

4.2 派生精靈子類

  1. 新建 plane_sprites.py 文件
  2. 定義 GameSprite 繼承自 pygame.sprite.Sprite

註意

  • 如果一個類的 父類 不是 object
  • 在重寫 初始化方法 時,一定要super() 一下父類的 __init__ 方法
  • 保證父類中實現的 __init__ 代碼能夠被正常執行

屬性

  • image 精靈圖像,使用 image_name 載入
  • rect 精靈大小,預設使用圖像大小
  • speed 精靈移動速度,預設為 1

方法

  • update 每次更新屏幕時在游戲迴圈內調用
    • 讓精靈的 self.rect.y += self.speed

提示

  • imageget_rect() 方法,可以返回 pygame.Rect(0, 0, 圖像寬, 圖像高) 的對象
import pygame


class GameSprite(pygame.sprite.Sprite):
    """游戲精靈基類"""
    
    def __init__(self, image_name, speed=1):
        
        # 調用父類的初始化方法
        super().__init__()
        
        # 載入圖像
        self.image = pygame.image.load(image_name)
        # 設置尺寸
        self.rect = self.image.get_rect()
        # 記錄速度
        self.speed = speed

    def update(self, *args):
        
        # 預設在垂直方向移動
        self.rect.y += self.speed
        

4.3 使用 游戲精靈 和 精靈組 創建敵機

需求

  • 使用剛剛派生的 游戲精靈精靈組 創建 敵機 並且實現敵機動畫

步驟

  1. 使用 from 導入 plane_sprites 模塊
    • from 導入的模塊可以 直接使用
    • import 導入的模塊需要通過 模塊名. 來使用
  2. 游戲初始化 創建 精靈對象精靈組對象
  3. 游戲迴圈中精靈組 分別調用 update()draw(screen) 方法

職責

  • 精靈
    • 封裝 圖像 image位置 rect速度 speed
    • 提供 update() 方法,根據游戲需求,更新位置 rect
  • 精靈組
    • 包含 多個 精靈對象
    • update 方法,讓精靈組中的所有精靈調用 update 方法更新位置
    • draw(screen) 方法,在 screen 上繪製精靈組中的所有精靈

實現步驟

  • 1) 導入 plane_sprites 模塊
from plane_sprites import *
  • 2) 修改初始化部分代碼
# 創建敵機精靈和精靈組
enemy1 = GameSprite("./images/enemy1.png")
enemy2 = GameSprite("./images/enemy1.png", 2)
enemy2.rect.x = 200
enemy_group = pygame.sprite.Group(enemy1, enemy2)
  • 3) 修改游戲迴圈部分代碼
# 讓敵機組調用 update 和 draw 方法
enemy_group.update()
enemy_group.draw(screen)

# 更新屏幕顯示
pygame.display.update()

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 3. 如果同時拿一個板塊股票的收市價和成交額 前一篇說到,用大盤指數,如恆生指數,上證,深證,這些重要的大盤指數來做Dataframe主鍵,那麼如果是同時拿一個板塊股票的收市價和成交額,可以怎樣操作呢。 在實際開發中,應該是簡單的數據結構,容易閱讀為主,所以Dataframe的multi index ...
  • 1.線程安全:當多個線程訪問一個對象時,如果不用考慮這些線程在運行時環境下的調度和交替執行,也不需要進行額外的同步,或者在調用方法進行任何其他的協調操作,調用這個對象的行為都可以獲得正確的結果,那這個對象就是線程安全的。 2.Java語言中的線程安全 根據線程安全的安全程度由強到弱來排序,我們可以把 ...
  • 2. 金融股票數據的另一個形態,怎樣在業務內部流動,同時怎樣避免錯誤 前一篇講解了股票的原始狀態,那麼在業務過程中,數據會變成怎樣的形態,來完成眾多奇奇怪怪的業務呢,以下將會解答。 首先,任何股票都有機會停市,退市。或者退市了再二次上市。 例子,阿裡爸爸(9988.HK)在港交所二次上市。 再例如, ...
  • SQL性能下降的原因 查詢語句寫的不好 索引失效 關聯查詢太多 伺服器調優及各個參數的的設置(緩衝、線程數等等) 常見的JOIN查詢 1、SQL的執行順序 手寫的順序: 真正機器執行的順序: 2、七種join查詢 最後兩種語法mysql不支持,但是我們可以用union來聯合其他的查詢結果來拼湊出最終 ...
  • 咳咳,這個是為了趕量 需要註意的就是輸入方式,別的也沒什麼難點 Problem Description Ignatius likes to write words in reverse way. Given a single line of text which is written by Igna ...
  • 1 引言 眾所周知,模塊化編程具備很多優點,尤其在複雜項目上體現更為明顯。Python模塊化編程有助於開發者統籌兼顧和分工協作,並提升代碼靈活性和可維護性,是編程開發者不可或缺的一項重要工具。 2 Python模塊 在平時Python編程中,我們所保存的以.py為尾碼的代碼文件(如hello.py) ...
  • import sys from qdarkstyle import load_stylesheet_pyqt5 from PyQt5.QtWidgets import QApplication, QTableView from PyQt5.QtCore import QAbstractTableMo ...
  • 本地127.0.0.1可以訪問到nginx,外網ip無法訪問 解決方法:1,關閉firewall防火牆(系統自帶):service firewalld stop<不推薦>。2,開發某個埠:firewall-cmd --permanent --add-port=80/tcp: <註意重啟才能生效:f... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...