Python (パイソン) であそぼう 1
〜 pygame で表示する迷路 〜
学習時間の目安: 約 120 分
2020-11-03 作成 福島
2021-03-15 更新 福島
2022-03-05 更新 福島
このページは Firefox と A4 用紙で印刷可能
TOP > asob > pygame-mazeplay
[ TIPS | TOYS | OTAKU | LINK | MOVIE | CGI | AvTitle | ConfuTerm | HIST | AnSt | Asob | Shell ]

プログラミング言語 Python
Python と書いて「パイソン」と読みます。
直訳すると「ニシキヘビ」(← ヘビ嫌いの人はクリックしないでください) です。
日本人にしてみれば、読みにくい単語です。

ヘビとは何の関係もなく、この言語を作った人が「空飛ぶモンティ・パイソン」という
テレビ番組が好きで、そこから名前を採ったそうです。

汎用的なプログラミング言語です。
最近注目を集め始めましたが、実は 30 年ぐらい前から存在している、伝統的な言語です。
AI (Artificial Intelligence: 人工知能) を記述するのに向いているとのうわさがありますが、
AI に特化しているわけではないし、向いていないわけでもありません。

注意事項
ここに記述してあるのは「読み物」ではありません
実習用の資料なので、読むだけで理解した気になるのではなく、必ず実際にプログラムを打ち込み、動作させてください。
(あまりお金のない人でも 10 年位前の中古 PC に Linux をインストールすれば、限りなく出費を抑えることができます)

0. 事前準備
0-1. この章では、pygame を使います。
インストールがまだなら、ここ (Windows10)ここ (CentOS) を参考にしてインストールしておいてください。

pygame と書いて「パイゲーム」と読みます。
Python を使ってゲームを作るためのパッケージのことです。
0-2. この章では、テキストエディタを使います。
Linux なら付属の「Vim」や「gedit」で十分です。
(Vim の初心者向け使い方はここにあります)

Windows なら「メモ帳」でも構いませんが、本格的なテキストエディタをお勧めします。
(強力なアンドゥや、キーマクロが使えるようになります)
インストールがまだなら、ここ (秀丸エディタ) を参考にしてインストールしておいてください。
また、プログラムを起動するには拡張子が重要となるので、エクスプローラーで拡張子が表示されるようにしておいてください。

1. とてもかんたんなプログラム
1-1. とてもかんたんなプログラムを作成する。
下の<テキスト1>をテキストエディタから打ち込んで、保存してください。

これは pygame 公式サイトにある いちばん小さい入門プログラム を、もっとかんたんにしたものです。
これより小さい pygame のプログラムはありません。

<テキスト1> ファイル名「program.py」
import pygame

pygame.init()

pygame.display.set_mode((320,240))

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
・間違えずに打ち込んでください。
 Python は「インデント」(字下げのことです) が必要なので、行頭の空白文字も重要です。

・最初なので「コピー・アンド・ペースト」で作成すると間違いがありません。
(キーボードに慣れている人は必ず手で打ち込んでください)


・ファイル名は「program.py」じゃなくても構いませんが「pygame.py」にはしないでください。

('    ' がインデント。命令を記述するときに空白文字で行を右にずらしています)
1-2. とてもかんたんなプログラムを実行する。
Windows10 に pygame をインストールした場合は、保存した「program.py」をダブルクリックするとプログラムを実行できます。
CentOS に pygame をインストールした場合は「python3 program.py 」を打ち込んでください。

<実行画面1>
右上の「×」をクリックすると終了します。

黒いだけの画面が表示されました。
ただそれだけですが、pygame はこれが基本です。

これを基本にして、自分のプログラムを追加します。

1-3. とてもかんたんなプログラムの説明。
<テキスト1> ファイル名「program.py」
import pygame   # pygame は Python から取り込まれることによって動作します。「import」は、次に続くプログラム名 (ここでは pygame) を取り込む命令です。

pygame.init()   # pygame は取り込まれるだけでは眠っているだけで何もできません。.init() は pygame に用意された「起こす」プログラムを呼び出しています。

pygame.display.set_mode((320,240)) # 画面を用意します。
                                   # display_set_mode((320,240)) は、横 320 ピクセル×縦 240 ピクセルの画面を用意します。

running = True  # これはあとで説明します。(※)
while running:  # while 命令は、条件 (running) が True の間はずっと有効となる命令です。
                # 何が有効かというと、字下げした次の行からのブロックがすべて実行されるという意味です。
                # 字下げされているのは --- A --- から --- B --- までの行すべてを指します。
    # --- A ---
    for event in pygame.event.get():    # pygame.event.get() は、キャッチしたイベントを一覧にして返す「関数」です。
                                        # ここでは、その一覧を event という変数に繰り返し入れながら、字下げした次の行からのブロックをすべて実行します。
        if event.type == pygame.QUIT:   # 一覧から取り出したイベントが「QUIT」(中断の意味) ならば、変数 running に False を入れます。
            running = False
    # --- B ---

本当は画面を黒く塗りつぶす命令が必要だけど、それが無くても黒くなるので、プログラムを簡単にするために省略しています。

※ 変数「running」について
プログラムは、いつか終わらせる必要があります。そうしないと永遠に走り続け、コンピュータが忙しいままになります。
ここでは、running という変数を用意し、最初はそこに True を入れ、「×」がクリックされたタイミングで同じ変数 running に False を入れて while 命令から抜け出ることにより、プログラムが終わるようにしています。

2. 文字を表示するプログラム
2-1. 文字を表示するプログラムを作成する。
下の<テキスト2>をテキストエディタから打ち込んで、保存してください。
ファイル名は<テキスト1>と同じです。
<テキスト1>との違いを太字で示しています。

<テキスト2> ファイル名「program.py」
import pygame

pygame.init()

screen = pygame.display.set_mode((320,240))

font = pygame.font.Font(None, 32)
moji = font.render('A', False, (255,255,255))
screen.blit(moji, [16,32])
pygame.display.update()

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

2-2. 文字を表示するプログラムを実行する。
「1-2. とてもかんたんなプログラムを実行する」と同じようにプログラムを実行します。

<実行画面2>
右上の「×」をクリックすると終了します。

2-3. 文字を表示するプログラムの説明。
<テキスト2> ファイル名「program.py」
import pygame

pygame.init()

screen = pygame.display.set_mode((320,240))    # 変数を介して画面を操作できるようにする (変数名 screen)

font = pygame.font.Font(None, 32)           # 縦が 32 ピクセルの標準書体を用意する
moji = font.render('A', False, (255,255,255))    # 文字 'A' を白色 (255,255,255) で用意する
screen.blit(moji, [16,32])                   # 用意した文字を画面 (screen) に描く。[16,32] は画面の左上を指定している。
                                                 # (本当の左上は [0,0] ですが、ここではこの数を使ってください。)
pygame.display.update()                      # 画面を更新する
                                                # 画面に何かを描いたら、必ず更新します。そうしないと表示されません。

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False


3. 文字を移動するプログラム
3-1. 文字を移動するプログラムその1を作成する。
文字を移動させます。

コンピュータの画面で文字を移動させるには、
  1. 最初に居た場所をゆかの色で塗りつぶす。
  2. 新しい場所に文字を描く。
と言うことを繰り返すことにって、あたかも文字が移動しているように見せます。

下の<テキスト3>をテキストエディタで打ち込んで、保存してください。
ファイル名は<テキスト1>や<テキスト2>と同じです。
<テキスト2>との違いを太字で示しています。

<テキスト3> ファイル名「program.py」
import pygame

pygame.init()

screen = pygame.display.set_mode((320,240))

font = pygame.font.Font(None, 32)
moji = font.render('A', False, (255,255,255))
yuka = font.render('A', False, (0,0,0))
screen.blit(moji, [16,32])
pygame.display.update()

yoko = 16
tate = 32

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            screen.blit(yuka, [yoko,tate])
            if   event.key == pygame.K_RIGHT: yoko += 16
            elif event.key == pygame.K_LEFT:  yoko -= 16
            elif event.key == pygame.K_DOWN:  tate += 32
            elif event.key == pygame.K_UP:    tate -= 32
            screen.blit(moji, [yoko,tate])
            pygame.display.update()
3-2. 文字を移動するプログラムその1を実行する。
「1-2. とてもかんたんなプログラムを実行する」と同じようにプログラムを実行します。

<実行画面3>
右上の「×」をクリックすると終了します。

キーボードの矢印キー を押して、
文字を自由に動かしてみてください。

画面の外へ移動することもできます。

3-3. 文字を移動するプログラムその1の説明。
<テキスト3> ファイル名「program.py」
import pygame

pygame.init()

screen = pygame.display.set_mode((320,240))

font = pygame.font.Font(None, 32)
moji = font.render('A', False, (255,255,255))
yuka = font.render('A', False, (0,0,0))          # ゆかの色で塗りつぶすための文字を用意する。(0,0,0) は黒色の意味。
screen.blit(moji, [16,32])
pygame.display.update()

# 移動する場所を覚える変数を、横、縦、それぞれ用意する。
yoko = 16    # 横の位置を覚える変数
tate = 32    # 縦の位置を覚える変数

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:       # 何かキーが押されたら、次のブロックを実行する。
            screen.blit(yuka, [yoko,tate])        # 文字の移動に備えて、最初に居た場所をゆかの色で塗りつぶす。
            if   event.key == pygame.K_RIGHT: yoko += 16     # 押されたキーが  だったら横位置を 16 ピクセル増やす。
            elif event.key == pygame.K_LEFT:  yoko -= 16     # 押されたキーが  だったら横位置を 16 ピクセル減らす。
            elif event.key == pygame.K_DOWN:  tate += 32     # 押されたキーが  だったら縦位置を 32 ピクセル増やす。
            elif event.key == pygame.K_UP:    tate -= 32     # 押されたキーが  だったら縦位置を 32 ピクセル減らす。
            screen.blit(moji, [yoko,tate])       # 場所が移動したはずなので、その横、縦を使って文字を書き直す。
            pygame.display.update()      # 画面を更新する。

4. 文字を移動するプログラムその2
4-1. 文字を移動するプログラムその2を作成する。
場所を覚える変数を分かりやすくします。

横に移動するときは +16 や -16 を、縦に移動するときは +32 や -32 を計算していますが、これはそれぞれ、
+16  →  +1 × 16
-16  →  -1 × 16
+32  →  +1 × 32
-32  →  -1 × 32
と、置き換えることができるので、プログラムもそのように変更します。
こうすることにより、無駄に大きな数を使わなくて済むようになり、自分の場所も分かりやすくなります。

下の<テキスト4>をテキストエディタで打ち込んで、保存してください。
ファイル名は<テキスト3>と同じです。
<テキスト3>との違いを太字で示しています。

<テキスト4> ファイル名「program.py」
import pygame

pygame.init()

screen = pygame.display.set_mode((320,240))

font = pygame.font.Font(None, 32)
moji = font.render('A', False, (255,255,255))
yuka = font.render('A', False, (0,0,0))
screen.blit(moji, [16,32])
pygame.display.update()

yoko = 1
tate = 1

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            screen.blit(yuka, [yoko*16,tate*32])
            if   event.key == pygame.K_RIGHT: yoko += 1
            elif event.key == pygame.K_LEFT:  yoko -= 1
            elif event.key == pygame.K_DOWN:  tate += 1
            elif event.key == pygame.K_UP:    tate -= 1
            screen.blit(moji, [yoko*16,tate*32])
            pygame.display.update()
4-2. 文字を移動するプログラムその2を実行する。
ここでは、場所を覚える変数の計算方法を変更しただけなので、実行結果は<実行画面3>と同じになります。

もしも違う画面になったら、文字の打ち間違いがあるかもしれません。
テキストをよく見返してください。

「1-2. とてもかんたんなプログラムを実行する」と同じようにプログラムを実行します。

<実行画面4>
右上の「×」をクリックすると終了します。

キーボードの矢印キー を押して、
文字を自由に動かしてみてください。

動作は 3-2 と同じになります。

4-3. 文字を移動するプログラムその2の説明。
<テキスト4> ファイル名「program.py」
import pygame

pygame.init()

screen = pygame.display.set_mode((320,240))

font = pygame.font.Font(None, 32)
moji = font.render('A', False, (255,255,255))
yuka = font.render('A', False, (0,0,0))
screen.blit(moji, [16,32])
pygame.display.update()

# 文字の最初の位置を設定する。
yoko = 1     # 1 × 16 ピクセルの意味
tate = 1     # 1 × 32 ピクセルの意味

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            screen.blit(yuka, [yoko*16,tate*32])         # 移動する前の場所を表示の場所に変換して、ゆかの色で塗りつぶしています。
            if   event.key == pygame.K_RIGHT: yoko += 1      # 押されたキーが  だったら右に一つ移動する。
            elif event.key == pygame.K_LEFT:  yoko -= 1      # 押されたキーが  だったら左に一つ移動する。
            elif event.key == pygame.K_DOWN:  tate += 1      # 押されたキーが  だったら下に一つ移動する。
            elif event.key == pygame.K_UP:    tate -= 1      # 押されたキーが  だったら上に一つ移動する。
            screen.blit(moji, [yoko*16,tate*32])         # 移動したあとの場所に文字を描いています。
            pygame.display.update()

5. 部屋を表示するプログラム
5-1. 部屋を表示するプログラムを作成する。
このままだと、文字はどこまでも移動できてしまい、画面の外へ出て行ってしまいます。
そうなったら、どこに居るか分からなくなるので、いくらキーを押しても画面の中に戻すのが難しくなってしまいます。

文字が画面の外へ出て行かないように、部屋を作って移動を制限します。

下の<テキスト5>をテキストエディタで打ち込んで、保存してください。
ファイル名は<テキスト4>と同じです。
<テキスト4>との違いを太字で示しています。
' ' は空白文字 (スペースキーで入力) です。TAB 文字とは異なるので注意してください。
<テキスト5> ファイル名「program.py」
import pygame

pygame.init()

screen = pygame.display.set_mode((320,240))

font = pygame.font.Font(None, 32)
moji = font.render('A', False, (255,255,255))
yuka = font.render('A', False, (0,0,0))

heya = [
"+---------------+",
"|               |",
"|               |",
"|               |",
"|               |",
"|               |",
"+---------------+",
]

tate = 0
for line in heya:
    yoko = 0
    for k in line:
        kabe = font.render(k, False, (255,255,255))
        screen.blit(kabe, [yoko*16,tate*32])
        yoko += 1
    tate += 1

screen.blit(moji, [16,32])
pygame.display.update()

yoko = 1
tate = 1

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            screen.blit(yuka, [yoko*16,tate*32])
            if   event.key == pygame.K_RIGHT and heya[tate    ][yoko + 1] == ' ': yoko += 1
            elif event.key == pygame.K_LEFT  and heya[tate    ][yoko - 1] == ' ': yoko -= 1
            elif event.key == pygame.K_DOWN  and heya[tate + 1][yoko    ] == ' ': tate += 1
            elif event.key == pygame.K_UP    and heya[tate - 1][yoko    ] == ' ': tate -= 1
            screen.blit(moji, [yoko*16,tate*32])
            pygame.display.update()
5-2. 部屋を表示するプログラムを実行する。
「1-2. とてもかんたんなプログラムを実行する」と同じようにプログラムを実行します。

<実行画面5>
右上の「×」をクリックすると終了します。

キーボードの矢印キー を押して、
文字を自由に動かしてみてください。

部屋の外へ出ることはできません。

5-3. 部屋を表示するプログラムの説明。
<テキスト5> ファイル名「program.py」
import pygame

pygame.init()

screen = pygame.display.set_mode((320,240))

font = pygame.font.Font(None, 32)
moji = font.render('A', False, (255,255,255))
yuka = font.render('A', False, (0,0,0))

# ゆかを空白文字 (' ') にして、壁をそれ以外の文字にして部屋を形作ります。
heya = [
"+---------------+",
"|               |",
"|               |",
"|               |",
"|               |",
"|               |",
"+---------------+",
]

# 部屋を 1 文字ずつ表示します。
tate = 0
for line in heya:    # 部屋データから 1 行ずつ文字を取り出す。
    yoko = 0
    for k in line:       # 部屋データから 1 つずつデータを取り出す。
        kabe = font.render(k, False, (255,255,255))    # 部屋の 1 部分から文字データを用意する。
        screen.blit(kabe, [yoko*16,tate*32])     # 用意した文字データで画面を描く
        yoko += 1    # 右隣の文字データを取り出せるようにする。
    tate += 1    # 前の 1 行分を描き終わったので、次の 1 行を取り出せるようにする。

screen.blit(moji, [16,32])
pygame.display.update()

yoko = 1
tate = 1

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            screen.blit(yuka, [yoko*16,tate*32])
            if   event.key == pygame.K_RIGHT and heya[tate    ][yoko + 1] == ' ': yoko += 1  # 押されたキーが  で、右側が ' '(ゆか) なら、右に一つ移動する。
            elif event.key == pygame.K_LEFT  and heya[tate    ][yoko - 1] == ' ': yoko -= 1  # 押されたキーが  で、左側が ' '(ゆか) なら、左に一つ移動する。
            elif event.key == pygame.K_DOWN  and heya[tate + 1][yoko    ] == ' ': tate += 1  # 押されたキーが  で、下側が ' '(ゆか) なら、下に一つ移動する。
            elif event.key == pygame.K_UP    and heya[tate - 1][yoko    ] == ' ': tate -= 1  # 押されたキーが  で、上側が ' '(ゆか) なら、上に一つ移動する。
            screen.blit(moji, [yoko*16,tate*32])
            pygame.display.update()

6. 部屋が迷路のプログラム
6-1. 部屋が迷路のプログラムを作成する。
この部屋は、自由に編集できます。
部屋データを編集して迷路にします。使う文字はアルファベットや記号なら何でも構いません。
漢字は画面表示が崩れることがあるので、使わないほうが良いでしょう。

下の<テキスト6>をテキストエディタで打ち込んで、保存してください。
ファイル名は<テキスト5>と同じです。
<テキスト5>との違いを太字で示しています。

<テキスト6> ファイル名「program.py」
import pygame

pygame.init()

screen = pygame.display.set_mode((320,240))

font = pygame.font.Font(None, 32)
moji = font.render('A', False, (255,255,255))
yuka = font.render('A', False, (0,0,0))

heya = [
"+---------------+",
"|     #       # |",
"| ### # # ### # |",
"| # #   #   # # |",
"| # ####### # # |",
"|     #     #   |",
"+---------------+",
]

tate = 0
for line in heya:
    yoko = 0
    for k in line:
        kabe = font.render(k, False, (255,255,255))
        screen.blit(kabe, [yoko*16,tate*32])
        yoko += 1
    tate += 1

screen.blit(moji, [16,32])
pygame.display.update()

yoko = 1
tate = 1

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            screen.blit(yuka, [yoko*16,tate*32])
            if   event.key == pygame.K_RIGHT and heya[tate    ][yoko + 1] == ' ': yoko += 1
            elif event.key == pygame.K_LEFT  and heya[tate    ][yoko - 1] == ' ': yoko -= 1
            elif event.key == pygame.K_DOWN  and heya[tate + 1][yoko    ] == ' ': tate += 1
            elif event.key == pygame.K_UP    and heya[tate - 1][yoko    ] == ' ': tate -= 1
            screen.blit(moji, [yoko*16,tate*32])
            pygame.display.update()
6-2. 部屋が迷路のプログラムを実行する。
「1-2. とてもかんたんなプログラムを実行する」と同じようにプログラムを実行します。

<実行画面6>
右上の「×」をクリックすると終了します。

キーボードの矢印キー を押して、
文字を自由に動かしてみてください。

ゆかの上しか移動できないので、壁を抜けることはできません。

6-3. 部屋が迷路のプログラムの説明。
部屋データを変更しただけなので、特に説明は要らないと思います。

各自、部屋データを変えたり、画面の大きさ (320,240) の数字を変えてみたり、
プログラムを自由に変えて実行して、何が変わるかを確かめてください。
この章は、ここで終了です。


*本稿は初心者から超上級者まで対応しています。


2021-03-15 :
font.render() の色指定で、pygame のバージョンによって色名称 ('white' 等) ではエラーになることがあるので、色指定リスト (255,255,255) に変更しました。

2022-03-05 :
変数 heya の空白文字 ( ) が TAB 文字と混同されることがあるので、彩色して分かりやすくしました。