URLhttps://learnscript.net/zh-hant/pygame/font/
    複製連結移至說明  範例

    如何尋找和載入遊戲字型?以及取得和設定字型樣式等問題

    閱讀 24:03·字數 7215·更新 
    Youtube 頻道
    訂閱 375

    雖然本節的範例中包含繪製文字的程式碼,但本節不會講解與文字繪製相關的問題,要了解文字繪製,請檢視在表面中繪製影像和文字(字型)一段。

    Pygame 中的 font 模組

    Pygame 套件的font模組,包含了與字型相關的功能,主要涉及字型的載入(取得),以及字型的繪製(本節內容不涉及此部分),當你匯入pygame模組時,font模組會被pygame模組匯入。

    初始化 font 模組

    pygame模組一樣,font模組擁有用於初始化的函式init,該函式會在pygame模組的init函式中被呼叫,這意味著一旦使用pygame模組進行初始化,呼叫font模組的init函式將是沒有必要的。

    init()

    可以重複呼叫 init 函式

    你可以反覆呼叫init函式,這沒有任何問題,即便在呼叫quit函式之後。

    font.py
    # 匯入模組 font
    from pygame import font
    
    # 初始化 font.init()

    判斷 font 模組是否已經初始化

    pygame模組一樣,font模組擁有判斷font模組是否已經初始化的函式get_init

    get_init()

    傳回值

    如果get_init函式傳回True,那麽表示font模組已經進行了初始化。

    在呼叫 quit 函式之後,get_init 函式將傳回 False

    在呼叫quit函式之後,get_init函式將傳回False,這表示再次呼叫init函式將產生實際效果,他會重新初始化font模組。

    font.py
    # …
    print(f'font 已經初始化?{font.get_init()}')
    font 已經初始化?True

    取消初始化 font 模組

    pygame模組一樣,font模組擁有用於取消初始化的函式quit,該函式會在pygame模組的quit函式中被呼叫,這意味著一旦使用pygame模組取消了初始化,呼叫font模組的quit函式將是沒有必要的。

    quit()

    可以重複呼叫 quit 函式

    init函式一樣,你可以反覆呼叫quit函式,這沒有任何的問題。

    取得所有可用字型的名稱

    font模組的get_fonts函式,可用於取得所有可用的字型的名稱。

    get_fonts()

    傳回值

    get_fonts函式的傳回值是一個 Python 字串串列,每一個字串對應一個字型名稱。

    在 Pygame 2.1.3 以及之後的版本中,除了系統字型,函式get_fonts還會檢索使用者字型,對於 Windows 作業系統而言。

    get_fonts 函式會簡化字型名稱

    get_fonts函式會將字型名稱改為小寫,同時,對於字型名稱中包含的空格或標點,get_fonts會嘗試去除他們。

    font.py
    # …
    # 取得所有可用字型的名稱
    print(font.get_fonts())
    ['arial', 'arialblack', 'bahnschrift', ]

    取得預設字型的檔案名

    font模組的get_default_font函式,可用於取得 Pygame 預設字型的檔案名稱。

    get_default_font()

    傳回值

    get_default_font函式的傳回值是一個 Python 字串,表示預設字型的檔案名稱(不是檔案路徑)。

    Pygame 套件所使用的預設字型

    Pygame 套件所使用的預設字型並非作業系統的預設字型,一般情況下,Pygame 的預設字型檔案(freesansbold.ttf)所在的目錄與pygame模組所在的目錄相同,但預設字型檔案也可能被組合在其他檔案中。

    這裏需要指出,即便 Pygame 套件所使用的預設字型檔案不存在,font模組的get_default_font函式還是會傳回其名稱。

    font.py
    # …
    # 取得預設字型的檔案名稱
    print(font.get_default_font())
    freesansbold.ttf

    取得指定字型的檔案路徑

    font模組的match_font函式,可用於取得最符合給出條件的字型的檔案路徑,當然,該函式所找到的字型可能並不完全符合你的要求。

    就像 CSS 的font-family一樣,你可以為font模組的match_font函式指定多個字型名稱,match_font將依次檢索這些字型名稱以及其他條件(粗體,斜體),當某個字型可用時,將傳回該字型的檔案路徑。

    match_font(name, bold=False, italic=False)

    name 參數

    name參數可以是一個字串,表示需要取得檔案路徑的字型的名稱,多個字型名稱使用,進行分隔。name參數也可以是包含多個字型名稱的疊代器物件,比如包含多個字型名稱的 Python 元組。

    如果你不知道應該如何書寫字型名稱,那麽可以使用get_fonts函式來檢視可用的字型名稱有哪些,詳情請參考取得所有可用字型的名稱一段。

    bold 參數

    bold參數是一個布林值,如果設定為True,那麽將嘗試取得粗體字型的檔案路徑。

    italic 參數

    italic參數是一個布林值,如果設定為True,那麽將嘗試取得斜體字型的檔案路徑。

    傳回值

    match_font函式將傳回包含字型檔案路徑的字串,如果未找到字型,則傳回空值None

    在 Pygame 2.1.3 以及之後的版本中,除了系統字型,函式match_font還會檢索使用者字型,對於 Windows 作業系統而言。

    match_font 函式會簡化字型名稱

    match_font函式會將字型名稱改為小寫,如果name參數所表示的字型名稱包含空格或標點符號(不包括英文,),那麽match_font將嘗試去除空格和標點符號。

    在下面的範例中,我們給出了兩個字型名稱,由於第一個字型tahoma有效,雖然只找到了粗體樣式(沒有找到粗斜體樣式),因此,第二個字型不會被檢測,第二個字型名稱Sitka Text等同於sitkatext

    font.py
    # …
    # 取得字型檔案的路徑
    print(font.match_font('tahoma,Sitka Text', True, True))
    # Windows 中的輸出結果
    C:\WINDOWS\Fonts\tahomabd.ttf

    為遊戲載入字型

    font模組的Font類別,可將指定的字型檔案載入到遊戲中,只需要在建立其執行個體時,指定字型檔案的路徑以及字型的大小。

    Font(name, size)

    name 參數

    name參數是表示字型檔案路徑的字串,或包含字型檔案路徑的類路徑(path-like)物件,或包含字型資料的IO物件。

    如果未設定參數name或該參數為空值None,那麽 Pygame 將使用預設字型。如果字型檔案不存在,那麽將導致例外狀況FileNotFoundError

    size 參數

    size參數是一個表示字型大小的 Python 整數,預設大小為12

    無法通過 Font 物件修改字型大小

    需要說明的是,一旦建立了Font類別的執行個體,你將無法通過該執行個體修改字型的大小。

    在下面的範例中,我們首先使用match_font函式取得了字型Microsoft JhengHei的檔案路徑,然後根據該路徑建立了一個Font物件,以將對應的字型載入到遊戲中。

    load.py
    # 匯入並初始化 font 模組
    from pygame import font
    font.init()
    
    # 取得字型檔案的路徑,並建立一個字型物件 path = font.match_font('Microsoft JhengHei') # 字型將采用預設大小 12 f = font.Font(path)
    # 建立遊戲視窗,並使用字型物件 f 繪製文字 from pygame import display w = display.set_mode((800, 600))
    # 在遊戲視窗中繪製文字 ts = f.render('你好!', False, [255, 255, 255]) w.blit(ts, [200, 200]) display.flip()
    # 等候 3 秒 import time time.sleep(3)

    取得和設定字型是否擁有粗體樣式

    Font物件的get_boldset_bold方法,以及bold變數,可用於取得和設定遊戲字型是否擁有粗體樣式。

    如果 Pygame 所載入的字型檔案本身為粗體樣式,那麽使用Font物件的set_bold方法或修改其bold變數,將不會產生任何效果,即你不能以非粗體樣式來繪製粗體文字。如果 Pygame 所載入的字型檔案本身為非粗體樣式,那麽也應盡量避免使用Font物件的set_bold方法或修改其bold變數,以粗體樣式來繪製非粗體文字(因為這需要計算),實作粗體效果應首先考慮載入對應的粗體字型檔案。

    get_bold()

    傳回值

    如果get_bold傳回True,則表示以粗體樣式繪製文字。

    set_bold(value)

    value 參數

    value參數是一個布林值,如果為True,則表示以粗體樣式繪製文字。

    font.bold
    font.bold = bold

    bold 值

    bold是一個布林值,如果為True,則表示以粗體樣式繪製文字。

    在下面的範例中,我們載入了一個非粗體字型檔案,通過修改bold變數,遊戲中的文字將以粗體樣式繪製。

    bold.py
    # 匯入並初始化 font 模組
    from pygame import font
    font.init()
    
    # 載入一個非粗體字型檔案,字型大小 24 f = font.Font(font.match_font('Microsoft JhengHei'), 24)
    # 修改為粗體樣式 f.bold = True print(f'粗體?{f.get_bold()}')
    # 建立遊戲視窗,並使用字型物件 f 繪製文字 from pygame import display w = display.set_mode((800, 600))
    # 在遊戲視窗中繪製文字 ts = f.render('以粗體樣式繪製', False, [255, 0, 0]) w.blit(ts, [50, 50]) display.flip()
    # 等候 3 秒 import time time.sleep(3)
    粗體?True

    取得和設定字型是否擁有斜體樣式

    Font物件的get_italicset_italic方法,以及italic變數,可用於取得和設定遊戲字型是否擁有斜體樣式。

    如果 Pygame 所載入的字型檔案本身為斜體樣式,那麽使用Font物件的set_italic方法或修改其italic變數,將不會產生任何效果,即你不能以非斜體樣式來繪製斜體文字。如果 Pygame 所載入的字型檔案本身為非斜體樣式,那麽也應盡量避免使用Font物件的set_italic方法或修改其italic變數,以斜體樣式來繪製非斜體文字(因為這需要計算),實作斜體效果應首先考慮載入對應的斜體字型檔案。

    get_italic()

    傳回值

    如果get_italic傳回True,則表示以斜體樣式繪製文字。

    set_italic(value)

    value 參數

    value參數是一個布林值,如果為True,則表示以斜體樣式繪製文字。

    font.italic
    font.italic = italic

    italic 值

    italic是一個布林值,如果為True,則表示以斜體樣式繪製文字。

    在下面的範例中,我們載入了一個斜體字型檔案,雖然嘗試通過set_italic方法為字型取消斜體樣式,但這不會產生任何效果。

    italic.py
    # 匯入並初始化 font 模組
    from pygame import font
    font.init()
    
    # 載入一個斜體字型檔案 f = font.Font(font.match_font('Arial', italic=True), 30)
    # 無法將斜體修改為非斜體 f.set_italic(False) print(f'斜體?{f.get_italic()}')
    # 建立遊戲視窗,並使用字型物件 f 繪製文字 from pygame import display w = display.set_mode([800, 600])
    # 在遊戲視窗中繪製文字 ts = f.render('Draw in italic style', True, (0, 255, 0)) w.blit(ts, (200, 200)) display.flip()
    # 等候 3 秒 import time time.sleep(3)
    斜體?True

    取得和設定字型是否擁有底線樣式

    Font物件的get_underlineset_underline方法,以及underline變數,可用於取得和設定遊戲字型是否擁有底線樣式。

    get_underline()

    傳回值

    如果get_underline傳回True,則表示以底線樣式繪製文字。

    set_underline(value)

    value 參數

    value參數是一個布林值,如果為True,則表示以底線樣式繪製文字。

    font.underline
    font.underline = underline

    underline 值

    underline是一個布林值,如果為True,則表示以底線樣式繪製文字。

    underline.py
    # 匯入並初始化 font 模組
    from pygame import font
    font.init()
    
    # 載入 Pygame 預設字型,字型大小 30 f = font.Font(size=30) # 修改為底線樣式 f.set_underline(True)
    # 建立遊戲視窗,並使用字型物件 f 繪製文字 from pygame import display w = display.set_mode((800, 600))
    # 在遊戲視窗中繪製文字 w.blit(f.render('Underline', False, [255, 0, 255]), [200, 200]) display.flip()
    # 等候 3 秒 import time time.sleep(3)

    取得和設定字型是否擁有刪除線樣式

    Font物件的get_strikethroughset_strikethrough方法,以及strikethrough變數,可用於取得和設定遊戲字型是否擁有刪除線樣式。

    get_strikethrough()

    傳回值

    如果get_strikethrough傳回True,則表示以刪除線樣式繪製文字。

    set_strikethrough(value)

    value 參數

    value參數是一個布林值,如果為True,則表示以刪除線樣式繪製文字。

    font.strikethrough
    font.strikethrough = strikethrough

    strikethrough 值

    strikethrough是一個布林值,如果為True,則表示以刪除線樣式繪製文字。

    strikethrough.py
    # 匯入並初始化 font 模組
    from pygame import font
    font.init()
    
    # 載入第一個可用的字型 fontname = font.get_fonts()[0] f = font.Font(font.match_font(fontname)) # 修改為刪除線樣式 f.strikethrough = True
    # 建立遊戲視窗,並使用字型物件 f 繪製文字 from pygame import display w = display.set_mode((800, 600))
    # 在遊戲視窗中繪製文字 w.blit(f.render('Strikethrough', False, [255, 255, 255]), [300, 300]) display.flip()
    # 等候 3 秒 import time time.sleep(3)

    取得繪製文字所需的空間大小

    Font物件的size方法,可用於計算繪製指定文字所需的空間大小,該方法通常用於布局操作,比如,你可以在取得繪製所需的空間大小之後,判斷文字是否能夠完全顯示在按鈕之內。

    size(text)

    text 參數

    text參數是一個字串,size方法將計算繪製該字串所需的空間大小。

    傳回值

    size方法傳回一個形式類似於(width,height)的 Python 元組,其中width表示繪製文字所需空間的寬度,其中height表示繪製文字所需空間的高度。

    Font 物件的 size 方法不會處理字串中的跳脫序列

    Font物件的size方法不會處理字串中的跳脫序列,比如,換行字元\n和定位字元\t,這些跳脫序列可能會被表示為一個或數個空心方塊,因此,size方法所傳回的空間大小可能和你預期的不一樣。

    在下面的範例中,繪製換行字元和定位字元僅需要很少的空間。

    size.py
    # 匯入並初始化 font 模組
    from pygame import font
    font.init()
    
    # 載入預設字型,字型大小 24 f = font.Font(size=24) print(f'繪製 A 所需的空間大小:{f.size('A')}') # 繪製空間不會增加一個行的高度 print(f'繪製 A\\n 所需的空間大小:{f.size('A\n')}') # 繪製空間不會增加一個定位寬度 print(f'繪製 A\\t\\n 所需的空間大小:{f.size('A\t\n')}')
    繪製 A 所需的空間大小:(12, 16)
    繪製 A\n 所需的空間大小:(19, 16)
    繪製 A\t\n 所需的空間大小:(26, 16)

    大部分字型會對特定的字母組合進行字元間距微調

    對於一些字母的組合,比如ae,大部分字型會對組合中的字母之間的距離進行微調(字距微調),以改善文字的可讀性,因此,一次性繪製所有文字所需要的空間寬度,可能與單獨繪製文字中的每個字元所需的空間寬度不同。

    size.py
    # …
    # 載入字型 tahoma
    f = font.Font(font.match_font('tahoma'))
    # 計算一次性繪製所需的空間寬度
    print(f'一次性繪製 Appearance 所需的空間寬度:{f.size("Appearance")[0]}')
    
    # 計算單獨繪製每個字元所需的空間寬度 width = 0 for i in 'Appearance': width += f.size(i)[0]
    print(f'單獨繪製 Appearance 中的每個字元所需的空間寬度:{width}')
    一次性繪製 Appearance 所需的空間寬度:62
    單獨繪製 Appearance 中的每個字元所需的空間寬度:65

    取得字型的行高

    Font物件的get_linesize方法,可以取得字型的行高,該方法通常用於在繪製多行文字時計算下一行文字的位置。

    Font 物件的 get_linesize 與 get_height 方法的傳回值可能不同

    需要註意,Font物件的get_linesize方法的傳回值與get_height方法的傳回值可能不相等,如果不相等,那麽字型行高一般大於字型高度。

    get_linesize()

    傳回值

    get_linesize方法的傳回值是表示字型行高的整數。

    height.py
    # 匯入並初始化 font 模組
    from pygame import font
    font.init()
    
    # 載入預設字型,字型大小 120 f = font.Font(size=120) # 取得字型行高 print(f'字型行高:{f.get_linesize()}')
    字型行高:90

    取得字型的高度

    Font物件的get_height方法,可用於取得字型的高度,該高度為字型中所有字形的平均高度。

    get_height()

    傳回值

    get_height方法的傳回值是表示字型高度的整數。

    height.py
    # …
    # 取得字型高度
    print(f'字型高度:{f.get_height()}')
    字型高度:82

    取得字型的上移量和下移量

    Font物件的get_ascentget_descent方法,可用於取得字型的上移量和下移量,上移量(正整數)表示字型基線與字型頂端之間的距離,下移量(負整數)表示字型基線與字型底端之間的距離,字型上移量和下移量的絕對值之和等於字型的高度(而非行高)。

    get_ascent()

    傳回值

    get_ascent方法的傳回值是表示字型上移量的正整數。

    get_descent()

    傳回值

    get_descent方法的傳回值是表示字型下移量的負整數。

    在下面的範例中,字型的上移量為66,字型的下移量為-16,兩者的絕對值之和為82,等於字型的高度。

    ascent_descent.py
    # 匯入並初始化 font 模組
    from pygame import font
    font.init()
    
    # 載入預設字型,字型大小 120 f = font.Font(size=120) print(f'字型上移量:{f.get_ascent()},字型下移量:{f.get_descent()}') print(f'字型高度:{f.get_height()}')
    字型上移量:66,字型下移量:-16
    字型高度:82

    取得字型的量值

    Font物件的metrics方法,可用於取得字型中某些字元的量值。

    metrics(text)

    text 參數

    text參數是一個字串,metrics方法將計算字串中的每個字元的量值。

    傳回值

    metrics方法的傳回值是一個包含元組的 Python 串列,每一個元組的形式均類似於(minx,maxx,miny,maxy,advance),其中minx表示字元在 X 軸上的最小位移值,maxx表示字元在 X 軸上的最大位移值,miny表示字元在 Y 軸上的最小位移值,maxy表示字元在 Y 軸上的最大位移值,advance表示字元的前進位移值。

    在下面的範例中,我們取得了字元Aep的量值。

    metrics.py
    # 匯入並初始化 font 模組
    from pygame import font
    font.init()
    
    # 載入預設字型,字型大小 120 f = font.Font(size=120) # 取得每個字元的量值 print(f'{f.metrics('Aep')}')
    [(2, 58, 0, 60, 59), (1, 44, -2, 44, 46), (4, 48, -18, 44, 50)]

    為文字整形設定文字編碼

    Font物件的set_script方法,可用於為文字整形設定文字編碼。

    set_script(script_code)

    script_code 參數

    script_code參數是一個表示文字編碼(符合 ISO 15924 標準,由四個字元組成)的字串。

    Font 物件的 set_script 方法需要 SDL_ttf 2.20.0 或更高版本

    要正常使用Font物件的set_script方法,需要 SDL_ttf 的版本為 2.20.0 或更高,否則會導致例外狀況。

    什麽是文字整形?

    文字整形用於對顯示的文字進行調整,以達到一種最佳的視覺效果,Pygame 使用 HarfBuzz 作為文字整形的引擎。

    set_script.py
    # 匯入並初始化 font 模組
    from pygame import font
    font.init()
    
    # 將文字整形設定為阿拉伯文 f = font.Font() f.set_script('Arab')

    取得 SDL_ttf 的版本資訊

    font模組組建在 SDL_ttf 之上,該模組的get_sdl_ttf_version函式,其傳回值是一個元組,元組包含了 SDL_ttf 的版本資訊。

    get_sdl_ttf_version(linked=True)

    linked 參數

    如果linked參數為True,則函式get_sdl_ttf_version傳回目前所使用的 SDL_ttf 的版本資訊,否則傳回 Pygame 套件在編譯階段所針對的 SDL_ttf 版本。

    傳回值

    get_sdl_ttf_version函式的傳回值是一個形式類似於(major,minor,patch)的 Python 元組,其中major表示主要版本號碼,minor表示次要版本號碼,patch表示修補號碼。

    version.py
    from pygame import font
    
    # 取得 SDL_ttf 版本 print(f'目前使用的 SDL_ttf 版本:{font.get_sdl_ttf_version()}') print(f'編譯階段針對的 SDL_ttf 版本:{font.get_sdl_ttf_version(False)}')
    目前使用的 SDL_ttf 版本:(2, 20, 1)
    編譯階段針對的 SDL_ttf 版本:(2, 20, 1)

    原始碼

    src/zh-hant/font·codebeatme/pygame·GitHub

    講解影片

    Pygame 字型載入與樣式控製,font 模組簡介·YouTube