doc drawn up: 2012-04-16 .. 2012-11-16

プログラミング言語 Python

はじめに

僕はこれまで長年に渡って Perl モンガーだったため、Perl 同様の軽量級スクリプト言語である Python、Ruby にさらに手を出す必要性が薄く、これまで Python を使ったことはありませんでした。ただ、Python には Pygame という比較的良く整えられた SDL を利用するためのライブラリがあるため、ゲーム用のプログラミング言語としては、とても魅力的でした(Perl でも SDL は利用可能ですが、Python + Pygame の場合よりは諸々の面で敷居は高くなると思います)。

以上のようなわけで、元々 Perl には使い慣れていたため、兄弟関係にある Python という言語を学習すること自体にはあまり苦労は感じていません。このメモでは、言語そのものについて述べることよりも、ライブラリなどの言語環境の面について触れることが中心になると思います。

Python は現時点(2012-11-16)で 3.3 が最新で、これまでは 3.x 系列が登場したにもかかわらず、長い間旧い方の 2.x 系列が主流だったようですが、今後 2.7 でメジャーアップデートが打ち切られることが決定されたため、これから 3.x への移行が一気に促進されそうな情勢です。

また、Pygame も 3.x に対応しています。

こういう時期なので、是非とも 3.x を使っていきたいところなのですが、実は、Python プログラムを Windows アプリケーションとして exe 化するためのツールである py2exe が現時点では 2.7 までしか対応していないため、非常に残念ながら今回のところは 2.7 を使うことにしました。やはり、どうせゲームを作ったのであれば、exe の形で一般ユーザーに配布できるというのは大きな魅力で、py2exe の利用は外せない条件となるからです。もちろん exe による配布を考えない場合、現時点でもすぐに 3.x が大推奨です。

Python 3 系列Python 2 系列
Python3.3.52.7.6
Pygame1.9.2a01.9.2a0
py2exe未対応0.6.9 (py2exe-0.6.9.win32-py2.7.exe)
TkInter標準標準
WxPython未対応3.0
Matplotlib1.2.01.2.0

2.x 系列を使う上での注意点

前述したような理由で、現時点では Python 2.7 + Pygame 1.9 + py2exe 0.6.9 で使うしかないのですが、3.x 系列を使う場合と大きく劣っているのは、Unicode 処理の点です。我々日本人にとっては、多用することとなる Unicode 処理の点で大きなハンディを抱えている 2.7 系列を使わなくてはならないのは痛いポイントなのですが、逆に言えば、文字データ処理にほとんど問題は絞られているので、この点さえ押さえていれば、後に 3.x 系列に移行する場合に Unicode 処理周りさえ書き換えればまずクリアできるという風に考えられます。(参考:「2 と 3 の違いの要点」)

Hello, ルパン!?

では早速、Python を使ったサンプルプログラムを作成してみたいと思います。サンプルプログラムの定番は Hello, world! ですが、元々 Perl モンガーである僕が今回 Python に手を染める理由は Pygame を使った Windows アプリケーションを作成することにあるため、ちょっとした Windows アプリケーションのサンプルプログラムを作成することにします。

そこでサンプルプログラムとして思い付いたのが、ルパン三世のタイトルみたいなものを表示するジョークソフトです。Vector にも Windows 3.1 版(Windows 2000 でも動きます)が公開されているもので、知る人ぞ知る、ちょっとしたお遊びアプリケーションです。元祖は X68000 版のようですが、色々な人がクローンを作成したようで、Macintosh 版も見たことがあります。

今回はそれを Python + Pygame で Windows版(厳密に言えば SDL 版なので Linux でも動かせる)を作ってしまおうというわけです。

Lupin the 3rd のソース

作成したプログラムのソースは以下のようになりました:

# -*- coding: utf-8 -*-

# python 2.7.3 / pygame 1.9.2a0 / py2exe 0.6.9 (pygame2exe.py) で作成

import pygame, pygame._view
from pygame.locals import *
import sys # システム処理のために必須

import codecs # Unicode処理のために必要(Python3では不要)
import time # タイマー(ウェイト)処理のために使う
import random # 乱数処理のために使う

# 設定値
Screen_Width  = 640
Screen_Height = 480
Font_Face = 'ipaexm.ttf'

# データファイル読み込み
datafile = codecs.open('lupin3rd.txt', 'r', 'utf-8-sig')
lines = datafile.readlines()
datafile.close()

# データのうち表示する行をランダムに選ぶ
random.seed()
number = random.randint(0, len(lines)-1)
text = lines[number].rstrip()

# 選んだ行のテキストの文字数と画面サイズから、文字のサイズを決定する
length = len(text)
font_size = int(Screen_Width/length)

# Pygameライブラリの初期化
pygame.init()

# フォントの設定
font_small = pygame.font.Font(Font_Face, font_size)
font_large = pygame.font.Font(Font_Face, Screen_Height)

# ウィンドウの設定
screen = pygame.display.set_mode((Screen_Width, Screen_Height), FULLSCREEN)
pygame.display.set_caption('ルパン3世')
screen.fill((0,0,0))
pygame.display.update()
pygame.mouse.set_visible(False)

# 音の再生が遅れることがあるので、少し待つ
time.sleep(3)

# タイピング音を文字数再生しながら、一文字ずつ表示するループ処理
typing_sound = pygame.mixer.Sound('lupin3rd_1.wav')
i = 0
while i < length:
    headline = font_large.render(text[i], True, (255,255,255))
    screen.blit(headline, ((Screen_Width-Screen_Height)/2,0))
    pygame.display.update()
    typing_sound.play()
    time.sleep(0.25)
    screen.fill((0,0,0))
    i += 1

# BGMを再生してテキスト全体を表示する
headline = font_small.render(text, True, (255,255,255))
screen.blit(headline, (0,Screen_Height/2-font_size/2))
pygame.display.update()
pygame.mixer.music.load('lupin3rd_2.wav')
pygame.mixer.music.play()

# 以下、Windowsアプリケーションとしてのイベント待ち無限ループ
while True:
    for event in pygame.event.get():
        # ウィンドウを閉じるか、ESCキーが押された場合 ⇒ 終了
        if (event.type == QUIT) or (event.type == KEYDOWN and event.key == K_ESCAPE):
            pygame.quit()
            sys.exit()
        # ESCキー以外の何らかのキーが押された場合 ⇒ 全画面モード解除
        elif event.type == KEYDOWN:
            screen = pygame.display.set_mode((Screen_Width, Screen_Height), 0)
            screen.blit(headline, (0,Screen_Height/2-font_size/2))
            pygame.display.update()
            pygame.mouse.set_visible(True)

プログラミングに慣れている人であれば、ソースのコメントだけでも、十分に理解できるのではないかと思います。いくつか要点を述べておくと:

コーディング作業

コーディング作業は、IDLE で Python プログラムのソースファイルを編集しつつ(Edit with IDLE)、逐次 IDLE の「Run Module」で実行させてチェックしつつ、再び IDLE の画面に戻って手を加えていくという形で進めていくことになります。エラーなどの諸情報は Python Shell の画面に報告されます。また、変数の値などをチェックするために print 命令で Python Shell に出力して調べたりできます。この IDLE のようなものが標準で備わっているという点が、実は Python の見逃せない美点だと思います。

py2exe で exe 化

完成した Python を exe 化するために py2exe を使います。py2exe 自体にも色々と使い方があるようですが、実は Pygame.org の方で Pygame を使った Python プログラムの exe 化用に py2exe を使った pygame2exe.py というサンプルプログラムを用意してくれているため、ほとんどそのサンプルのまま、ほんの一部を書き換えるだけで exe 化が成功します。pygame2exe.py の最低限の書き換えポイントとしては、self.script = "MyApps.py" の MyApps.py の部分を exe 化するプログラムのファイル名に書き換えるだけです。その他の部分は、exe ファイルのアイコンをカスタムしたりする等のためのものです。

exe 化するには、このようにして用意した pygame2exe.py を単独の python プログラムとして実行します。ただし、IDLE から実行するのではなく、普通のコマンドプロンプトから python pygame2exe.py として実行した方がいいでしょう。dist フォルダが作成されて、その中に exe 化されたプログラムが作成されていると思います(一緒に作成されている w9xpopen.exe は旧い Windows 9x 用のものらしく、WindowsNT/2000/XP 系以降では不要らしい)。

以上で、あっけなく、exe 化された Windows アプリケーションが作成できてしまいました。

サンプルプログラム

[lupin3rd.zip]

TkInter など


<coding>