Brythonで書く神経衰弱ゲーム – ブラウザ上で動作するPython3実装
ブラウザ上で動作する言語と聞いて真っ先に思い浮かぶのはJavaScriptだと思います。
でも、BrythonというJavaScriptで書かれたライブラリを利用すれば、Pythonでも動かせるんです!
しかも文法はPython3です。そして標準ライブラリのほとんどが使えます。動作は軽快です。コールバックの設定にデコレータを使えて視覚的にも気分的にもスッキリできます。
日本語の資料が少ないのが弱点ですが、積極的に情報発信してもっと増やしていきたいものですね。
ゲーム制作に際し、フリーアイコン素材サイトICOOON MONOさんの画像を使わせていただきました。いつも高品位なアイコン素材ありがとうございます。
神経衰弱ゲームのコード解説
jQueryをBrythonから使っています。
pythonの文法上$
は識別子として使えませんので、jq=window.jQuery
としてjqを$の代わりに使っています。
気持ちいいのは、デコレータでコールバックの登録ができるところですね。
@bind(jq('#item li'), 'mousedown')
def onSelect(ev):
以下、コードの全容です。(2文字インデントで少し読みにくいですが…)
※ マウス押下時の判定に不備がありましたので修正しました(2019/03/18)
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/brython-dev/brython/master/www/src/brython.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/brython-dev/brython/master/www/src/brython_stdlib.js"></script>
<script type="text/python">
from browser import window,bind,timer,alert
from random import shuffle
jq = window.jQuery
n_kind = 8
indexes = list(range(1,n_kind+1))
indexes += indexes
selected, cleared = None,None
ignore_select = True
for i in range(2*n_kind):
jq("#item").append("<li><img src='/wp/wp-content/uploads/2019/03/icon-128px-hatena.jpeg'></li>");
def reset():
shuffle(indexes)
global cleared,selected,ignore_select
cleared,selected = [],[]
ignore_select = False
for i in range(2*n_kind):
close(i)
@bind(jq('#item li'), 'mousedown')
def onSelect(ev):
global selected
if ignore_select: return
idx = jq('#item li').index(ev.currentTarget)
if len(selected) < 2 and idx not in selected and idx not in cleared:
selected.append(idx)
open(idx)
if len(selected) == 2:
check()
def open(idx):
img_num = indexes[idx]
jq(f'#item li:eq({idx}) img').attr('src',f'/wp/wp-content/uploads/2019/03/icon-128px-{img_num}.jpeg')
def close(idx):
jq(f'#item li:eq({idx}) img').attr('src','/wp/wp-content/uploads/2019/03/icon-128px-hatena.jpeg')
def close_selected_items():
global selected,ignore_select
close(selected[0])
close(selected[1])
selected = []
ignore_select = False
def splash():
global ignore_select
ignore_select = True
cnt = 10
def f():
nonlocal cnt
shuffle(indexes)
if cnt > 0:
for i in range(2*n_kind):
(open if cnt%2 else close)(i)
cnt -= 1
timer.set_timeout(f,300)
else:
reset()
return f
def check():
global selected, cleared
if indexes[selected[0]] == indexes[selected[1]]:
cleared.extend(selected)
selected = []
if len(cleared) == 2*n_kind:
timer.set_timeout(splash(),250)
else:
ignore_select = True
timer.set_timeout(close_selected_items, 500)
splash()()
</script>