はじめに
pyxelの設計想定外のことをしているかもしれません。あくまでネタとしてお楽しみください。
実行画面(出オチ)
何をしているのか
2つのプロセスそれぞれでpyxel.run()しています。
無茶なことしたかな…と思いきや意外とすんなりいったのでびっくり。
ソースコード解説
concurrent.futures
モジュールのProcessPoolExecutor
を使用します。
from concurrent.futures import ProcessPoolExecutor
プロセスを2つぶん用意して、app_func_worker(0)
とapp_func_worker(1)
をそれぞれ別プロセスで実行します。
executor = ProcessPoolExecutor(max_workers=2)
appFutures = [ executor.submit(app_func_worker,i) for i in range(2) ]
上記で指定した関数app_func_worker()のなかで、pyxelでは定番のApp()を呼んでいます。
def app_func_worker(app_id):
return App(app_id)
ソースコード
全ソースコードはこちら。やってることの割にこのソースコードの短さ…恐るべしpython&pyxel。
python歴まだ若いので至らないところあったらご容赦ください。
※pyxel公式のサンプルソースコード01_hello_pyxel.py
をベースにしています。
※ウインドウが2つ重なって出てくるので手動で横に並べてね(笑)
from concurrent.futures import ProcessPoolExecutor
import pyxel
WW,WH,X,Y,DX,DY = 160,120,50,50,4,4
def app_func_worker(app_id):
return App(app_id)
class App:
def __init__(self,app_id):
global X,Y,DX,DY,WW,WH
self.app_id = app_id
self.wx = 160 * app_id
self.wy = 0
pyxel.init(WW, WH, title="Hello Pyxel",display_scale=2)
pyxel.images[0].load(0, 0, "assets/pyxel_logo_38x16.png")
pyxel.run(self.update, self.draw)
def update(self):
global X,Y,DX,DY,WW,WH
if X + DX < 0 or X + DX + 38 > 320:
DX *= -1
if Y + DY < 0 or Y + DY + 16 > 120:
DY *= -1
X += DX
Y += DY
def draw(self):
global X,Y,DX,DY,WW,WH
pyxel.cls(0)
if self.wx - 38 < X < self.wx + WW:
pyxel.blt(X - self.wx, Y, 0, 0, 0, 38, 16)
pyxel.text(55, 41, f"Hello, Pyxel {self.app_id} !", pyxel.frame_count % 16)
def cleanup():
print ('** cleanup **')
executor.shutdown(wait=True)
if __name__ == "__main__":
try:
executor = ProcessPoolExecutor(max_workers=2)
appFutures = [ executor.submit(app_func_worker,i) for i in range(2) ]
except Exception as e:
print('エラーが発生しました')
print(e)
cleanup()
おわりに
キーセンスはどちらの画面で拾っているかとか、pyxel.quit()すると何故か両プロセスとも落ちてくれる(これはこれでありがたい)とか、気になるところはいろいろありますが、ひとまずネタとして割り切って公開しました。
マルチディスプレイ環境で横3画面使ってダライアス(昔のシューティングゲーム)とか、タッチディスプレイ縦横9画面使ってストラックアウト(スポンジボールにしておこう)とか、夢が広がりますね!