はじめに
pygameで文字を半透明にするとき、初心者が詰まるポイントになりそうだと感じたため、ちょっとした解説を置いておきます。
ダメな例
一番最初に思いつくのは、単に透明度を渡してあげる方法ですが、これだけでは透明になりません
text = font.render('Hello World!', True, (255, 255, 255, 128))
では以下のように変更したらどうか?
text = font.render('Hello World!', True, (255, 255, 255, 128)).convert_alpha()
これもうまく行きません。次の項目でうまく行かない理由を説明します。
なぜダメか
比較のため、図形を透明化したい場合について先に説明します。透明な図形を描画するためには、以下のどちらかの方法で、透明度の設定が可能なSurfaceの上にdrawする必要があります。
# 1パターン目
alpha_surface = pygame.Surface((100, 100)).convert_alpha()
pygame.draw.rect(alpha_surface, (255, 255, 255, 192), (0, 0, 100, 100))
# 2パターン目
alpha_surface = pygame.Surface((100, 100), pygame.SRCALPHA)
pygame.draw.rect(alpha_surface, (255, 255, 255, 192), (0, 0, 100, 100))
ここで1パターン目の方をこう書き替えたらどうなるでしょうか
alpha_surface = pygame.Surface((100, 100))
pygame.draw.rect(alpha_surface, (255, 255, 255, 192), (0, 0, 100, 100))
alpha_surface = alpha_surface.convert_alpha()
実はこの順番で書くと、透明にならなくなります。透明度が設定されていないSurfaceに描画した段階で、透明度の情報が失われるためです。font.renderはSurfaceのインスタンスを返しますが、これは透明度の設定が可能な状態ではないため、これと同様の理由で後からconvert_alphaしても透明にならないというわけです。
解決策
set_alphaというメソッドがあるので、それを使えば解決します。これはSurface全体の透明度を後から設定するためのメソッドなので、Surfaceのインスタンスである文字も当然透明化できます。Surface内で透明度を変えたい場合には使い勝手が悪いですが、今回は文字を透明化したいだけなので、特に問題ないでしょう。他にも画像の半透明化などに使えるので、覚えておくといいかもしれません。
text = font.render('Hello World!', True, (255, 255, 255))
text.set_alpha(128)
サンプル
以上の内容を踏まえてサンプルを書いてみました。単に半透明な文字を表示するだけでなく、簡易的ですが影を表現できたりもしますね。
import pygame, sys
pygame.init() #おまじない
screen = pygame.display.set_mode((512, 512)) #ウィンドウの作成
pygame.display.set_caption('template') #ウィンドウのタイトルを設定
clock = pygame.time.Clock() #ゲームループのfpsを設定するためのやつ
font = pygame.font.SysFont('MS Gothic', 32) #フォントの設定
# 図形の良い例
alpha_surface = pygame.Surface((100, 100)).convert_alpha() #四角形の作成
pygame.draw.rect(alpha_surface, (255, 255, 255, 192), (0, 0, 100, 100)) #四角形を作成
# 図形の悪い例
not_alpha_surface = pygame.Surface((100, 100))
pygame.draw.rect(not_alpha_surface, (255, 255, 255), (0, 0, 100, 100)) #四角形を作成
not_alpha_surface = not_alpha_surface.convert() #四角形を作成
# textは透明にならないが、shadowは透明になる
text = font.render('Hello World!', True, (255, 255, 255, 128)).convert_alpha() #テキストの作成
shadow = font.render('Hello World!', True, (0, 0, 0)) #テキストを作成
shadow.set_alpha(64) #テキストの透明度を設定
def main():
while True:
screen.fill((0, 255, 255)) #画面を黒で塗りつぶすscreen.fill('#000000')でも行けます
screen.blit(alpha_surface, (100, 100)) #四角形を表示する
screen.blit(not_alpha_surface, (200, 100)) #四角形を表示する
screen.blit(shadow, (68, 68)) #テキストを表示する
screen.blit(text, (64, 64)) #テキストを表示する
for event in pygame.event.get():
if event.type == pygame.QUIT: #右上のバッテンが押された時のイベント
pygame.quit() #pygameを終了
sys.exit() #プログラムを終了
pygame.display.update() #画面を更新(ほかにもdisplay.flipとかもあるのでお好きな方をどうぞ)
clock.tick(30) #fpsを30に設定
if __name__ == '__main__':
main()
まとめ
文字を半透明にしたい時は、set_alphaを使おう!
最後に
ここまで読んで下さりありがとうございました。もしこれを使っても透明にならないぞっていう方は、ループの中で何度もblitしていないか確認してみてください。(半透明でも重ねていくと不透明になるので)
