Games directly in Jupyter Notebook

Jupyter Notebook practice is the foundation of our Data Science course… But the interactive notepad can be used for more than just work. For details from the Jupyter Notebook developers blog, we invite you under cat.


Obviously, Jupyter needs simpler games, about 1000 lines of code, the development of which will not take a few days, but several hours: Pong, Pinball and AngryBirds. Therefore, we will focus on 2D games with simulation of the physical environment: they are very easy to implement using engines such as Box2D or Chipmunk2D.

Box2D

Box2D Is a library for simulating the behavior of rigid bodies in two-dimensional space in games. Here is the best demo of it, compiled into JavaScript using Emscripten. Try it:

Via Box2D it is easy to write games that simulate the physical environment, the mechanics of solids and the action of physical forces. For example, Angry Birds or World of Goo.

Box2D: Debug Draw

DebugDraw

Box2D has an abstract class DebugDraw with methods for drawing the simplest elements. Here’s its API:

DebugDraw on Box2D In action:

The implementation of this abstract class allows physical objects to be drawn for the user interface. Box2D has a DebugDraw implementation on glfw… In Python, you can do it with pygame or kivy… These renderings and DebugDraw are more than enough to quickly test game ideas in Box2D… In the finished product, they are replaced with custom rendering routines.

LiquidFun

LiquidFun – another library for 2D modeling of the behavior of solids and liquids in games written in C ++ with Box2D… It is best explained by a demo compiled in JavaScript with Emscripten (runs in browser):

More than just games

But Box2D Is not only a physics engine for 2D games, it is also used in education: on the YouTube channel iforce2d v Box2D made engine internal combustion and wind tunnel.

And such aerodynamic tube:

Box2D in Python

Box2D has bindings for many languages, it compiles to Wasm… Here are some demos:

The use of Box2D / LiquidFun in Python is especially interesting. There are such possibilities here:

pybox2d

Thanks to pybox2d there are mature and reliable in Box2D Python bindings with an extensive documentation… And here are the disadvantages pybox2d, he:

  • works only with the old version of Box2D;

  • no support for LiquidFun;

  • almost no maintenance pybox2d;

  • Python bindings are generated with SIWG (I personally prefer pybind11).

pyb2d

I’ll make a reservation right away: pyb2d for Box2D in Python I did (I wanted to write bindings for Box2D / LiquidFun using pybind11). Though pyb2d works with new Box2D 2.4.1 and supports LiquidFun and pybind11, in some ways it is inferior to pybox2d:

  • at pyb2d fewer examples;

  • he is not as mature and reliable;

  • not as well documented yet.

Particularly impressive BatchDebugDraw on pyb2d. The DebugDraw API could have been done directly in Python, but such an implementation would have several disadvantages:

  • When there are many shapes in the game, such as circles, you have to call very often drawCircle and making a lot of calls from C ++ to Python and vice versa, this leads to some overhead.

  • There are backends with the ability batch drawingallowing you to draw several simple elements at the same time. For example, 100 circles in different places in just one function call, the arguments of which are NumPy ndarray arrays with the centers / radii of the circles. Using such an API package can lead to tremendous speedups.

DebugDraw pyb2d API package for Python:

These shortcomings are eliminated in the implementation BatchDebugDraw on pyb2d. This is where all the individual calls are collected first, such as drawCircle, drawSegment, drawPolygon and so on. Their arguments are stored in NumPy arrays. After all the shapes are assembled, using the functions draw_circles, draw_segments, draw_polygons etc. the Python API is called. All shapes are passed to Python in one function call. On the Python side, these instructions batch drawing passed to the batch-drawing API of the supported UI (we will use the ipycanvas batch drawing API to integrate pyb2d with Jupyter).

Box2D integration requirements in Jupyter

To turn Jupyter into a game development platform, you need:

  • surface / canvas for drawing game content;

  • access to input devices (mouse, keyboard or even gamepads). Without user interaction, games would be boring.

Ipycanvas, Ipywidgets, Ipyevents

Jupyter has a huge ecosystem of extensions. To integrate with Box2D, you just need to choose the ones you need: Ipycanvas gives access to HTML Canvas from Python kernels to Jupyter (this is a surface / canvas for drawing game elements), and Ipywidets and Ipyevents – access to input devices (gamepads, keyboard and mouse).

Ipycanvas

Ipycanvas Is a lightweight library developed by Martin Renoux and providing browser Canvas API for Jupyter. It allows you to draw basic elements (text, lines, polygons, arcs, images, etc.) directly from Python. Having mastered a couple of tricks, on ipycanvas you can quickly make great animations, even when the server and the client are on different computers (for example, when you run ipycanvas on Mybinder).

Try it game “Life” on Ipycanvas:

DebugDraw on Ipycanvas

The first step of integrating pyb2d into Jupyter Notebook is implementation DebugDraw on Ipycanvas. We recently released new version Ipycanvas with extended API: drawing is now very fast. We use it when implementing the DebugDraw API.

Event Handling in Jupyter

Here we apply Ipyevents… Obviously, when starting the game, you need to manage events. To do this, in the Jupyter-notebook, a game loop is started in a dedicated thread, and events are listened to on the main thread.

Adding buttons

Buttons for launch, pauses and dumping games on Box2D are added using ipywidgets

What’s the bottom line?

We are integrating Box2D and pyb2d into Jupyter. To test the integration in practice, we have implemented several games:

Billiards

A very simple billiard game, try it it in the binding module:

Angry Shapes

This one is similar to Angry Birds the game is implemented using pyb2d, try it to play:

World of goo homage

Also implemented with pyb2d, try:

Rocket

Drive missile from the keyboard, just don’t hit the black hole:

Compatibility

All these pyb2d examples are also run in a window pygame or kivy – there are backends for them. Want to test on pygame? The Jupyter backend will help with this: examples can be placed on Mybinder (it is convenient to use them here).

Nuances

Although the pyb2d integration with Jupyter gives a decent frame rate even when run via Mybinder, in the backend on pygame it is usually even higher and the gameplay is smoother.

Let’s get ahead of ourselves

We are currently working on:

  • adding examples and improving documentation in pyb2d;

  • improved performance of integration with Jupyter;

  • adding pyb2d to JupyterLite;

  • implementation of remote multiplayer gameplay through the JupyterLab collaboration mode.

In this mode, you can connect to Notebook from two computers and play billiards against each other:

You can learn how to solve complex problems using Jupyter Notebook in our courses:

Find out the details here

Professions and courses

Data Science and Machine Learning

Python, web development

Mobile development

Java and C #

From the basics to the depth

As well as

Similar Posts

Leave a Reply