If you like Python and making games, graphics, or demos you might have reached for pygame, pyglet, pyOpenGL, or kivy in the past. The browser has been a far-off land for Python. This is a shame, I think, because graphics programming in the browser is a superior experience for experimentation: zero-installation and no drivers to mess with.
I’ve been thinking about how we could make game development in Python more accessible for everyone. The browser is a nice target because it handles the drivers and setup. The only question was how we could run Python code there.
Our goal is a simple demonstration you can see below.
We want to animate a box moving on a sinusoidal wave along the y-axis and trailing the mouse on the x-axis while the mouse is within the canvas bounds.
The first step is to download and unzip the Brython archive in your
project directory. You don’t even need Python installed on your
system. From here on out,
brython.js is your Python.
test.html file to the Brython distribution and add the
following to it:
1 2 3 4 5 6 7 8 9 10 11 12
<html> <head> <meta charset="UTF-8"> <script src="brython.js"></script> </head> <body onload="brython(1)"> <script type="text/python" src="test.py"></script> <div id="game" style="width: 800; height: 500; margin: 0 auto;"> <canvas id="stage" width="800" height="500" style="width: 100%"></canvas> </div> </body> </html>
That’s all there is to it. The important part to note is that we call
brython() function in the document body’s
Once you call this function from your page, Brython can run Python
scripts… as we do on the next line.
So go ahead and create
test.py next to your
test.html and move on
to the next step.
Here are the imports you should put at the top of
1 2 3 4 5
from browser import doc from browser.timer import request_animation_frame as raf import math import time
There are a some things here to notice. First being the
package. It includes modules for interacting with most (or perhaps
all, I haven’t checked thoroughly) of the browser APIs. The
module gives us access to the DOM. We use
timer module to schedule our animation loop in the browser. And
at the end we have a couple of… Python standard library imports.
A note on the standard library in Brython: it’s there but the issue is
thorny. Brython ships with a good deal of the standard library. You
can import all of the usual suspects. However the import machinery on
direct access to the filesystem. This can get really slow if you try
to import a module that imports other modules such as
Brython provides a bundled single-file standard lib that you can include in your HTML file directly but it requires asking the user to download around 2MB of code first.
It might be possible to compile your own bundled standard library to slim down that 2MB of code but that is out of the scope of the discussion here. Read the Brython documentation on the import mechanism for more information.
This tutorial is going to be using the 2D-context of the canvas element. With Brython this is a simple matter of adding a couple lines of code:
canvas = doc['stage'] ctx = canvas.getContext('2d')
This code is purely for demonstration purposes and is in no way meant
to be illustrative of best practices or serve as a guide. Consider
yourself warned. However it suits our purpose for exploring the
the following code to
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
ticks = 0 x = 0.0 def mouse_moved(ev): global x new_x = ev.clientX - (canvas.width / 2) + 25 if new_x > 50 and new_x < canvas.width - 100: x = new_x canvas.bind("mousemove", mouse_moved) def clear(): ctx.save() ctx.setTransform(1, 0, 0, 1, 0, 0) ctx.clearRect(0, 0, canvas.width, canvas.height) ctx.restore() def draw(): global ticks ticks += 1 clear() y = (150 * math.sin(ticks / 50)) + 150 ctx.fillStyle = "blue" ctx.fillRect(x, y, 100.0, 100.0) ctx.fill() def animate(i): global id id = raf(animate) draw() animate(0)
I will continue experimenting with Brython and Skulpt in the hopes that I can get a full-fledged game running on them. I agree with other people in the Python community that this language should be better at games and one of the more important platforms for games today is the web. I suspect that the approach Brython and others take might be the avenue by which we can bring Python to the client-side of the web.
Download Brython or Skulpt today and see for yourself how much fun it is.