Перейти к основному содержимому

Kivy — мобильные приложения и игры на Python

Разработчику Начальный уровень

Что такое Kivy

Kivy — open-source фреймворк для кроссплатформенных приложений с сенсорным вводом. Интерфейс рисуется через OpenGL ES 2, поэтому один и тот же код можно запускать на Windows, macOS, Linux, Android и (с ограничениями) iOS. Для учебных мобильных игр и прототипов на Python Kivy — практичная альтернатива тяжёлым движкам вроде Unity.

Виджет в Kivy — узел дерева UI с координатами, размером и обработчиками событий. Главный цикл Kivy не пишут вручную: его запускает App.run(), а кадры и таймеры планируют через Clock. Это отличает Kivy от Pygame, где цикл while running — центр программы (см. Разработка игр на Python).

Краткий обзор в экосистеме Python — в справочнике библиотек. В этой статье — архитектура, отличия от Pygame/Tkinter/Flutter и маршрут к практикумам (2048, Pong, Snake).

Где читать дальше

Мобильный контекст — ограничения платформы, магазины, сенсорный UI — раздел "Мобильные приложения", Мобильные игры.
Игры на десктопе — Pygame и учебный практикум — Разработка игр на Python, Практикум разработки игр.
Окна с формами — встроенный Tkinter — Tkinter и GUI, галерея виджетов в Lab.


Сравнение Kivy, Pygame, Tkinter и Flutter

КритерийKivyPygameTkinterFlutter
ЦельМультитач UI, мобильные игры2D-игры на десктопеДесктопные формыНативный мобильный UI
ГрафикаOpenGL, canvasSDL, blit на SurfaceСистемные виджеты Tcl/TkSkia, Material/Cupertino
Сенсорon_touch_*, свайпыМышь, джойстикМышьЖесты из коробки
Сборка APKBuildozer, python-for-androidНетНетflutter build apk
Кривая обученияСредняяНиже для игрНиже для формВыше (Dart + экосистема)

Правило выбора

  • Уже знаете Python и нужна простая мобильная игра с тачем — Kivy.
  • Игра только для ПК — Pygame и мини-игры в Lab.
  • Нужен продуктовый мобильный UI с нативным видом — Flutter или Kotlin/Swift из мобильного раздела.
  • Окно с кнопками и полями без OpenGL — Tkinter.

Установка и первый запуск

Перед Kivy полезно настроить окружение по Зависимости Python — venv и requirements.txt избавят от конфликтов пакетов.

python -m venv .venv
# Windows: .venv\Scripts\activate
# Linux/macOS: source .venv/bin/activate
pip install "kivy>=2.3.0"

Минимальное приложение:

from kivy.app import App
from kivy.uix.button import Button


class HelloApp(App):
def build(self):
return Button(text="Привет, Kivy!", on_press=lambda *_: print("tap"))


if __name__ == "__main__":
HelloApp().run()

Разбор.

  • App — точка входа: метод build() возвращает корневой виджет, run() запускает цикл событий.
  • on_press — обработчик нажатия; на мобильном это сработает и от тапа.
  • if __name__ == "__main__" — тот же приём, что в первой программе на Python и точке входа __main__.

Запуск — python main.py. Окно появится на десктопе — это нормально: Kivy сначала отлаживают на ПК, затем упаковывают в APK (сборка APK).


Архитектура Kivy

App и жизненный цикл

Жизненный цикл мобильного экрана в общих чертах описан в Мобильных приложениях. В Kivy на практике важны три шага:

  • Наследуем kivy.app.App, реализуем build() — возвращаем корневой виджет.
  • App.run() запускает главный цикл — обработка событий, отрисовка, таймеры.
  • Точка входа — if __name__ == "__main__": ...App().run(), как в обычных Python-скриптах.

Виджеты и компоновка

Виджет (Widget и наследники) — прямоугольная область с pos, size и дочерними элементами. Layout раскладывает детей по правилам.

КлассНазначение
BoxLayoutВертикальный или горизонтальный стек
GridLayoutСетка с фиксированным числом столбцов (cols)
FloatLayoutАбсолютное позиционирование дочерних элементов
WidgetПустая область — база для кастомной отрисовки на canvas

Размеры задают двумя способами:

  • Доля родителяsize_hint=(1, 0.3) (ширина 100%, высота 30%).
  • Фиксированный размерsize_hint_y=None и height=dp(48) (см. ниже про dp).

Аналог компоновки в других стеках — Flutter Layout, Tkinter pack/grid.

Единицы dp и sp

dp (density-independent pixel) — логический пиксель, не зависящий от плотности экрана. kivy.metrics.dp(48) даёт одинаково "щёлкаемую" кнопку на телефоне и на мониторе с высоким DPI.

sp (scale-independent pixel) — для шрифтов; в Kivy пишут "22sp" в font_size.

На мобильных важен адаптивный дизайн — см. Мобильные игры (раздел про экраны и safe areas). В Kivy доли size_hint и dp — основной инструмент.

Отрисовка через canvas

Canvas — слой OpenGL-примитивов (Rectangle, Ellipse, Line, RoundedRectangle), привязанный к виджету. canvas.before рисует под дочерними виджетами (фон), canvas — поверх фона, но логика та же.

from kivy.graphics import Color, Rectangle

with self.canvas:
Color(0.2, 0.8, 1, 1)
self.rect = Rectangle(pos=self.pos, size=self.size)
self.bind(pos=self._sync, size=self._sync)

Разбор.

  • with self.canvas — контекстный менеджер добавляет примитивы на слой виджета.
  • Color(r, g, b, a) — компоненты 0..1, не 0..255.
  • bind(pos=..., size=...) обязателен: без него при ресайзе окна прямоугольник "отстанет" от виджета.

В практикуме Pong ракетка и мяч — виджеты с Rectangle/Ellipse; в 2048RoundedRectangle у плиток.

Игровой цикл и Clock

В Pygame игровой цикл — явный while running с clock.tick(60) (теория в 312). В Kivy кадры планируют через Clock:

from kivy.clock import Clock

Clock.schedule_interval(self.update, 1.0 / 60.0) # ~60 FPS

def update(self, dt):
self.ball.x += self.ball.velocity_x * dt

Разбор.

  • dt — секунды с прошлого вызова; умножение скорости на dt даёт движение, не зависящее от частоты кадров (как в физике Pong на Pygame).
  • schedule_once — один отложенный вызов (подача мяча через 0.8 с после гола).
  • Отмена — event.cancel(); в Snake интервал пересоздают при ускорении.

Сенсорный ввод

Touch в Kivy — объект с координатами touch.x, touch.y. Цепочка событий:

  • on_touch_down — палец коснулся экрана;
  • on_touch_move — палец движется;
  • on_touch_up — палец оторван.

Свайп — разность координат между down и up. Сохраняют _touch_start, сравнивают dx/dy с порогом dp(30) — так сделано в Kivy — 2048 и Kivy — Snake. Теория жестов — Мобильные игры (тап, свайп, виртуальные кнопки).

Перетаскивание — обновление позиции в on_touch_move, пока player_touch_activeKivy — Pong.

Клавиатура на десктопе — Window.bind(on_key_down=handler); удобно при отладке на ПК без телефона.

Возврат True из обработчика означает "событие обработано" и останавливает всплытие к родителю.

Properties и привязки

Property в Kivy — объявленный атрибут с уведомлением при изменении. Пример:

from kivy.properties import NumericProperty

class Paddle(Widget):
score = NumericProperty(0)

# где-то в App:
self.field.player.bind(score=self._update_score_labels)

При player.score += 1 Kivy сам вызовет _update_score_labels — не нужно вручную обновлять Label после каждого гола. Подробнее в практикуме Pong, этап 8.


Разделение логики и UI

Модель хранит состояние и правила; представление рисует и принимает ввод. Связь — тонкий слой: game.move("left")board.refresh().

В учебных проектах Kivy:

  • 2048game_logic.py (Game2048) не импортирует Kivy; main.py только рисует сетку.
  • Pong / Snake — логика в GameField / SnakeBoard, корневой layout — в App.build().

Тот же приём — в SmallPong на Pharo (PongGame + PongGameMorph) и Pygame-практикуме Pong (пакет game/).

Плюсы разделения:

  • логику можно проверить без GUI (тесты, REPL);
  • проще перенести UI на другой фреймворк;
  • меньше смешивания математики и отрисовки в одном файле.

Сборка APK

Для Android обычно используют Buildozer — обёртку над python-for-android, которая собирает Python, Kivy и зависимости в APK.

Типичные шаги:

  1. Установите зависимости Buildozer (Linux или WSL; на Windows нативная сборка часто проблемна — см. сравнение стеков).
  2. Создайте buildozer.spec с requirements = python3,kivy.
  3. Выполните buildozer android debug — получите APK для установки по USB (установка на телефон).

Подпись, keystore и публикация — Сборка мобильных приложений и Публикация Android.

Совет

Сначала доведите игру до рабочего состояния на десктопе (python main.py), затем переходите к Buildozer. Отладка графики и тача в эмуляторе Android сложнее, чем в окне Kivy на ПК.


Практикумы — три мобильные игры

Пошаговые реализации с самопроверкой на каждом этапе:

ИграФокусСтатья
2048Свайпы, сетка, JsonStore, логика без UIKivy — 2048
PongClock, физика мяча, тач, ИИKivy — Pong
SnakeТик змейки, еда, D-pad + свайпKivy — Snake

Обзор маршрута и порядок прохождения — Практикум Kivy — о разделе.


Частые ошибки

СимптомПричинаЧто сделать
Чёрный экранНе вызван App.run() или build() вернул NoneПроверьте точку входа и return в build()
Графика "плывёт" при ресайзеНе обновляются Rectangle.pos / sizebind(pos=..., size=...) на виджете
Свайп не срабатываетПорог слишком большой или touch уходит в дочерний виджетУменьшите порог dp(20–30), перехватите touch на поле
Игра "тормозит" на телефонеТяжёлая логика в on_touch_moveПеренесите физику в Clock, touch только меняет состояние
pip install kivy падаетНет SDL2 / зависимостей ОСДокументация Kivy — Installation

Официальные материалы