Pythonでお絵描きしてみよう (Pyxelの新命令の紹介)
Pythonでちょっとしたお絵描きやアニメーションを作成したいということはありませんか?
Python向けレトロゲームエンジンPyxelでは、バージョン 1.2からお手軽にお絵描きをするための命令を追加されています。
新しい命令を使うことで、次のような画像を10行程度のPythonコードで作成することができます。
今回は新しい描画命令の使い方と、それを使ったクリエイティブ・コーディングの例を紹介していきたいと思います。
Pyxel 1.2 について
PyxelはPythonで手軽にドット絵タイプのレトロゲームを作成するためのゲームエンジンです。
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では、show
とflip
という、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コードを記述することで、次の画面が表示されます。
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コードを記述することで、次のアニメーションが作成できます。
画像やアニメーションの保存方法
作成した画像やアニメーションは、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
のように短い別名をつけて、前述の棒グラフのコードを短縮することで、次のようなツイートが可能になります。
Why don't you draw a graph with Pyxel?
— Takashi Kitao (@kitao) July 24, 2019
Pyxelでグラフ描画 #python
import pyxel as p
data = [40,70,50,20,100,50,40,20]
p.init(128,128)
for i,d in enumerate(data):
p.rect(i*14+10,120-d,10,d,8+i)
p.line(0,120,127,120,7)https://t.co/YdpuZTThr0() pic.twitter.com/2ZIc7BBr9S
私もあまり詳しくないのですが、各種の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へのツイート結果がこちらです。
a=0
— Takashi Kitao (@kitao) September 2, 2019
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 #pyxel #shortcoding pic.twitter.com/VsbXJmGaJi
皆さんも、Pyxelでクリエイティブ・コーディングやショートコーディングにチャレンジしてみてみませんか?