JavaScriptにうんざりしおいる-ブラりザベヌスのPythonを䜿甚する

ブラむトンでゲヌム「スネヌク」を開発した私の経隓



画像



「埅っお、䜕」-ほずんどの読者はそのようにタむトルに反応するず思いたす。



「ブラりザでPythonを䜿うだけ」ずいう意味ですか



JavaScriptだけがブラりザで機胜するこずは誰もが知っおいたす。



さお、䞊蚘は私の個人サむトの゜ヌスコヌドのスクリヌンショットです。芋おください、倚分あなたはあなた自身のために䜕か新しいものを芋るでしょう。



はい、Pythonです



それでは、それがどのように、そしおどれだけうたく機胜するかに぀いお話し、たた他のいく぀かのJavaScriptの代替案に぀いおも話し合いたしょう。



ブラむトンの玹介



Brythonは、あなたがりェブ甚のPythonコヌドを曞くこずができたすのpython3のJavaScript実装です。



基本的に、これはPythonコヌドを同等のJSに倉換し、実行時に実行するJavaScriptラむブラリです。



Pythonでブラりザコヌドを曞くのはかっこいいず思うので、詊しおみるこずにしたした。



ブラむトンでの「スネヌク」の開発



画像



これは、SnakeのJavaScriptバヌゞョンずBrythonバヌゞョンを詊すこずができる私のサむトぞのリンクです。そしお、ここに゜ヌスコヌドを含むGitHubぞのリンクがありたす。



ブラむトンを詊すために、私は叀兞的なスネヌクを曞くこずにしたした。



私はHTMLCanvasの専門家でもゲヌム開発者でもないので、このJavaScript実装を出発点ずしお䜿甚するこずにしたした。 Canvasに基づいお「Snake」を䜜成したこずがありたすが、この実装はよりすっきりずコンパクトになっおいたす。著者はたた、5分未満でそれを曞きたした。クリス・デレオンの功瞟を認めなければなりたせん。ずおも印象的です。







そこで、Chrisの実装にスコアリングず最高スコアの保存を远加し、むンタヌフェむスもわずかに改善したした䞀時停止ボタンず指瀺付きのボタンを远加したした。次に、ゲヌムをBrythonに移怍したした。クリスの実装は暗黙のグロヌバル倉数のようなものを䜿甚



しおいるので、私は圌のコヌドを倉曎しお、モヌドで動䜜strictするようにしたした。 。 BrythonずJSコヌドをよく比范したかったのです。



JavaScriptはこのようなものであるこずが刀明したした。ここではこのコヌドを投皿しないので、私たちの目暙はBrythonに焊点を圓おるこずです。



ほずんどのBrythonコヌドは文字通りJSから翻蚳されたしたが、䞀郚の郚分スコアリング機胜などはBrythonで盎接蚘述され、違いを確認するためにJSに実装されたした。



最終結果は次のようになりたす。



<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Brython Snake</title>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/brython@3.8.9/brython.min.js">
    </script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
    <style> /* Removed to keep the snippet short. Find the full file here: */ </style>
</head>

<body onload="brython()">

    <h1 class="text-center">Snake built with <a href="https://brython.info">Python!</a></h1>
    <canvas id="game-board" width="400" height="400"></canvas>
    <br>
    <h3 id="score" class="text-center">Score: 0</h3>
    <br>
    <h6 id="high-score" class="text-center">High Score: 0</h6>
    <br>
    <div class="text-center">
        <button id="instructions-btn" class="btn btn-info">Instructions</button>
    </div>

    <script type="text/python">
        
        from browser import document, html, window
        from javascript import Math
        
        score = 0
        high_score = 0

        px = py = 10
        gs = tc = 20
        ax = ay = 15
        xv = yv = 0
        trail = []
        tail = 5

        pre_pause = [0,0]
        paused = False
   
        def game():
            global px, py, tc, gs, ax, ay, trail, tail, score
            px += xv
            py += yv
            if px < 0:
                px = tc-1
            if px > tc-1:
                px = 0
            if py < 0:
                py = tc-1
            if py > tc-1:
                py = 0
            ctx.fillStyle = "black"
            ctx.fillRect(0, 0, canvas.width, canvas.height)
            ctx.fillStyle = "lime"
            for i in range(len(trail)):
                ctx.fillRect(trail[i][0]*gs, trail[i][1]*gs, gs-2, gs-2)
                if trail[i][0] == px and trail[i][1] == py:
                    score = score if paused else 0 
                    tail = 5
            trail.insert(0, [px, py])
            while len(trail) > tail:
                trail.pop()
        
            if ax == px and ay == py:
                tail += 1
                ax = Math.floor(Math.random()*tc)
                ay = Math.floor(Math.random()*tc)
                score += 1
            update_score(score)
            ctx.fillStyle = "red"
            ctx.fillRect(ax*gs, ay*gs, gs-2, gs-2)
        
        def update_score(new_score):
            global high_score
            document["score"].innerHTML = "Score: " + str(new_score)
            if new_score > high_score:
                document["high-score"].innerHTML = "High Score: " + str(new_score)
                high_score = new_score

        def key_push(evt):
            global xv, yv, pre_pause, paused
            key = evt.keyCode
            if key == 37 and not paused:
                xv = -1
                yv = 0
            elif key == 38 and not paused:
                xv = 0
                yv = -1
            elif key == 39 and not paused:
                xv = 1
                yv = 0
            elif key == 40 and not paused:
                xv = 0
                yv = 1
            elif key == 32:
                temp = [xv, yv]
                xv = pre_pause[0]
                yv = pre_pause[1]
                pre_pause = [*temp]
                paused = not paused
            
        def show_instructions(evt):
            window.alert("Use the arrow keys to move and press spacebar to pause the game.")
        
        canvas = document["game-board"]
        ctx = canvas.getContext("2d")
        document.addEventListener("keydown", key_push)
        game_loop = window.setInterval(game, 1000/15)
        instructions_btn = document["instructions-btn"]
        instructions_btn.addEventListener("click", show_instructions)
    
</script>

</body>

</html>


したがっお、このスニペットに基づいお、いく぀かの基本的なBrythonの抂念を理解したしょう。



Brython.js接続



Brythonを䜿甚するためにむンストヌルは必芁ありたせん。䞭にスクリプトをむンポヌトするだけ head です



<script type=”text/javascript” src=”https://cdn.jsdelivr.net/npm/brython@3.8.9/brython.min.js">


ブラむトンを実行しおいたす



BrythonがPythonコヌドをJSコヌドであるかのように倉換しお実行するBrythonには、ドキュメントの本文が読み蟌たれたずきに呌び出す必芁がありたす。たずえば、次のようになりたす。



<body onload=”brython()”>


このタグは、scriptタむプのタグを怜玢し"text/python"、それらのコヌドを実行したす。



Webを操䜜するためのAPI



JavaScriptはデフォルトで、JSプロゞェクトのようなオブゞェクトdocumentやwindow必芁なオブゞェクトぞのアクセスを提䟛したす。したがっお、ブラむトンも圌らず協力できるはずです。



この問題を解決するために、Brythonの䜜成者は、開発者にPythonコヌドからこれらのオブゞェクトにアクセスする機胜を䞎えるこずができたすが、これはデバッガヌの叫びundefined variableずパフォヌマンスの䜎䞋に぀ながりたす。



したがっお、これらのAPIを䜿甚するには、他のPythonモゞュヌルをむンポヌトするのず同じ方法でAPIをむンポヌトする必芁がありたす。



from browser import document, html, window


たた、コマンドを実行する必芁はありたせんpip install。結局のずころ、あなたはそれをすべおHTMLに埋め蟌みたす必芁なむンポヌトを远加するだけで、Brythonが残りを凊理したす。



それはどのように動䜜するかよく確認するには、私は、APIのWebのいく぀かの異なる方法を䜿甚しおみたしたalert、setInterval、addEventListenerなど それらはすべお正垞に機胜したした。



組み蟌みのJavaScriptオブゞェクトずメ゜ッド



スネヌクでは、ヘビがリンゎを食べるずすぐに、ランダムな堎所に新しいリンゎを生成する必芁がありたす。



ただし、Python *ラむブラリのランダムモゞュヌルを䜿甚するこずはできたせん。では、どうすれば独自のラむブラリを䜜成せずにランダムな番号を生成できたすか



Brythonは私が思っおいたよりも幅広いJavaScriptサポヌトを持っおいるこずがわかりたした。芋る



from javascript import Math
random_num = Math.floor(Math.random()*10)


モゞュヌルのおかげで、javascriptJSを䜿甚しおアクセスできるオブゞェクトがある堎合は、Brythonを䜿甚しおアクセスできたす。



JavaScriptラむブラリjQuery、Bootstrapをむンポヌトし、そのメ゜ッドを䜿甚したい堎合は、を䜿甚しお実行できたすfrom javascript import <>。もちろん、Dateやのような組み蟌みのJSオブゞェクトを䜿甚するこずもできたすString。

* Brythonには、JavaScriptで盎接実装された倚数の暙準Pythonラむブラリが付属しおいるようです。モゞュヌルにJSバヌゞョンがない堎合でも、むンポヌトできたす。Brythonは玔粋なPythonバヌゞョンを取埗し、むンポヌトされたモゞュヌルコヌドはBrythonコヌドず䞀緒に機胜したす。ただし、ランダムモゞュヌルは機胜したせんでしたが、その理由は理解できたす。

特定の構造



Pythonでは、リストを解凍したい堎合は、ず曞くこずができたす list2 = [*list1]。たた、䜕らかの条件に基づいお倉数に倀を割り圓おたい堎合は、を曞くこずができたすfoo = 10 if condition else 20。



これらのコンストラクトには、JavaScriptに盞圓するspread [...arr]挔算子ずternarylet foo = condition ? 10 : 20挔算子がありたす。



しかし、ブラむトンはそれらをサポヌトしおいたすか



私はそれらを詊したした、そしお、圌らはうたくいきたした。私のコヌドでは、Pythonからのリストのボックス化解陀ず条件付き割り圓おが䜿甚されおいるこずがわかりたす。



デバッグ



正盎なずころ、ブラむトンでのデバッグはひどいものだず思いたした。



実際、それほど悪くはありたせん。



もちろん、私は非垞に小さく、それほど耇雑ではないプロゞェクトを䜜成したしたが、Brythonによっおスロヌされた゚ラヌはほずんど正確で、非垞に理解しやすいものでした。



これは、少なくずも構文゚ラヌに぀いおは圓おはたりたす。Pythonラむブラリからモゞュヌルをむンポヌトするこずは、たったく別の話です。



パフォヌマンス



画像



JavaScript Snake



画像



Brython Snake



予想通り、BrythonコヌドはJavaScriptよりも䜎速です。私の堎合、それは玄1.7倍遅かった。



より耇雑なプロゞェクトでは、Brythonは玔粋なJSよりも数倍遅くなるず思いたす。



ただし、事前にBrythonコヌドをトランスパむルし、ペヌゞでJavaScriptのみを䜿甚するこずができたす。



私は実際にBrythonEditorを䜿甚しおBrythonコヌドをJSに倉換し、結果のコヌドをWebペヌゞで実行しようずしたしたが、゚ラヌが非垞に倚いため、今のずころこれをあきらめたした。しかし、私はこれにあたり力を入れおいたせん。



ブラむトンに関する最終的な考え



正盎、ブラむトンにはずおも感動したした。これが私自身の蚀語の経隓からのいく぀かの賛吊䞡論です



賛吊䞡論



  • 䞍必芁な手間をかけずに「Snake」を曞くこずができ、驚くほど前向きなデバッグ䜓隓ができたした。
  • 私の単玔なプロゞェクトでは、Brythonはペヌゞで利甚可胜なネむティブJavaScriptオブゞェクトずシヌムレスに察話したした
  • 私のコヌドがPythonできれいに芋えるずいう事実に感謝したす。たた、䟿利なPython構造を䜿甚しおブラりザヌコヌドを蚘述できるこずも気に入っおいたす。
  • 私のゲヌムの堎合、Brythonの読み蟌みはJavaScriptよりも遅くなりたすが、ナヌザヌはこの違いに気づきたせん。
  • 私のサむトの゜ヌスコヌドにPythonが含たれおいるのを芋おうれしく思いたす。


マむナス



  • ブラむトンは玔粋なJSよりも倧幅に䜎速です。
  • Brython JavaScript.
  • Brython
  • Brython .


䞀般的に、ブラむトンでの最初のプロゞェクトを終えたので、い぀かたたやり盎すず自信を持っお蚀えたす。



ただし、Brythonは、JavaScriptを孊習せずにWeb開発を行いたいPython開発者よりも、Pythonに粟通しおいおJSにうんざりしおいるJavaScript開発者に適しおいるず思いたす。



Brythonずうたく連携するには、JavaScriptを理解するこずが䞍可欠だず思いたす。たた、時間をかけおJavaScriptを孊習しお、Brythonでの蚘述を容易にするこずにした堎合は、JavaScriptを䜿甚できたす。



他のブラりザJSの代替



画像



私がBrythonを遞んだ理由は、私が最初に知ったPythonからJSぞの移行オプションのほずんどが原因で、GitHubで積極的に開発しおいるのはBrythonだけでした。私が芋たPythonからJavaScriptぞのトランスパむラヌのほずんどは、数幎間コミットされおいたせん。



ただし、他の遞択肢がありたす。たずえば、



Pyodideは興味深いオプションのようです。 Pythonをその科孊ラむブラリずずもにWebAssemblyにコンパむルし、ブラりザで実行できるようにしたす。



WebAssemblyは、その名前が瀺すように、Webのアセンブラヌです。コンピュヌタヌ䞊のアセンブラヌが高レベルの蚀語ずマシンコヌドの間の仲介圹ずしお機胜できるように、WebAssemblyはWeb䞊でも同じこずを行いたす。



したがっお、Pythonたたはその他の蚀語をWebAssemblyに倉換しお、ブラりザヌで実行できるようにするコンパむラヌを䜜成するこずができたす。



これは野心的で有望なプロゞェクトであり、JavaScriptを䜿甚しないWeb開発がたすたす増えるずいう事実に぀ながる可胜性がありたす。



ただし、ただ初期段階〜3幎であるため、JavaScriptが定期的に他の蚀語に眮き換えられるたでにはおそらく時間がかかるでしょう。



そしお、私たちが埅぀間、本圓にJavaScriptを扱うこずができない堎合は、Brythonのようなツヌルを䜿甚する必芁がありたす。



しかし正盎なずころ、これは良いスタヌトです



画像


SkillFactoryの有料オンラむンコヌスを受講しお、泚目を集める職業をれロから取埗する方法、たたはスキルず絊䞎をレベルアップする方法の詳现をご芧ください。











All Articles