Web PyxelからのJavaScript呼び出し

PyxelプログラムからJavaScriptを実行する

 本記事は,高校生向けのプログラミング学習からは離れた内容になります。Pyxelで作成したゲームをPyxel Webの機能を利用して公開している人を読者に想定した記事です。

 Pyxel Web が Pyodide の仕組みを利用している(2023年3月現在)ので,下記サイトを参考に,PyxelのプログラムからJavaScriptを使ってHTMLのDIV要素のテキストを変更する処理を試してみました。(成功したのでローカルストレージにデータを保存する実験もしました)

 参考サイト Type translations — Version 0.22.1
  Calling JavaScript functions from Python

 

PyxelプログラムからWeb画面にメッセージを表示する

HTMLファイル例

 DOMを操作したいので,HTMLファイルを作成して,.pyファイルを指定して実行する形式の例を示します。(pyxel app2html で変換したHTMLファイルでもJavaScriptのalert() 呼び出しができました)

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Calling JavaScript functions from pyxel</title>
    <style>
        #msg{
            position: absolute;
            top: 5px;
            left: 5px;
            border: solid 1px #eeeeee;
            width: 10rem;
            color: #aaa;
            background: black
        }
    </style>
</head>
<body>
    <script src="https://cdn.jsdelivr.net/gh/kitao/pyxel/wasm/pyxel.js"></script>
    <pyxel-run  root="." name="jstest.py"></pyxel-run>
    <div id="msg">This is a html.</div>
</body>
</html>

・ID msg のdivタグが書き換えたい要素です。
 div要素そのままだと画面上で見えなかったので,スタイルを指定しました。

 

Pyxelのプログラム例(マウス座標)

 マウスポインタの座標をdiv要素に表示します。

jstest.py

from js import document
import pyxel

pyxel.init(80,64)
pyxel.mouse(True)
x=y=0
def update():
    global x,y
    x = pyxel.mouse_x
    y = pyxel.mouse_y
    if pyxel.frame_count % 3 == 0:
        document.getElementById("msg").innerText = "(x,y)=("+str(x)+","+str(y)+")"
    return

def draw():
    pyxel.cls(1)
    pyxel.text(1,1, "x="+str(x),7)
    pyxel.text(1,8, "y="+str(y),7)
    return

pyxel.run(update,draw)

 
 Webサーバーに配置して実行

 ブラウザでのデモ
 http://benkyoubox.starfree.jp/100_game/10_pyxel/JStest/callsample.html

 

Pyxelのプログラム例(乱数表示)

 div要素の書き換えが動き続けると,表示内容をクリップボードにコピーできなかったので,1回の出力に変えてみました。

rnditest.py

from js import document
import pyxel

pyxel.init(80,64)

val = 0
def update():
    global val
    if pyxel.btnp(pyxel.KEY_SPACE):
        val = pyxel.rndi(1,100)
        document.getElementById("msg").innerText = "val = "+str(val)
    return

def draw():
    pyxel.cls(1)
    pyxel.text(1,1, "Press space",7)
    pyxel.text(1,8, "val = "+str(val),7)
    return

pyxel.run(update,draw)

 HTMLファイル側の指定.pyファイル名を変更して実行してみます。

 
 ブラウザでのデモ(スペースキーを押すと,乱数を表示します)
 http://benkyoubox.starfree.jp/100_game/10_pyxel/JStest/copytest.html

 ※Ctrl+Cのショートカットキーは,どこかで止めているようで働きませんでした。
 Edgeの右クリックメニューからコピーが選択出来て,Web画面に表示した val = 73 をクリップボードにコピーすることができました。

 

ローカルストレージにデータを保存する

 JavaScriptが実行できたので,ローカルストレージにデータを保存して読み出してみます。(ローカルストレージはWebブラウザにテキストデータを保存できる仕組みです。セキュアではないので重要な情報は扱わないこと)

HTMLファイル例
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Calling JavaScript functions from pyxel</title>

</head>
<body>

    <script src="https://cdn.jsdelivr.net/gh/kitao/pyxel/wasm/pyxel.js"></script>
    <pyxel-run  root="." name="lstest.py"></pyxel-run>

</body>
</html>
Pyxelのプログラム例(データ保存と読み込み)

lstest.py

from js import localStorage
import pyxel

pyxel.init(240,160)

val = "no data"
def update():
    global val
    if pyxel.btnp(pyxel.KEY_S):
        localStorage.setItem("_savetest_pyxel", "I am pyxel. "+str(pyxel.frame_count));

    if pyxel.btnp(pyxel.KEY_L):
        val = localStorage.getItem("_savetest_pyxel")
    return

def draw():
    pyxel.cls(1)
    pyxel.text(1,1, "Press [S]ave or [L]oad",7)
    pyxel.text(1,8, "val = "+str(val),7)
    return

pyxel.run(update,draw)

・Sキーを押すと,ローカルストレージにキー"_savetest_pyxel"でデータを保存します。
・Lキーを押すと,ローカルストレージから読み込んだデータを表示します。

 
 ブラウザでのデモ
 http://benkyoubox.starfree.jp/100_game/10_pyxel/JStest/lstest.html
 SaveしてLoadして表示を確認→ブラウザを終了してもう一度アクセス→Loadして表示できれば成功
 ※プライベートブラウズの場合は動作できません
 
 実際にアプリに組み込むにはエラーを考慮する(※)必要があると思いますが,ゲームデータの保存に利用できるかもしれませんので,参考にしてください。
 (※JavaScript側にtry catchを入れた関数を定義して呼び出すなど)
 
 
次の記事(自作の関数呼び出し例)
kinutani.hateblo.jp
 

関連記事

kinutani.hateblo.jp