mieki256's diary



2021/02/13() [n年前の日記]

#2 [python][pygame] PygameをWindows10上でインストール

Pygame というのは…Pythonを使って2Dゲームを作れるライブラリ、という説明でいいのだろうか。

_pygame.org/news
_pygame - Wikipedia

メインPCにインストールしてみたり。環境は以下。

経緯。 :

ツッコミが入ったことをキッカケにして _昔の日記ページ に目を通したのだけど。自分自身も過去の自分にツッコミを入れたくなってしまった…。

「Pygameで描画するスクリプトって、どのプログラムのことだよ!?」
「Python のバージョンは? Pygame のバージョンは? なんでそこらへんをメモしてないのよ!?」

みたいな。コレじゃダメだよ…>過去の自分。動作ログにすらなってないやん。

まあ、Raspberry Pi Zero W が想像していた以上に非力でガッカリしました、という当時の気分だけは分かるのだけど…。おそらく、ガッカリし過ぎて、それ以外のことがどうでもよくなって、環境その他をメモするのをスポンと忘れたのだろう…。

さておき。当時動かしたスクリプトって一体どれだっけ? 今も残ってるのかな? とHDDの中を漁ってたら、そもそも今のメインPC(Windows10機)に Pygame をインストールしてなかったことに気付いた。去年の8月頃にSSDが突然死して、Windows10を再インストールしてから、そのあたりの環境復旧をしてなかったので、この際 Pygame をインストールしておこう、と。

Pygame をインストール。 :

pip でインストール。
pip install pygame
> pip list | grep pygame
pygame            2.0.1
Pygame 2.0.1 がインストールされた。

…えっ。2.0.1?

Pygame が 2.x.x になってた。 :

インストールしてみて驚いた。Pygame って 2.0.0 になってたの? ずっと 1.9.x だったはずだけど、とうとう 2.0.0 に?

_Releases - pygame/pygame
_Release pygame 2.0 - the happy dance birthday release - pygame/pygame

2020/10/29 に、2.0.0 が公開されていたらしい。一時期は開発が停滞してアレだったのに…。素晴らしい。よくぞここまで。

ということは、SDL も SDL1 から SDL2 になって描画が高速化されてたりするのだろうか?

libsdl version 2 support. Technically pygame 2.0 still works with SDL 1, but we recommend SDL2 which is vastly improved over SDL1 for most use cases. Probably we will remove SDL 1 support starting pygame 2.1.
「libsdlバージョン2をサポートしてるけど、Pygame 2.0 は SDL1」ってどういうことやねん…。結局、SDL1 のままなのか、そうじゃないのか。

とりあえず、pygame.get_sdl_version() を呼べば、(x, x, x) の形で、Pygame が使ってるSDLのバージョンが得られるらしい。
    sdlver = "SDL ver: %d.%d.%d" % (pygame.get_sdl_version())
「2.0.14」と表示された。すると、Pygame 2.0.1 Windows版では、SDL2が使われていると考えていいのかな。

そもそもDOS窓上から Pygameを使ったスクリプトを実行したら、SDLのバージョンも表示されていた。
> python pygame_fullscreen.py
pygame 2.0.1 (SDL 2.0.14, Python 3.8.7)
Hello from the pygame community. https://www.pygame.org/contribute.html
やはり SDL 2.0.14 を使っているっぽい。

ちなみに、Pygame 1.x.x + SDL1 は、どんな環境でも安定動作させるためにデフォルトではソフトウェア描画をしていて、そのせいで描画速度が遅かったりしたのだけど。SDL2 はハードウェア描画を積極的に使うようになっているから高速に描画できる場面がほとんど、という話だったはず。「Pygameは描画が遅い」というのは過去の話ですよ、と思ってもいいのかも…しれない? たぶん。分からんけど。

Pygameを使ったスクリプトを動かしてみた。 :

HDDの中から、Pygame を使って描画するスクリプトを発掘してきた。Pygame 2.0.1 用に少し修正して実行。ていうか、昔の日記ページにも一応置いてあった模様…。

_Raspberry Pi3上でpygameのスクリプトを動かしてみた
_DXRubyその他の動作速度を確認した結果をメモ

スクリプトの処理内容は…。
  • ウインドウサイズは 640 x 480。
  • 64 x 64ドットのスプライトを、160枚描画。
  • BGを、2枚描画。
  • oggを再生。
  • 1キーを押すと、ウインドウ表示とフルスクリーン表示が切り替わる。
  • 2,3,4キーでスプライトやBGの描画On/Offを切り替えられる。

これだけ表示して60FPSが出るようなら、昔風のリアルタイム2Dアクションゲームなら十分作れるはずだよなと…。



_pygame_fullscreen.py
import pygame
from pygame.locals import *
import math
import os
import sys

SCR_RECT = Rect(0, 0, 640, 480)
mode_v = 0


class MySprite(pygame.sprite.Sprite):
    u"""スプライトクラス."""

    def __init__(self, img, x, y, vx, vy):
        u"""初期化処理."""
        pygame.sprite.Sprite.__init__(self)

        # self.image = pygame.image.load(filename).convert_alpha()
        self.image = img
        self.w = self.image.get_width()
        self.h = self.image.get_height()
        self.whf = self.w / 2
        self.hhf = self.h / 2
        self.fpx = float(x)
        self.fpy = float(y)
        self.fpvx = float(vx)
        self.fpvy = float(vy)
        self.rect = Rect(int(self.fpx - self.whf),
                         int(self.fpy - self.hhf),
                         self.w, self.h)

    def update(self):
        u"""毎フレーム呼ばれる処理."""
        self.fpx += self.fpvx
        self.fpy += self.fpvy
        self.rect = Rect(int(self.fpx - self.whf),
                         int(self.fpy - self.hhf),
                         self.w, self.h)
        if self.rect.left <= 0 or self.rect.right >= SCR_RECT.width:
            self.fpvx *= -1
        if self.rect.top <= 0 or self.rect.bottom >= SCR_RECT.height:
            self.fpvy *= -1
        # self.rect = self.rect.clamp(SCR_RECT)


def draw_bg(bx, by, bg, screen):
    u"""BG描画処理."""
    bx = int(bx)
    by = int(by)
    for ofs in [[0, 0], [512, 0], [0, -512], [512, -512]]:
        screen.blit(bg, (bx + ofs[0], by + ofs[1]))


def main():
    u"""メイン処理."""
    global mode_v

    fullscreen_flag = False
    running = True
    cap = ""

    # pygame初期化
    pygame.init()

    if True:
        mode_v = pygame.DOUBLEBUF
        screen = pygame.display.set_mode(SCR_RECT.size, mode_v)
    else:
        mode_v = pygame.OPENGL | pygame.DOUBLEBUF
        screen = pygame.display.set_mode(SCR_RECT.size, mode_v, vsync=1)

    pygame.display.set_caption("Pygame Full Screen Demo")

    # フォント指定
    font = pygame.font.Font("res/Vegur-Bold.otf", 18)

    # BG画像読み込み
    bg1 = pygame.image.load("res/bg1.png").convert()
    bg2 = pygame.image.load("res/bg2.png").convert_alpha()

    # スプライトグループを作成してスプライトクラスに割り当て
    sprgrp = pygame.sprite.OrderedUpdates()

    # スプライトを作成
    pmax = 160
    sprimg = pygame.image.load("res/ufo.png").convert_alpha()
    # ckey = sprimg.get_at((0,0))
    # sprimg.set_colorkey(ckey)
    x = SCR_RECT.width / 2
    y = SCR_RECT.height / 2
    for i in range(pmax):
        rad = math.radians(i * 360 / pmax)
        vx = 3.0 * math.cos(rad)
        vy = 3.0 * math.sin(rad)
        sprgrp.add(MySprite(sprimg, x, y, vx, vy))

    # BGM start
    pygame.mixer.music.load("res/bgm32.ogg")
    pygame.mixer.music.play(-1)

    drvname = "DRIVER: %s" % (pygame.display.get_driver())
    sdlver = "SDL ver: %d.%d.%d" % (pygame.get_sdl_version())

    bgx = [0, 0]
    bgy = [0, 0]

    sprdraw = True
    bg0draw = True
    bg1draw = True
    frame_count = 0
    clock = pygame.time.Clock()

    # main loop
    while running:

        # キー入力に対する処理
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE or event.key == K_q:
                    # ESCキーで終了
                    running = False

                elif event.key == K_1:
                    # フルスクリーンモードへの切り替え
                    fullscreen_flag = not fullscreen_flag
                    pygame.display.toggle_fullscreen()

                    drvname = "DRIVER: %s" % (pygame.display.get_driver())

                elif event.key == K_2:
                    # スプライト描画のon/off切り替え
                    sprdraw = not sprdraw

                elif event.key == K_3:
                    # BG0描画のon/off切り替え
                    bg0draw = not bg0draw

                elif event.key == K_4:
                    # BG1描画のon/off切り替え
                    bg1draw = not bg1draw

        # BG
        bgx[0] = -64 + (64 * math.cos(math.radians(frame_count)))
        bgx[1] = -128 + (128 * math.cos(math.radians(frame_count)))
        bgy[0] = (bgy[0] + 2) % 512
        bgy[1] = (bgy[1] + 6) % 512
        if bg0draw:
            draw_bg(bgx[0], bgy[0], bg1, screen)
        if bg1draw:
            draw_bg(bgx[1], bgy[1], bg2, screen)

        # スプライト座標更新
        sprgrp.update()

        # スプライト描画
        if sprdraw:
            sprgrp.draw(screen)

        # テキスト描画
        strdt = [
            cap,
            drvname,
            sdlver,
            "1: FULL/WDW",
            "2: SPR ON/OFF",
            "3: BG0 ON/OFF",
            "4: BG1 ON/OFF",
            "ESC,Q: EXIT"
        ]
        fontcolor = (255, 255, 255)
        fy = 8
        for s in strdt:
            screen.blit(font.render(s, True, fontcolor), (16, fy))
            fy += 18

        # ウインドウタイトルの文字列を設定
        if not fullscreen_flag:
            pygame.display.set_caption(cap)

        # 60fpsになるよう時間待ち
        clock.tick(60)
        # clock.tick_busy_loop(60)

        # pygame.display.update()
        pygame.display.flip()

        cap = '%5.2f FPS' % clock.get_fps()
        frame_count = frame_count + 1

    pygame.quit()
    sys.exit()


if __name__ == "__main__":
    main()

使用画像、ogg、フォントファイルは以下。解凍して、res/ フォルダの中にコピー。画像とoggはCC0ライセンスってことで。

_res.zip

フォントは、CC0ライセンスの Vegur フォントを使わせてもらいました。ありがたや。

_Vegur | ドットコロン

とりあえず、これでメインPC(Windows10機)上に Pygame をインストールして使える状態になったことを確認できた。

補足。pygame.display.toggle_fullscreen() について。 :

以前書いたスクリプトでは、ウインドウ表示とフルスクリーン表示の切り替えに、pygame.display.set_mode() を使っていたのだけど。

_display - Pygameドキュメント 日本語訳

Pygame 2.0.0 以降は pygame.display.toggle_fullscreen() を呼ぶだけで、ウインドウ表示とフルスクリーン表示の切り替えができるようになっているらしいので、今回はソレを利用することにした。

_pygame.display - pygame v2.0.1.dev1 documentation

pygame.display.toggle_fullscreen() は Pygame 1.x.x の頃から存在していたのだけど、X11(Linuxのデスクトップ画面)でしか使えなかったそうで…。Pygame 2.0.0 からは Windows や Mac 上でも正常動作するようになったので、コレを使わない理由は無いよね、ということになっているらしい。

_Update display.toggle_fullscreen() docs for pygame 2 - Issue #1990 - pygame/pygame - GitHub

以上です。

過去ログ表示

Prev - 2021/02 - Next
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project