Pythonでお絵描きしてみよう (Pyxelの新命令の紹介)

Pythonでちょっとしたお絵描きやアニメーションを作成したいということはありませんか?

Python向けレトロゲームエンジンPyxelでは、バージョン 1.2からお手軽にお絵描きをするための命令を追加されています。

新しい命令を使うことで、次のような画像を10行程度のPythonコードで作成することができます。

f:id:tkitao:20190903003152g:plain

今回は新しい描画命令の使い方と、それを使ったクリエイティブ・コーディングの例を紹介していきたいと思います。

Pyxel 1.2 について

PyxelPythonで手軽にドット絵タイプのレトロゲームを作成するためのゲームエンジンです。

Pyxelの機能や詳しい使い方の説明は日本語版マニュアルに記載されていますが、とりあえず使ってみたいということであれば、以下の命令を入力すれば完了です。

[Windows]

Pythonをインストールした環境で、

pip install pyxel

[Mac]

Homebrewをインストールした環境で、

brew install python3 sdl2 sdl2_image
pip3 install pyxel

Pyxelは2018年7月30日の公式リリース以降、バージョンアップを重ねており、先月 (2019年8月)にリリースされたバージョン 1.2では、showflipという、Pythonで手軽にお絵描きを作成するための命令と、作成したプログラムをPythonなしでも実行可能にするPyxel Packagerというツールが追加されています。

show命令とflip命令について

show命令とflip命令は、Python+Pyxelでアニメーションやインタラクティブアート作品(クリエイティブ・コーディング)を手軽に作成したり、Twitterに投稿できるようにしたいという目的で追加された命令です。

showは、画面を描画した後、ESCキーが押されるまで待機する命令で、静止画の作成に使用します。

例えば、棒グラフを作成する場合であれば、

import pyxel

data = [40, 70, 50, 20, 100, 50, 40, 20]  # 棒グラフ用のデータ

pyxel.init(128, 128)  # 128x128で画面を作成する

for i, d in enumerate(data):
    # 色を変えながら値に応じた高さの矩形を描画
    pyxel.rect(i * 14 + 10, 120 - d, 10, d, 8 + i) 

pyxel.line(0, 120, 127, 120, 7)  # 棒グラフの下に直線を引く

pyxel.show()  # 画面を表示する

のようなPythonコードを記述することで、次の画面が表示されます。

f:id:tkitao:20190901231534p:plain

flipは、画面を1度描画した後に処理を継続する命令で、アニメーションの作成に使用します。

例えば、画面をボールが動き回るアニメーションであれば、

import pyxel

x = y = 30  # ボールの座標
v = w = 3  # ボールの速度

pyxel.init(160, 120)  # 160x120で画面を作成する

while True:
    pyxel.cls(1)  # 画面を色番号1(青)で消去する

    # ボールの移動処理
    x += v
    y += w

    if x <= 7 or x >= 152:
        x = min(max(x, 7), 152)
        v = -v

    if y <= 7 or y >= 112:
        y = min(max(y, 7), 112)
        w = -w

    pyxel.circ(x, y, 7, pyxel.frame_count % 16)  # ボールを色を変えながら描画する
    pyxel.flip()  # 画面を描画する

のようなPythonコードを記述することで、次のアニメーションが作成できます。

f:id:tkitao:20190901233703g:plain

画像やアニメーションの保存方法

作成した画像やアニメーションは、Pyxelのスクリーンショット保存機能で画像ファイルとして保存できます。

静止画(スクリーンショット)であれば、ALT+1 (MacならOPTION+1)を押すとデスクトップにPNGファイルが保存されます。

動画であれば、ALT+3 (MacならOPTION+3)でデスクトップに最大30秒の直近のアニメーションがGIFファイルとして保存されます。

また、録画の開始タイミングを変更したい場合は、ALT+2で録画開始タイミングを指定することも可能です。

キー操作などを伴うインタラクティブなプログラムを配布したい場合は、

pyxelpackager 対象のPythonファイル名

と入力することで、distフォルダの下に、PythonやPyxelをインストールしなくても、単体で実行可能なファイルが作成されます。

ショートコーディングに挑戦してみる

Pythonコードを短くする工夫をして、Twitterの文字制限(英字は280文字)をクリアすることで、作成したコードをTwitterに直接投稿することができます。

例えば、Pyxelのインポート時に、

import pyxel as p

のように短い別名をつけて、前述の棒グラフのコードを短縮することで、次のようなツイートが可能になります。

私もあまり詳しくないのですが、各種のPythonワンライナーのテクニックなどを応用することで、もっと可能性が広がるのではないかと思います。

Pyxelでクリエイティブ・コーディングしてみる

これまでの内容を踏まえ、Twitterでツイートできる長さでクリエイティブ・コーディングにチャレンジしてみます。

こんな感じのPythonコードを作成してみました。

from math import sin, sqrt
from pyxel import circ, cls, flip, init

a=0
init(128,128)
while 1:
 cls(1)
 for x in range(0,128,4):
  for y in range(0,128,4):
   d=sqrt((x-64)**2+(y-64)**2)
   b=sin(d*0.2+a)*4
   c=(15-d*0.2)%16
   circ(x+b,y+sin(b/4)*4,1,c)
 a+=0.2
 flip()

やって気づきましたが、Pythonのimport文長い…。ちょっとズルをして、import文の記述は省略させてもらうことにします。

Twitterへのツイート結果がこちらです。

皆さんも、Pyxelでクリエイティブ・コーディングやショートコーディングにチャレンジしてみてみませんか?