10行でPythonとPyxelでインベーダーを動かす

10行以内のプログラム
スポンサーリンク

管理人は、インベーダーが大好きです。
ドット絵が好きということもありますが、インベーダーのキャラデザインはいつ見てもワクワクします。
今回は、PythonとレトロゲームエンジンのPyxelを使って10行でインベーダーを画面に登場させてみます。

実行イメージはこんな感じ。

ちなみにPyxelを使うと上記のようなアニメーションGIF画像を保存できます。
Pyxelを使ったプログラム実行中にAlt+2(開始)、Alt+3(終了)でアニメーションGIFとして保存できます。Pyxel良いですね!

スポンサーリンク

Pyxelのインストール

あらかじめパソコンにPythonがインストールされているとします。
コマンドプロンプトあるいはターミナルから

pip install pyxel
又は
pip3 installl pyxel

とタイプすればインストールできます。(但し、Mac等の環境では少し違います)

詳しくは公式ページを参照してください。

Pyxel – GitHub

リソースデータの準備

Pyxelには、リソースエディタが付属しています。

pyxeleditor invader_resource.pyxres

とコマンドプロンプト(Macならターミナル)から入力して、あらかじめドット絵データを作成しておきます。

pyxeleditorコマンドの引数invader_resource.pyxresは保存されるリソースファイル名です。これは後ほど10行プログラム内で使います。

ちなみにインベーダーのドット絵は11×8ドットというかなりイレギュラーな仕様なんです!昔のゲームは自由さがありますね。

今回インベーダーのドット絵をアニメーション用に上下2種類作りました。

10行プログラム

10line_invader.py

# -*- coding: utf-8 -*-
import pyxel
pyxel.init(128, 128, caption="invader", scale=4, fps=5)
pyxel.load("invader_resource.pyxres")
def update():
	"""NONE"""
def draw():
	pyxel.cls(1)
	pyxel.blt(pyxel.frame_count % pyxel.width, 60, 0, 0, 8*(pyxel.frame_count % 2), 11, 8, 0)
pyxel.run(update, draw)

解説

10行しか無いので、1行ずつ解説します。

1行目

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

Pythonプログラムの文字コード設定です。文字コードUTF-8に設定。

2行目

import pyxel

レトロゲームエンジンpyxelを使うためにインポートします。

3行目

pyxel.init(128, 128, caption="invader", scale=4, fps=5)

表示するウインドウサイズやウインドウキャプションを設定する画面です。
サイズ128×128ドットのウインドウです。(ちなみにpyxelでは、最大サイズが縦横255ドットです)

scale=4は、そのまま表示すると小さいので4倍に拡大して表示します。ドット絵っぽく見えるようにするため。

fps=5は、1秒間に5フレームずつ表示するようにしています。標準の30フレームだと今回の10行プログラムでは、動きが速すぎて変な感じでしたので、5フレームにしました。適当に調整して下さい。

4行目

pyxel.load("invader_resource.pyxres")

ドット絵のリソースファイルを先ほどinvader_resource.pyxresというファイル名で保存してあります。
プログラムにリソースファイルを知らせるための設定です。

5行目~6行目

def update():
	"""NONE"""

pyxelでは、最低限update関数draw関数が必要になります。
今回update関数にさせる処理が無かったため、”””NONE”””として何もしていません。

7行目~9行目

def draw():
	pyxel.cls(1)
	pyxel.blt(pyxel.frame_count % pyxel.width, 60, 0, 0, 8*(pyxel.frame_count % 2), 11, 8, 0)

draw関数の処理です。
pyxelの場合、画面の描画は全てdraw関数で行います。
pyxel.cls(1)は、画面を指定色でクリアする命令です。引数は、色番号で0~15までの16色が使えます。
今回は、宇宙っぽい色の1にしました。適当に変更可能です。

次の9行目

pyxel.blt(pyxel.frame_count % pyxel.width, 60, 0, 0, 8*(pyxel.frame_count % 2), 11, 8, 0)

がこの10行プログラムの肝ですかね。(というかここ以外は特に何もしていないと思う)

pyxel.blt関数は、リソースファイルから必要な部分を切り出して画面に表示する関数です。
第1引数と第2引数は、インベーダーのx,y座標です。今回は第1引数のx座標のみ変化させています。y座標は60で固定。
pyxelのフレーム変数(pyxe.frame_count)とpyxelのウインドウの画面幅が自動的に代入される変数(pyxel.width)を使って右に移動させています。

pyxel.frame_count % pyxel.width

pyxel.frame_countは、1秒間に5ずつカウント(3行目のfps=5で指定)されることを利用してpyxel.width(画面幅=128。同じく3行目で指定)で割った余りを使って常に0~127の値になるようにしています。
ですから1秒間に5ドットずつ右に進むようになります。(一番右端まで行ったらまた0に戻るためインベーダーは左端から再登場する)

pyxel.blt関数の6,7番目の引数は、リソース画像から切り出す位置のx座標とy座標です。
作ったドット絵は、縦に2種類作りましたので、切り出し位置のy座標は、上のインベーダー画像が0、下のインベーダー画像が8となっています。

7番目の引数を0と8交互に切り替えるとインベーダーがアニメーションしているように見えると考えました。
で、次の式を引数に指定しています。

8 * (pyxel.frame_count % 2)

pyxel.frame_countで1秒間に5フレーム進む(要するに数値が0, 1, 2, 3, 4…と増えていく)ため、1秒間に0 -> 8 -> 0 -> 8 -> 0…と変化していく形となります。

10行目

pyxel.run(update, draw)

pyxelでは最後にpyxel.runを呼び出してプログラム開始となります。

10行でインベーダーが動き出しました!(かな?)

コメント