Практика в Jupyter Notebook — это основа нашего курса по Data Science. Но интерактивный блокнот можно использовать не только для работы. За подробностями из блога разработчиков Jupyter Notebook приглашаем под кат.
Очевидно, что в Jupyter нужны игры попроще, около 1000 строк кода, на разработку которых не уйдёт не много дней, а несколько часов: Pong, Pinball и AngryBirds. Поэтому сделаем акцент на 2D-играх с моделированием физической среды: их очень легко реализовать при помощи движков типа Box2D или Chipmunk2D.
Box2D
Box2D — это библиотека для моделирования в играх поведения твёрдых тел в двумерном пространстве. Вот её лучшая демонстрация, скомпилированная в JavaScript с помощью Emscripten. Попробуйте:
С помощью Box2D легко писать игры, моделирующие физическую среду, механику твёрдых тел и действие физических сил. Например, Angry Birds или World of Goo.
Box2D: Debug Draw
DebugDraw
В Box2D есть абстрактный класс DebugDraw с методами рисования простейших элементов. Вот его API:
DebugDraw на Box2D в действии:
Реализация этого абстрактного класса позволяет рисовать физические объекты для пользовательского интерфейса. В Box2D есть реализация DebugDraw на glfw. В Python можно сделать её на pygame или kivy. Этих отрисовок и DebugDraw более чем достаточно, чтобы быстро протестировать игровые идеи в Box2D. В готовом продукте они заменены на специальные процедуры отрисовки.
LiquidFun
LiquidFun — ещё одна библиотека 2D-моделирования поведения твёрдых тел и жидкости в играх, написанных на C++ с Box2D. Лучше всего её объясняет демо, скомпилированное в JavaScript с помощью Emscripten (запускается в браузере):
Больше, чем просто игры
Но Box2D — это не только физический движок для игр в 2D, он используется и в образовании: на YouTube-канале iforce2d в Box2D сделали двигатель внутреннего сгорания и аэродинамическую трубу.
И такая аэродинамическая труба:
Box2D на Python
В Box2D есть биндинги для многих языков, он компилируется в Wasm. Вот несколько демо:
http://www.iforce2d.net/embox2d/testbed.html (только HTTP)
Особенно интересно использование Box2D / LiquidFun в Python. Здесь есть такие возможности:
pybox2d
Благодаря pybox2d в Box2D есть зрелые и надёжные привязки Python с обширной документацией. И вот недостатки pybox2d, он:
работает только со старой версией Box2D;
нет поддержки LiquidFun;
почти нет сопровождения pybox2d;
привязки Python генерируются с помощью SIWG (лично я предпочитаю pybind11).
pyb2d
Сразу оговорюсь: pyb2d для Box2D на Python сделал я (хотелось написать биндинги для Box2D / LiquidFun с помощью pybind11). Хотя pyb2d работает с новой версией Box2D 2.4.1 и поддерживает LiquidFun и pybind11, кое в чём он уступает pybox2d:
у pyb2d меньше примеров;
он не такой зрелый и надёжный;
пока не так хорошо документирован.
Особенно впечатляет BatchDebugDraw на pyb2d. API DebugDraw можно было сделать прямо в Python, но такая реализация имела бы ряд недостатков:
Когда в игре много фигур, например окружностей, приходится очень часто вызывать drawCircle и выполнять много вызовов из C++ в Python и наоборот, это приводит к определённым накладным расходам.
Есть бэкенды с возможностью пакетного рисования, позволяющие рисовать несколько простейших элементов одновременно. Например, 100 окружностей в разных местах всего одним вызовом функции, аргументы которой — массивы NumPy ndarray с центрами/радиусами окружностей. Использование такого API-пакета может привести к огромному ускорению.
API-пакет DebugDraw pyb2d для Python:
Эти недостатки устранены в реализации BatchDebugDraw на pyb2d. Здесь сначала собираются все отдельные вызовы, такие как drawCircle, drawSegment, drawPolygon и т. д. Их аргументы сохраняются в массивах NumPy. После того как все фигуры собраны, с помощью функций draw_circles, draw_segments, draw_polygons и т. д. вызывается Python API. Все фигуры передаются в Python в одном вызове функции. На стороне Python эти инструкции пакетного рисования передаются в batch-drawing API поддерживаемого пользовательского интерфейса (будем использовать API пакетного рисования ipycanvas для интеграции pyb2d с Jupyter).
Требования интеграции Box2D в Jupyter
Чтобы сделать из Jupyter платформу для разработки игр, требуется:
поверхность/холст для рисования контента игр;
доступ к устройствам ввода (мышь, клавиатура или даже геймпады). Без взаимодействия с пользователем игры были бы скучными.
Ipycanvas, Ipywidgets, Ipyevents
В Jupyter огромная экосистема расширений. Для интеграции с Box2D нужно лишь выбрать из них нужные: Ipycanvas даёт доступ к HTML Canvas из ядер Python в Jupyter (это поверхность/холст для рисования элементов игр), а Ipywidets и Ipyevents — доступ к устройствам ввода (геймпадам, клавиатуре и мыши).
Ipycanvas
Ipycanvas — это легковесная библиотека, разработанная Мартином Рену и предоставляющая браузерный Canvas API для Jupyter. Она позволяет рисовать простейшие элементы (текст, линии, многоугольники, дуги, изображения и т. д.) прямо из Python. Освоив пару трюков, на ipycanvas достаточно быстро можно делать отличную анимацию, даже когда сервер и клиент на разных компьютерах (например, при запуске ipycanvas на Mybinder).
Попробуйте игру «Жизнь» на Ipycanvas:
DebugDraw на Ipycanvas
Первый этап интеграции pyb2d в Jupyter Notebook — реализация DebugDraw на Ipycanvas. Недавно мы выпустили новую версию Ipycanvas с расширенным API: рисовать теперь можно очень быстро. Используем её при реализации API DebugDraw.
Обработка событий в Jupyter
Здесь применяем Ipyevents. Очевидно, что при запуске игры надо управлять событиями. Для этого в Jupyter-notebook в выделенном потоке запускается цикл игры, а в основном потоке прослушиваются события.
Добавление кнопок
Кнопки для запуска, паузы и сброса игры на Box2D добавляются с помощью ipywidgets.
Что в итоге?
Мы интегрируем Box2D и pyb2d в Jupyter. Чтобы проверить интеграцию в деле, мы реализовали несколько игр:
Бильярд
Очень простая бильярдная игра, попробуйте её в модуле привязки:
Angry Shapes
Эта похожая на Angry Birds игра реализована с помощью pyb2d, попробуйте поиграть:
World of Goo homage
Тоже реализована с pyb2d, попробуйте:
Rocket
Управляйте ракетой с клавиатуры, только не попадите в чёрную дыру:
Совместимость
Все эти примеры pyb2d также запускаются в окне pygame или kivy — для них есть бэкенды. Хотите протестировать на pygame? В этом поможет бэкенд Jupyter: примеры можно разместить на MyBinder (здесь ими удобно пользоваться).
Нюансы
Хотя интеграция pyb2d с Jupyter даёт приличную частоту кадров даже при запуске через Mybinder, в бэкенде на pygame она обычно ещё выше, а игровой процесс более плавный.
Забегаем вперёд
Сейчас мы работаем над:
добавлением примеров и улучшением документации в pyb2d;
повышением производительности интеграции с Jupyter;
добавлением pyb2d в JupyterLite;
реализацией удалённого многопользовательского игрового процесса через режим совместной работы JupyterLab.
В этом режиме можно подключаться к Notebook с двух компьютеров и играть на бильярде друг против друга:
Научиться решать сложные задачи с помощью Jupyter Notebook вы сможете на наших курсах:
Узнайте подробности здесь.
Профессии и курсы
Data Science и Machine Learning
Python, веб-разработка
Мобильная разработка
Java и C#
От основ — в глубину
А также
telpos
Есть что-то подобное для геометрической оптики?