pygame で画面モードを設定すると、実際の目に見える surface (サーフェイス) が ディスプレイ上に作成されます。この surface は画面全体を覆うこともできますし、 あるいは各プラットフォームのウインドウマネージャに対応したウインドウの形に することもできます。 display surface は、pygame における普通の surface オブジェクト以上の 何物でもありません。pygame.display モジュールには、この画像 surface の 内容をディスプレイ上で更新するための特別な関数があります。
pygame での画面モード設定は、他のほとんどのグラフィックスライブラリよりも ラクです。それは、たとえ指定した画面モードが使えないときでも、 pygame がその画面モードをエミュレーションしてくれるからです。 pygame は指定された画面モードに最適なディスプレイの解像度と 色深度を選び、指定された方式でその display にアクセスできるようにします。 実際には pygame.display は SDL ライブラリのバインディングのひとつなので、 本当の仕事は SDL がやってるんですけどね。
このやり方で画面モードを設定するのは一長一短があります。 長所は、もしあるゲームに特定の画面モードが必要な場合でも、 pygame はそれをサポートしていないプラットフォーム上でそのゲームを 走らせることができるということ。だから何かを新しく始めるのが簡単で、 あとから戻ってきて、より特化されたモードを選ぶということができます。 短所は、得られるものが必ずしも厳密に指定したそのものではないかもしれない ということ。また、画面モードをエミュレーションすると若干パフォーマンスが低下します。 このチュートリアルでは各プラットフォームの画面性能を調べたり、 自分のゲームに適した画面モードを設定するいくつかの方法を説明します。
最初に知るべきことは、どうやって実際に現在の画面モードを変更するかです。 画面モードは、pygame.display が初期化されたあとならいつでも変更して かまいません。もしすでに画面モードを設定している場合、それを設定しなおすと 自動的に現在の画面モードが切りかわります。画面モードの設定は、 関数 pygame.display.set_mode((width, height), flags, depth) によって おこなえます。この関数に最低限要求される引数は、新しい画面モードに必要な ディスプレイの幅 (width) と高さ (height) からなるシーケンスだけです。 色深度 (depth) には surface に必要なピクセルのビット数を与えます。 depth に 8 が与えられた場合、pygame はカラーマップつきの surface を作成します。 これより大きな数が与えられた場合、pygame はあらかじめ与えられた色を使うモード (packed color mode) を使います。depth と色のモードについては、display と surface の モジュールにより詳しい情報があります。depth のデフォルト値は 0 です。 引数として 0 が与えられると、pygame は最適なビット数を選んで使います。 ふつうこれはシステムの現在の色深度と同じになります。フラグ (flags) 引数は 画面モードに関する拡張機能をあつかうあめのもので、たとえば HWSURFACE フラグを 使うと display surface をハードウエアメモリ上に作成することができます。 繰り返しますが、より詳しい情報は pygame のリファレンスにあります。
では、いま使っているプラットフォームとグラフィックス資源 (訳注: 画像データ) に 最適な画面モードを選ぶにはどうしたらいいでしょうか? 画面装置に関する 情報を収集する、いくつかのメソッドが用意されています。 これらのメソッドはすべて display モジュールが初期化されたあとで 呼ばなければなりませんが、おそらくこれらは画面モードを設定する前に 使いたいと思うでしょう。まず、pygame.display.get_info() が VidInfo 型と呼ばれる特別なオブジェクトを返します。これには現在使っている グラフィックスドライバについての詳細な情報が入っています。 関数 pygame.display.list_modes(depth, flags) を使うと、 そのシステムがサポートしている画面モードを知ることができます。 pygame.display.mode_ok((width, height), flags, depth) は set_mode() と同じ引数をとりますが、与えられた要求に もっとも近い色深度を返します。さいごに、pygame.display.get_driver() は pygame によって選ばれたグラフィックスドライバの名前を返します。
とりあえず鉄則を覚えてください。pygame は要求されたあらゆる 画面モードに対してもちゃんと動作します。いくつかの画面モードは エミュレーションによって実現する必要があり、これはゲームのスピードを 低下させることにつながります。なぜなら pygame は画面を更新するたびに 「実際の」画面モードに合わせて画像を変換しなければならないからです。 ベストなやり方は、つねに pygame に最適な色深度を選ばせておき、 すべてのグラフィックス資源を読み込むときにその形式に変換してやることです。 pygame に色深度を選ばせるには set_mode() を depth 引数なしで (あるいは depth を 0 にして) 呼ぶか、あるいは mode_ok() を使って 必要な色深度にもっとも近いビット数をみつけることです。
画面モードがウインドウになっている場合、ふつうデスクトップの 色深度と同じになります。フルスクリーンになっている場合、プラットフォームに よっては要求にあった任意の色深度に切り換えることもできます。画面モードを 設定する前に VidInfo オブジェクトを取得すれば、あらかじめ現在のデスクトップの 色深度を知ることができます。
画面モードを設定したあとは、VidInfo オブジェクトを取得することで その設定に関する情報を知ることができます。あるいはその display surface に 対する Surface.get* メソッドを呼んでもかまいません。
以下は最適な画面モードを選ぶのに使えるルーチンです。 ここで使っている関数に関するより詳しい情報については、 display モジュールのドキュメントを見てください。
pygame.display.mode_ok(size, flags, depth)
この関数は pygame.display.set_mode() とまったく同じ引数をとります。 これは与えられた画面モードのときに使える色深度を返します。 もしこれが 0 を返した場合、その画面モードを実現するにはエミュレーションが 必要ということになります。pygame.display.list_modes(depth, flags)
与えられた色深度 (depth) とフラグ (flags) をもつ画面モードの リストを返します。合致する画面モードがないときは、空のリストを返します。 flags 引数のデフォルトは FULLSCREEN になっています。FULLSCREEN を 指定せずに別のフラグを指定した場合、おそらく返り値として -1 を得るでしょう。 この場合 display はウインドウになり、あらゆる画面サイズが可能になります。 ここで返される画面モードのリストは大きい順に並んでいることに注意してください。pygame.display.get_info()
現在の画面装置に関するさまざまな情報を含んだ VidInfo オブジェクトを返します。 このオブジェクトを print してみると、どんなメンバや値があるのか すぐわかるでしょう。>>> import pygame.displayこれらのフラグは、すべて VidInfo オブジェクトのメンバとして検査することができます。 いくつかある blit フラグは、どんな surface を blit する (訳注: 貼り付ける) ときに ハードウエアアクセラレーションがサポートされるかを示しています。
>>> pygame.display.init()
>>> info = pygame.display.get_info()
>>> print info
<VideoInfo(hw = 1, wm = 1,video_mem = 27354
blit_hw = 1, blit_hw_CC = 1, blit_hw_A = 0,
blit_sw = 1, blit_sw_CC = 1, blit_sw_A = 0,
bitsize = 32, bytesize = 4,
masks = (16711680, 65280, 255, 0),
shifts = (16, 8, 0, 0),
losses = (0, 0, 0, 8)>
以下に画面を初期化する方法をいくつか示します。 画面モードをどうやって初期化するかについて、なにがしかのアイデアが得られるでしょう。
>>> # 640x480 のウインドウで、最適な色深度を得る
>>> pygame.display.set_mode((640, 480))
>>> # 16ビットにできる画面モードのうち、最大のものを得る
>>> modes = pygame.display.list_modes(16)
>>> if not modes:
... print '16ビットはサポートされていません'
... else:
... print '見つかった画面サイズ:', modes[0]
... pygame.display.set.mode(modes[0], FULLSCREEN, 16)
>>> # 8ビットの surface が必要、それでなければダメ
>>> if pygame.display.mode_ok((800, 600), 0, 8) != 8:
... print '8ビットの画面でしか動きません、ごめんなさい'
... else:
... pygame.display.set_mode((800, 600), 0, 8)
訳: Yusuke Shinyama