人工知能に関する断創録

このブログでは人工知能のさまざまな分野について調査したことをまとめています(更新停止: 2019年12月31日)

フルスクリーンモード

ゲームはフルスクリーンでやると臨場感がありますね。Pygameはウィンドウモードとフルスクリーンモードの切り替えがものすごく簡単にできます。F2キーを押すたびにウィンドウモードとフルスクリーンモードが切り替わります。このスクリプトはスプライトグループの使い方(2008/5/17)をベースにしています。

fullscreen.zip

f:id:aidiary:20100605232035p:plain

サンプルスクリプト

サンプルスクリプトを動かす前にSCR_RECTをお使いのPCの解像度に合わせて変更してください。たとえば、1024x768なら

 SCR_RECT = Rect(0, 0, 1024, 768)

としてください。変更しなくても大丈夫ですが、ゲームから復帰したときにデスクトップのアイコン位置が変わってしまうおそれがあります。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygame
from pygame.locals import *
import sys
 
SCR_RECT = Rect(0, 0, 640, 480)
 
class MySprite(pygame.sprite.Sprite):
    def __init__(self, filename, x, y, vx, vy):
        # デフォルトグループをセット
        pygame.sprite.Sprite.__init__(self, self.containers)
        self.image = pygame.image.load(filename).convert_alpha()
        width = self.image.get_width()
        height = self.image.get_height()
        self.rect = Rect(x, y, width, height)
        self.vx = vx
        self.vy = vy
        
    def update(self):
        self.rect.move_ip(self.vx, self.vy)
        # 壁にぶつかったら跳ね返る
        if self.rect.left < 0 or self.rect.right > SCR_RECT.width:
            self.vx = -self.vx
        if self.rect.top < 0 or self.rect.bottom > SCR_RECT.height:
            self.vy = -self.vy
        # 画面からはみ出ないようにする
        self.rect = self.rect.clamp(SCR_RECT)
 
def main():
    pygame.init()
    screen = pygame.display.set_mode(SCR_RECT.size)
    pygame.display.set_caption(u"フルスクリーンモード")
    # スプライトグループを作成してスプライトクラスに割り当て
    group = pygame.sprite.RenderUpdates()
    MySprite.containers = group
    # スプライトを作成
    python1 = MySprite("python.png", 0, 0, 2, 2)
    python2 = MySprite("python.png", 10, 10, 5, 5)
    python3 = MySprite("python.png", 320, 240, -2, 3)
    clock = pygame.time.Clock()
    fullscreen_flag = False
    while True:
        clock.tick(60)  # 60fps
        screen.fill((0,0,255))
        # スプライトグループを更新
        group.update()
        # スプライトグループを描画
        group.draw(screen)
        pygame.display.update()
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == KEYDOWN and event.key == K_F2:
                # F2キーでフルスクリーンモードへの切り替え
                fullscreen_flag = not fullscreen_flag
                if fullscreen_flag:
                    screen = pygame.display.set_mode(SCR_RECT.size, FULLSCREEN, 32)
                else:
                    screen = pygame.display.set_mode(SCR_RECT.size, 0, 32)
 
if __name__ == "__main__":
    main()

フルスクリーンモード

フルスクリーンモードを使うには、メイン画面のSurfaceを作るときにFULLSCREENというオプションをセットするだけです。

   screen = pygame.display.set_mode(SCR_RECT.size)
                                    ↓
   screen = pygame.display.set_mode(SCR_RECT.size, FULLSCREEN)

これだけでフルスクリーンモードで実行できます。pygame.display.set_mode()には他にもオプションを指定できます。たとえば、

   screen = pygame.display.set_mode(SCR_RECT.size,
                                    DOUBLEBUF|HWSURFACE|FULLSCREEN)

とするとHardware Surfaceを使います。Hardware Surfaceというのはビデオカードのメモリ上に作られるSurfaceです(普通はメインメモリ上に作られます)。 Hardware Surfaceはビデオカード上に作られるので画像の描画が高速になります。HWSURFACEを使うときはダブルバッファリング用のフラグである DOUBLEBUFも一緒に指定するのが普通です。ただし、Hardware Surfaceはプラットフォーム依存でWindows以外のOSでサポートされていない可能性もあります。あまり使わない方がよさそうです。

ウィンドウモードとフルスクリーンモードの切り替え

        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == KEYDOWN and event.key == K_F2:
                # F2キーでフルスクリーンモードへの切り替え
                fullscreen_flag = not fullscreen_flag
                if fullscreen_flag:
                    screen = pygame.display.set_mode(SCR_RECT.size, FULLSCREEN, 32)
                else:
                    screen = pygame.display.set_mode(SCR_RECT.size, 0, 32)

この部分では、F2キーを押すとウィンドウモードとフルスクリーンモードを動的に切り替えます。fullscreen_flagがTrueのとき、フルスクリーンモードでscreenを初期化し直しています。

 fullscreen_flag = not fullscreen_flag

という書き方はフラグを切り替えるときの定石です。fullscreen_flagがTrueのときはFalseになり、Falseのときは Trueになります。set_mode()の3番目の引数は色深度で32bitの色を使うという意味です。省略すると自動的に最適な値が指定されるのでなくてもOKです。