Разработка игр
December 5

Знакомимся с созданием ретроигр при помощи Pyxel

Pyxel – это дань уважения игровым консолям золотого века, таким как SNES или Game Boy Color: крупные пиксели, мало цветов и минималистичный четырёхканальный звук. Такие простые игры можно создавать быстро, и они будут без проблем работать на любых ПК и на любой ОС.

Установка

Pyxel – это фреймворк на Python со встроенным медиаредактором. Чтобы начать работу, открываем свою любимую IDE, создаем виртуальное окружение и устанавливаем сам Pyxel:

pip install pyxel

И сразу загрузим встроенные примеры проектов:

pyxel copy_examples

Теперь мы можем использовать команду run для запуска одного из примеров:

pyxel run pyxel_examples/02_jump_game.py

В Jump Game нужно использовать клавиши влево и вправо для замедления и ускорения персонажа.

Если всё работает, то поиграйте, а потом почитайте документацию, чтобы знать, как вносить правки в эти игры.

Медиаредактор Pyxel

Pyxel предоставляет медиаредактор для спрайтов, тайловых карт, звука и музыки. Он работает со всеми стандартными форматами файлов.

  • Pyxel работает с форматом PNG (с поддержкой прозрачности). Можно загрузить PNG/GIF/JPG файлы, просто перетащив их в окно редактора.
  • Поддерживаются только пиксельные шрифты в формате BDF (можно редактировать их с помощью FontForge).
  • Карты используют формат TMX, их можно редактировать при помощи Tiled.
  • Pyxel использует старые синтезаторные инструкции в специальном формате для звуков.

Pyxel создает архивы pyxres, которые представляют собой ZIP-файлы с вложенным TOML-файлом.

Запускаем редактор, чтобы создать такой архив с ресурсами:

pyxel edit initiation.pyxres &

И нарисуем 2 космических корабля, 16 пикселей в высоту и ширину.

Это твой личный корабль, рисуйте его, как хотите.

Первый рисунок – это вариант корабля, который смотрит вправо, а второй будет смотреть влево.

Первый цвет палитры прозрачный; это значение 0 в коде .

Код

Теперь создадим файлик initiation.py и будем в нём писать код.

Статический космический корабль

Приложение создаём на основе класса. В методе __init__ указываем размер экрана и его название, указываем используемые ресурсы (тот самый pyxres файл).

Метод update обрабатывает входные данные (в данном случае с клавиатуры) .

Метод draw отрисовывает весь игровой экран.

import pyxel


class App:
    def __init__(self):
        pyxel.init(160, 120, title="UFO static")  # ширина, высота, название
        pyxel.load("initiation.pyxres")
        self.player_x = 72  # 🛸 позиция по оси x
        self.player_y = 72  # 🛸 позиция по оси y
        self.ship = (0, 0, 16, 16, 0)  # x, y, ширина, высота, прозрачный цвет

        pyxel.run(self.update, self.draw)

    def update(self):
        if pyxel.btnp(pyxel.KEY_Q):
            pyxel.quit()

    def draw(self):
        pyxel.cls(0)  # очистка экрана цветом 0

        # Отрисовка 🛸
        pyxel.blt(self.player_x, self.player_y, 0, *self.ship)


App()

Попросим Pyxel зафиксировать изменения и показать результат:

pyxel watch . initiation.py

Корабль находится посреди космической пустоты. Всё, что мы можем – выйти из приложения при помощи клавиши Q.

Добавляем тряску

Немного математики, всего лишь косинусы, чтобы наш кораблик немножко дрыгался.

import pyxel


class App:
    def __init__(self):
        pyxel.init(160, 120, title="UFO shaken")  # ширина, высота, название
        pyxel.load("initiation.pyxres")
        self.player_x = 72  # 🛸 позиция по оси x
        self.player_y = 72  # 🛸 позиция по оси y
        self.ship = (0, 0, 16, 16, 0)  # x, y, ширина, высота, прозрачный цвет

        pyxel.run(self.update, self.draw)

    def update(self):
        if pyxel.btnp(pyxel.KEY_Q):
            pyxel.quit()

        # 🛸 тряска на 1/16 за тик, начиная с y = 72
        self.player_y = pyxel.cos(pyxel.frame_count * 360 / 16) + 72

    def draw(self):
        pyxel.cls(0)  # очистка экрана цветом 0

        # Отрисовка 🛸
        pyxel.blt(self.player_x, self.player_y, 0, *self.ship)


App()

Движение корабля вперёд и назад

Направление "взгляда" корабля будет определяться двумя спрайтами.

При помощи стрелок мы сможем перемещать его вперёд или назад на два пикселя. За пределы экрана выйти нельзя.

import pyxel


class App:
    def __init__(self):
        pyxel.init(160, 120, title="UFO shaken")  # ширина, высота, название
        pyxel.load("initiation.pyxres")
        self.player_x = 72  # 🛸 позиция по оси x
        self.player_y = 72  # 🛸 позиция по оси y
        self.spaceship_r = (0, 0, 16, 16, 0)  # x, y, ширина, высота, прозрачный цвет
        self.spaceship_l = (16, 0, 16, 16, 0)
        self.ship = self.spaceship_r  # 🛸 смотрит ->

        pyxel.run(self.update, self.draw)

    def update(self):
        if pyxel.btnp(pyxel.KEY_Q):
            pyxel.quit()

        if pyxel.btn(pyxel.KEY_LEFT) or pyxel.btn(pyxel.GAMEPAD1_BUTTON_DPAD_LEFT):
            self.player_x = max(self.player_x - 2, 0)  # летим ->
            self.ship = self.spaceship_l  # 🛸 смотрим <-
        if pyxel.btn(pyxel.KEY_RIGHT) or pyxel.btn(pyxel.GAMEPAD1_BUTTON_DPAD_RIGHT):
            self.player_x = min(self.player_x + 2, pyxel.width - 16)  # летим ->
            self.ship = self.spaceship_r  # 🛸 смотрим ->
            
        # 🛸 тряска на 1/16 за тик, начиная с y = 72
        self.player_y = pyxel.cos(pyxel.frame_count * 360 / 16) + 72

    def draw(self):
        pyxel.cls(0)  # очистка экрана цветом 0

        # Отрисовка 🛸
        pyxel.blt(self.player_x, self.player_y, 0, *self.ship)


App()

Вот и всё, у нас есть маленький трясущийся космический кораблик, которым можно управлять с клавиатуры. Что дальше? Звуки, звёзды на фоне, лазерные лучи и враждебные инопланетяне? Дело за вами!

👉🏻Подписывайтесь на PythonTalk в Telegram 👈🏻

👨🏻‍💻Ещё больше полезного на OlegTalks💬

🍩 Поддержите канал 🫶

Источник: Garambrogne 2.0