Разработка игры в стиле Mario с нуля на Python

Создание собственной игры в духе легендарного Super Mario Bros — это отличный способ прокачать навыки программирования, погрузиться в основы геймдева и просто повеселиться. В этой статье разберем, как разработать простую платформенную игру с нуля на языке Python, используя библиотеку Pygame.

http://t.me/pythonl – в нашем тг канале еще больше уроков и проектов для python разработчиков.


Предварительная подготовка

Перед тем как приступить к разработке, убедитесь, что у вас установлен Python и Pygame:

pip install pygame

Создадим структуру проекта:

/mario_game
|-- main.py
|-- player.py
|-- level.py
|-- config.py
|-- assets/
    |-- images/
    |-- sounds/

1. Окно игры

Начнем с создания игрового окна:

# main.py
import pygame
from config import *

pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Mini Mario")
clock = pygame.time.Clock()

🔍 Построчное объяснение:


import pygame

Импортируем библиотеку Pygame, которая используется для разработки 2D-игр в Python. Она предоставляет удобный интерфейс для работы с графикой, звуком, управлением и т.д.


from config import *

Импортируются все переменные из модуля config.py. Обычно в этом файле мы задаём глобальные настройки, такие как размеры окна, цвета, FPS и прочее.

Пример содержимого config.py:

pythonКопироватьРедактироватьSCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

pygame.init()

Инициализирует все встроенные модули Pygame (видео, звук, таймеры и т.д.). Это обязательный вызов перед использованием остальных функций библиотеки.


screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

Создаёт главное игровое окно с заданной шириной и высотой. Возвращает объект Surface, на который мы будем рисовать всё: фон, персонажей, платформы и т.д.


pygame.display.set_caption("Mini Mario")

Устанавливает заголовок окна (то, что отображается в верхней части окна игры или на панели задач).


clock = pygame.time.Clock()

Создаёт объект Clock, с помощью которого можно контролировать частоту кадров (FPS) в игровом цикле. Это помогает сделать игру более стабильной и плавной.


📌 Итог:
Этот блок создаёт окно и подготавливает всё необходимое для запуска игры: графику, заголовок, и таймер для контроля скорости игры. Это фундамент, с которого начинается практически любое приложение на Pygame.

2. Создание игрока

Создадим класс Player, который отвечает за героя:

# player.py
import pygame

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.image.load("assets/images/mario.png").convert_alpha()
        self.rect = self.image.get_rect(topleft=(x, y))
        self.velocity_y = 0
        self.on_ground = False

    def update(self, keys):
        dx = 0
        if keys[pygame.K_LEFT]:
            dx = -5
        if keys[pygame.K_RIGHT]:
            dx = 5

        self.velocity_y += 0.5  # gravity
        if self.velocity_y > 10:
            self.velocity_y = 10
        dy = self.velocity_y

        if keys[pygame.K_SPACE] and self.on_ground:
            self.velocity_y = -10
            self.on_ground = False

        self.rect.x += dx
        self.rect.y += dy

        # ground check (simplified)
        if self.rect.bottom >= SCREEN_HEIGHT:
            self.rect.bottom = SCREEN_HEIGHT
            self.velocity_y = 0
            self.on_ground = True

Давайте разберём следующий блок кода — класс Player из файла player.py, который отвечает за управление игровым персонажем:

🔍 Объяснение построчно:

class Player(pygame.sprite.Sprite):

Создаём класс игрока, который наследуется от pygame.sprite.Sprite — это позволяет удобно управлять группами спрайтов (например, отрисовкой и столкновениями).


def __init__(self, x, y):

Конструктор, принимает начальные координаты x и y для размещения игрока на экране.


super().__init__()

Вызываем конструктор родительского класса (Sprite), чтобы всё работало правильно в рамках pygame.sprite.


self.image = pygame.image.load("assets/images/mario.png").convert_alpha()

Загружаем картинку персонажа (Mario), используем convert_alpha() для поддержки прозрачности.


self.rect = self.image.get_rect(topleft=(x, y))

Создаём прямоугольник (rect) — это объект, описывающий позицию и размеры спрайта. Мы используем его для движения и столкновений.


self.velocity_y = 0

Скорость по вертикали (нужна для прыжков и гравитации).


self.on_ground = False

Флаг, указывающий, стоит ли игрок на земле. Это нужно, чтобы не позволить прыгать в воздухе.


👇 Метод update(self, keys) — вызывается каждый кадр

dx = 0

Смещение по горизонтали.


if keys[pygame.K_LEFT]: dx = -5

Если нажата стрелка влево — двигаемся влево на 5 пикселей.

if keys[pygame.K_RIGHT]: dx = 5

Если нажата стрелка вправо — двигаемся вправо.


self.velocity_y += 0.5

Добавляем гравитацию. Чем дольше падаем — тем быстрее.

if self.velocity_y > 10: self.velocity_y = 10

Ограничиваем максимальную скорость падения.


dy = self.velocity_y

Сохраняем вертикальное смещение.


if keys[pygame.K_SPACE] and self.on_ground:

Если нажата клавиша пробел и игрок стоит на земле — делаем прыжок:

pythonКопироватьРедактироватьself.velocity_y = -10
self.on_ground = False

self.rect.x += dx

Перемещаем игрока по горизонтали.

self.rect.y += dy

Перемещаем по вертикали (с учётом гравитации и прыжков).


if self.rect.bottom >= SCREEN_HEIGHT:

Если игрок опускается ниже экрана (например, упал) — ставим его обратно на землю:

pythonКопироватьРедактироватьself.rect.bottom = SCREEN_HEIGHT
self.velocity_y = 0
self.on_ground = True

📌 Вывод

Класс Player реализует базовое движение игрока:
• Влево/вправо
• Прыжок
• Гравитация
• Простая проверка, стоит ли он на земле

Это фундамент платформера.

3. Уровень и платфоры

Создадим платформы, по которым может ходить игрок:

# level.py
import pygame

class Platform(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height):
        super().__init__()
        self.image = pygame.Surface((width, height))
        self.image.fill((100, 100, 100))
        self.rect = self.image.get_rect(topleft=(x, y))

🔍 Объяснение построчно

import pygame

Импортируем Pygame — для работы со спрайтами и отрисовкой.


class Platform(pygame.sprite.Sprite):

Определяем класс Platform, представляющий собой простую платформу. Как и Player, он наследует pygame.sprite.Sprite, что позволяет использовать его в группах спрайтов, например Group.draw().


def __init__(self, x, y, width, height):

Конструктор, принимает:

  • x, y — координаты верхнего левого угла платформы
  • width, height — размеры платформы

super().__init__()

Вызываем конструктор родительского класса Sprite.


self.image = pygame.Surface((width, height))

Создаём пустую поверхность (Surface) — прямоугольник нужного размера. Это будет изображение платформы.


self.image.fill((100, 100, 100))

Закрашиваем платформу серым цветом. Можно заменить на любую картинку — например, кирпичи, траву и т.д.


self.rect = self.image.get_rect(topleft=(x, y))

Создаём прямоугольную область (rect), описывающую положение платформы на экране.


🧱 Что делает этот класс?

Он создаёт прямоугольную платформу, по которой может ходить игрок. Позже мы добавляем такие платформы в Group и рисуем их, как обычные спрайты.


🧩 Как используется?

Вот часть из main.py, где мы добавляем платформу на экран:

pythonКопироватьРедактироватьfrom level import Platform

platforms = pygame.sprite.Group()
platforms.add(Platform(0, SCREEN_HEIGHT - 40, SCREEN_WIDTH, 40))  # земля

Тут создаётся платформа-земля — она тянется на всю ширину экрана, располагается внизу и имеет высоту 40 пикселей.

4. Главный цикл игры

Соберем все воедино:

# main.py (продолжение)
from player import Player
from level import Platform

player = Player(100, 300)
player_group = pygame.sprite.Group()
player_group.add(player)

platforms = pygame.sprite.Group()
platforms.add(Platform(0, SCREEN_HEIGHT - 40, SCREEN_WIDTH, 40))

running = True
while running:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    keys = pygame.key.get_pressed()
    player.update(keys)

    screen.fill((135, 206, 235))  # sky blue
    platforms.draw(screen)
    player_group.draw(screen)

    pygame.display.flip()

pygame.quit()

5.

  1. Сделать уровни из массива/тайлов
  2. Добавить столкновения игрока с платформами

🧱 1. Уровень из массива (tile map)

Идея простая: задаём уровень как список строк, где каждый символ означает элемент карты. Пример:


level_map = [
" ",
" ",
" XX XX ",
" ",
" XXXX XXXX XX ",
"XXXXXXXX XXXXXXXXX XXXX ",
]
  • "X" — платформа
  • " " — пустота

🔄 Построение карты

Создаём функцию, которая будет проходить по level_map и размещать платформы на нужных позициях:

TILE_SIZE = 40  # размер одного тайла

def build_level(level_data):
platforms = pygame.sprite.Group()
for row_index, row in enumerate(level_data):
for col_index, tile in enumerate(row):
if tile == "X":
x = col_index * TILE_SIZE
y = row_index * TILE_SIZE
platform = Platform(x, y, TILE_SIZE, TILE_SIZE)
platforms.add(platform)
return platforms

📌 Теперь можно создать платформы так:

pythonКопироватьРедактироватьplatforms = build_level(level_map)

🧱 2. Столкновения с платформами

Добавим в Player.update() логику проверки столкновений с платформами. Например:

def update(self, keys, platforms):
dx = 0
dy = 0

# движение влево/вправо
if keys[pygame.K_LEFT]:
dx = -5
if keys[pygame.K_RIGHT]:
dx = 5

# гравитация
self.velocity_y += 0.5
if self.velocity_y > 10:
self.velocity_y = 10
dy += self.velocity_y

# прыжок
if keys[pygame.K_SPACE] and self.on_ground:
self.velocity_y = -10
self.on_ground = False

# горизонтальные столкновения
self.rect.x += dx
for platform in platforms:
if self.rect.colliderect(platform.rect):
if dx > 0: # вправо
self.rect.right = platform.rect.left
if dx < 0: # влево
self.rect.left = platform.rect.right

# вертикальные столкновения
self.rect.y += dy
self.on_ground = False
for platform in platforms:
if self.rect.colliderect(platform.rect):
if self.velocity_y > 0: # падение
self.rect.bottom = platform.rect.top
self.velocity_y = 0
self.on_ground = True
elif self.velocity_y < 0: # прыжок вверх
self.rect.top = platform.rect.bottom
self.velocity_y = 0


👾 Использование:

В main.py теперь передаём платформы в update():

pythonКопироватьРедактироватьplayer.update(keys, platforms)

6. Развитие

Что можно добавить дальше:

  • Враги и ИИ
  • Монетки и система очков
  • Таймер, жизни, уровни
  • Фоновая музыка и звуки прыжков
  • Анимации бега и прыжков
  • Камера, следящая за игроком

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


Вывод

Создание своей Mario-подобной игры на Python — это увлекательный проект, который помогает понять принципы гейм-логики, работы с графикой и анимацией. Начав с простого, вы легко сможете наращивать функциональность и делать свою игру всё более продвинутой.

+1
2
+1
22
+1
0
+1
1
+1
0

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *