Найти в Дзене
Concepta junior

Создаем свою компьютерную игру на Python: приключение с прыгающим героем

Привет, юные программисты и любители приключений! Ты когда-нибудь мечтал создать свою собственную компьютерную игру? Такую, где герой прыгает по платформам, собирает монетки и сражается с монстрами? Сегодня я расскажу тебе, как можно сделать такую игру самостоятельно, используя язык программирования Python! Начнем с самого начала — что же такое "платформер"? Это такой тип игр, где главный герой прыгает по разным платформам, перепрыгивает через пропасти, забирается по лестницам и собирает разные предметы. Одними из самых известных и любимых игр этого типа являются "Супер Марио" и "Супер Мит Бой". Мы будем создавать нечто похожее! Наш герой сможет двигаться влево и вправо, прыгать, и стоять на платформах. А в будущем мы сможем добавить ему еще больше способностей! Для создания нашей игры мы будем использовать специальную библиотеку под названием Pygame. Это как волшебная коробка с инструментами, которая поможет нам оживить наши идеи и превратить их в настоящую игру! Важное замечание: Мы
Оглавление

Привет, юные программисты и любители приключений!

Ты когда-нибудь мечтал создать свою собственную компьютерную игру? Такую, где герой прыгает по платформам, собирает монетки и сражается с монстрами? Сегодня я расскажу тебе, как можно сделать такую игру самостоятельно, используя язык программирования Python!

Что такое платформер?

Начнем с самого начала — что же такое "платформер"? Это такой тип игр, где главный герой прыгает по разным платформам, перепрыгивает через пропасти, забирается по лестницам и собирает разные предметы. Одними из самых известных и любимых игр этого типа являются "Супер Марио" и "Супер Мит Бой".

Мы будем создавать нечто похожее! Наш герой сможет двигаться влево и вправо, прыгать, и стоять на платформах. А в будущем мы сможем добавить ему еще больше способностей!

Волшебная библиотека Pygame

Для создания нашей игры мы будем использовать специальную библиотеку под названием Pygame. Это как волшебная коробка с инструментами, которая поможет нам оживить наши идеи и превратить их в настоящую игру!

Важное замечание: Мы будем использовать Python версии 2.x, потому что с версией 3.x могут возникнуть некоторые проблемы при запуске нашей игры.

Шаг 1: Создаем окно для нашей игры

Первым делом нам нужно создать окошко, в котором будет происходить всё действие нашей игры. Вот как это сделать:

python#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Импортируем нашу волшебную библиотеку Pygame
import pygame
from pygame import *

# Задаем размеры окна
WIN_WIDTH = 800
# Ширина окна
WIN_HEIGHT = 640
# Высота окна
DISPLAY = (WIN_WIDTH, WIN_HEIGHT)
# Объединяем ширину и высоту в одну переменную
BACKGROUND_COLOR = "#004400"
# Цвет фона (в данном случае - темно-зеленый)

def main():
pygame.init()
# Запускаем волшебство Pygame
screen = pygame.display.set_mode(DISPLAY)
# Создаем окошко
pygame.display.set_caption("Супер Марио Бой")
# Пишем название в шапку окна
bg = Surface((WIN_WIDTH, WIN_HEIGHT))
# Создаем поверхность для фона
bg.fill(Color(BACKGROUND_COLOR))
# Заливаем фон зеленым цветом

while 1:
# Основной цикл игры (будет работать вечно, пока мы не закроем игру)
for e in pygame.event.get():
# Проверяем все события (нажатия клавиш, мыши и т.д.)
if e.type == QUIT:
raise SystemExit, "QUIT"
# Если нажали крестик - выходим из игры

screen.blit(bg, (0, 0))
# Рисуем фон на экране
pygame.display.update()
# Обновляем экран, чтобы увидеть изменения

if __name__ == "__main__":
main()

Когда ты запустишь этот код, ты увидишь окно с зеленым фоном. Это будет полем, на котором будут происходить все приключения нашего героя!

Шаг 2: Создаем уровень с платформами

Теперь нам нужно создать уровень, по которому наш герой будет бегать и прыгать. Для этого мы используем специальный способ описания уровня с помощью символов:

python# Добавим новые константы для платформ
PLATFORM_WIDTH = 32
# Ширина платформы
PLATFORM_HEIGHT = 32
# Высота платформы
PLATFORM_COLOR = "#FF6262"
# Цвет платформы (красноватый)

# И добавим этот код внутрь функции main(), перед основным циклом
level = [
"-------------------------",
# Каждый символ "-" будет платформой
"- -",
# А каждый пробел будет пустым местом
"- -",
"- -",
"- -- -",
"- -",
"-- -",
"- -",
"- --- -",
"- -",
"- -",
"- --- -",
"- -",
"- ----------- -",
"- -",
"- - -",
"- -- -",
"- -",
"- -",
"-------------------------"]

Это наш уровень, нарисованный с помощью символов! Символ "-" означает платформу, а пробел - пустое место. Это как карта сокровищ, только для нашей игры!

Теперь нам нужно добавить код, который будет рисовать эти платформы на экране. Добавим его в основной цикл после screen.blit(bg, (0, 0)):

pythonx = y = 0 # Начальные координаты
for row in level:
# Перебираем каждую строку уровня
for col in row:
# Перебираем каждый символ в строке
if col == "-":
# Если это символ платформы
# Создаем платформу, заливаем её цветом и рисуем
pf = Surface((PLATFORM_WIDTH, PLATFORM_HEIGHT))
pf.fill(Color(PLATFORM_COLOR))
screen.blit(pf, (x, y))

x += PLATFORM_WIDTH
# Двигаемся вправо для следующего символа
y += PLATFORM_HEIGHT
# Переходим на следующую строку
x = 0
# Возвращаемся в начало строки

Теперь, если запустить игру, мы увидим зеленое поле, обрамленное красными платформами. Но нам нужен герой, который будет бегать по этим платформам!

Шаг 3: Создаем нашего героя

Наш герой будет особенным — он должен уметь двигаться влево и вправо, а также прыгать. Создадим для него отдельный файл player.py:

python#!/usr/bin/env python
# -*- coding: utf-8 -*-

from pygame import *

MOVE_SPEED = 7
# Скорость передвижения героя
WIDTH = 22
# Ширина героя
HEIGHT = 32
# Высота героя
COLOR = "#888888"
# Цвет героя (серый)

class Player(sprite.Sprite):
def __init__(self, x, y):
sprite.Sprite.__init__(self)
self.xvel = 0
# Скорость движения по горизонтали
self.startX = x
# Начальная позиция X
self.startY = y
# Начальная позиция Y
self.image = Surface((WIDTH, HEIGHT))
# Создаем поверхность для героя
self.image.fill(Color(COLOR))
# Заливаем героя цветом
self.rect = Rect(x, y, WIDTH, HEIGHT)
# Создаем прямоугольник для проверки столкновений

def update(self, left, right):
if left:
self.xvel = -MOVE_SPEED
# Если нажали "влево", двигаемся влево

if right:
self.xvel = MOVE_SPEED
# Если нажали "вправо", двигаемся вправо

if not(left or right):
# Если ничего не нажато, стоим на месте
self.xvel = 0

self.rect.x += self.xvel
# Изменяем позицию героя

def draw(self, screen):
# Рисуем героя на экране
screen.blit(self.image, (self.rect.x, self.rect.y))

Теперь вернемся к нашему основному файлу и добавим героя. Перед определением уровня добавим:

pythonfrom player import Player # Импортируем нашего героя

hero = Player(55, 55)
# Создаем героя на позиции (55, 55)
left = right = False
# По умолчанию не двигаемся

Также необходимо добавить проверку нажатия клавиш в обработчик событий:

pythonif e.type == KEYDOWN and e.key == K_LEFT:
left = True
if e.type == KEYDOWN and e.key == K_RIGHT:
right = True

if e.type == KEYUP and e.key == K_RIGHT:
right = False
if e.type == KEYUP and e.key == K_LEFT:
left = False

И сразу после рисования уровня добавим:

pythonhero.update(left, right) # Обновляем позицию героя
hero.draw(screen)
# Рисуем героя

Но наш герой перемещается слишком быстро! Добавим ограничение скорости игры. После определения уровня добавим:

pythontimer = pygame.time.Clock() # Создаем таймер

И в начало основного цикла добавим:

pythontimer.tick(60) # Ограничиваем скорость до 60 кадров в секунду

Шаг 4: Добавляем гравитацию и прыжки

Наш герой умеет бегать, но он завис в воздухе и не может прыгать. Давай добавим гравитацию и возможность прыгать!

В файле player.py добавим новые константы:

pythonJUMP_POWER = 10 # Сила прыжка
GRAVITY = 0.35
# Сила притяжения

В метод __init__ добавим:

pythonself.yvel = 0 # Скорость вертикального движения
self.onGround = False
# Стоим ли мы на земле

Изменим метод update, добавив возможность прыгать:

pythondef update(self, left, right, up, platforms):
if up:
if self.onGround:
# Прыгаем только если стоим на земле
self.yvel = -JUMP_POWER

if left:
self.xvel = -MOVE_SPEED

if right:
self.xvel = MOVE_SPEED

if not(left or right):
self.xvel = 0

if not self.onGround:
# Если не на земле, падаем
self.yvel += GRAVITY

self.onGround = False
# Перед проверкой столкновений считаем, что не на земле

self.rect.y += self.yvel
# Двигаемся по вертикали
self.collide(0, self.yvel, platforms)
# Проверяем столкновения по вертикали

self.rect.x += self.xvel
# Двигаемся по горизонтали
self.collide(self.xvel, 0, platforms)
# Проверяем столкновения по горизонтали

Теперь добавим метод collide, который будет проверять столкновения с платформами:

pythondef collide(self, xvel, yvel, platforms):
for p in platforms:
if sprite.collide_rect(self, p):
# Если есть столкновение с платформой

if xvel > 0:
# Если движемся вправо
self.rect.right = p.rect.left
# Останавливаемся

if xvel < 0:
# Если движемся влево
self.rect.left = p.rect.right
# Останавливаемся

if yvel > 0:
# Если падаем
self.rect.bottom = p.rect.top
# Останавливаемся на верхушке платформы
self.onGround = True
# Теперь мы на земле
self.yvel = 0
# Останавливаем падение

if yvel < 0:
# Если прыгаем вверх
self.rect.top = p.rect.bottom
# Ударяемся о низ платформы
self.yvel = 0
# Останавливаем прыжок

В основном файле мы также должны изменить некоторые вещи.

Добавим переменную для прыжка:

pythonup = False # По умолчанию не прыгаем

Добавим проверку нажатия клавиши "вверх":

pythonif e.type == KEYDOWN and e.key == K_UP:
up = True

if e.type == KEYUP and e.key == K_UP:
up = False

Шаг 5: Создаем блоки для платформ

Сейчас наши платформы просто рисуются на экране, но не взаимодействуют с героем. Давай создадим для них отдельный класс в новом файле blocks.py:

python#!/usr/bin/env python
# -*- coding: utf-8 -*-

from pygame import *

PLATFORM_WIDTH = 32
PLATFORM_HEIGHT = 32
PLATFORM_COLOR = "#FF6262"

class Platform(sprite.Sprite):
def __init__(self, x, y):
sprite.Sprite.__init__(self)
self.image = Surface((PLATFORM_WIDTH, PLATFORM_HEIGHT))
self.image.fill(Color(PLATFORM_COLOR))
self.rect = Rect(x, y, PLATFORM_WIDTH, PLATFORM_HEIGHT)

Теперь изменим наш основной файл, чтобы использовать этот класс. Импортируем его:

pythonfrom blocks import Platform

Перед определением массива level добавим:

pythonentities = pygame.sprite.Group() # Группа всех объектов
platforms = []
# Список платформ
entities.add(hero)
# Добавляем героя в группу всех объектов

Заменим код создания платформ:

pythonif col == "-":
pf = Platform(x, y)
# Создаем платформу
entities.add(pf)
# Добавляем её в группу всех объектов
platforms.append(pf)
# Добавляем в список платформ

Теперь вместо вызова hero.draw(screen) мы будем рисовать все объекты сразу:

pythonentities.draw(screen) # Рисуем все объекты

И не забудьте изменить вызов метода update для героя, добавив новые параметры:

pythonhero.update(left, right, up, platforms)

Шаг 6: Делаем игру красивее с помощью картинок

Серые и красные прямоугольники не очень красивы. Давай заменим их на настоящие картинки!

Для начала заменим платформы. В файле blocks.py заменим строку:

pythonself.image.fill(Color(PLATFORM_COLOR))

На:

pythonself.image = image.load("blocks/platform.png") # Загружаем картинку платформы

Убедись, что у тебя есть папка "blocks" с файлом "platform.png" внутри!

Теперь сделаем нашего героя анимированным. Для этого нам понадобится библиотека pyganim. Добавим анимации в файл player.py:

pythonimport pyganim # Импортируем библиотеку для анимации

# Добавим константы для анимации
ANIMATION_DELAY = 0.1
# Скорость смены кадров
ANIMATION_RIGHT = ['mario/r1.png', 'mario/r2.png', 'mario/r3.png', 'mario/r4.png', 'mario/r5.png']
ANIMATION_LEFT = ['mario/l1.png', 'mario/l2.png', 'mario/l3.png', 'mario/l4.png', 'mario/l5.png']
ANIMATION_JUMP_LEFT = [('mario/jl.png', 0.1)]
ANIMATION_JUMP_RIGHT = [('mario/jr.png', 0.1)]
ANIMATION_JUMP = [('mario/j.png', 0.1)]
ANIMATION_STAY = [('mario/0.png', 0.1)]

В метод __init__ добавим создание анимаций:

pythonself.image.set_colorkey(Color(COLOR)) # Делаем фон прозрачным

# Анимация движения вправо
boltAnim = []
for anim in ANIMATION_RIGHT:
boltAnim.append((anim, ANIMATION_DELAY))
self.boltAnimRight = pyganim.PygAnimation(boltAnim)
self.boltAnimRight.play()

# Анимация движения влево
boltAnim = []
for anim in ANIMATION_LEFT:
boltAnim.append((anim, ANIMATION_DELAY))
self.boltAnimLeft = pyganim.PygAnimation(boltAnim)
self.boltAnimLeft.play()

self.boltAnimStay = pyganim.PygAnimation(ANIMATION_STAY)
self.boltAnimStay.play()
self.boltAnimStay.blit(self.image, (0, 0))
# По умолчанию стоим

self.boltAnimJumpLeft = pyganim.PygAnimation(ANIMATION_JUMP_LEFT)
self.boltAnimJumpLeft.play()

self.boltAnimJumpRight = pyganim.PygAnimation(ANIMATION_JUMP_RIGHT)
self.boltAnimJumpRight.play()

self.boltAnimJump = pyganim.PygAnimation(ANIMATION_JUMP)
self.boltAnimJump.play()

Теперь изменим метод update, чтобы показывать нужную анимацию:

pythonif up:
if self.onGround:
# Прыгаем только с земли
self.yvel = -JUMP_POWER
self.image.fill(Color(COLOR))
self.boltAnimJump.blit(self.image, (0, 0))

if left:
self.xvel = -MOVE_SPEED
self.image.fill(Color(COLOR))
if up:
# Для прыжка влево есть отдельная анимация
self.boltAnimJumpLeft.blit(self.image, (0, 0))
else:
self.boltAnimLeft.blit(self.image, (0, 0))

if right:
self.xvel = MOVE_SPEED
self.image.fill(Color(COLOR))
if up:
self.boltAnimJumpRight.blit(self.image, (0, 0))
else:
self.boltAnimRight.blit(self.image, (0, 0))

if not(left or right):
# Стоим
self.xvel = 0
if not up:
self.image.fill(Color(COLOR))
self.boltAnimStay.blit(self.image, (0, 0))

Шаг 7: Создаем камеру, которая следует за героем

Сейчас наш уровень ограничен размером окна. Давай сделаем камеру, которая будет следовать за героем, и мы сможем создавать уровни любого размера!

Добавим в основной файл класс камеры:

pythonclass Camera(object):
def __init__(self, camera_func, width, height):
self.camera_func = camera_func
self.state = Rect(0, 0, width, height)

def apply(self, target):
return target.rect.move(self.state.topleft)

def update(self, target):
self.state = self.camera_func(self.state, target.rect)

Добавим функцию для настройки камеры:

pythondef camera_configure(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
l, t = -l+WIN_WIDTH / 2, -t+WIN_HEIGHT / 2

l = min(0, l)
# Не двигаемся дальше левой границы
l = max(-(camera.width-WIN_WIDTH), l)
# Не двигаемся дальше правой границы
t = max(-(camera.height-WIN_HEIGHT), t)
# Не двигаемся дальше нижней границы
t = min(0, t)
# Не двигаемся дальше верхней границы

return Rect(l, t, w, h)

Создадим экземпляр камеры перед основным циклом:

pythontotal_level_width = len(level[0])*PLATFORM_WIDTH # Вычисляем ширину уровня
total_level_height = len(level)*PLATFORM_HEIGHT
# Вычисляем высоту уровня

camera = Camera(camera_configure, total_level_width, total_level_height)
# Создаем камеру

Теперь изменим отрисовку объектов в основном цикле:

pythoncamera.update(hero) # Центрируем камеру относительно героя

for e in entities:
screen.blit(e.image, camera.apply(e))
# Рисуем все объекты с учетом смещения камеры

Теперь мы можем сделать наш уровень больше:

pythonlevel = [
"----------------------------------",
"- -",
"- -- -",
"- -",
"- -- -",
"- -",
"-- -",
"- -",
"- ---- --- -",
"- -",
"-- -",
"- -",
"- --- -",
"- -",
"- -",
"- --- -",
"- -",
"- ------- ---- -",
"- -",
"- - -",
"- -- -",
"- -",
"- -",
"----------------------------------"]

Заключение: твоя первая игра готова!

Вот и всё! Теперь у тебя есть собственная игра-платформер, где герой может бегать, прыгать и стоять на платформах. Весь мир игры следует за героем благодаря камере.

Ты можешь добавить в игру много всего интересного:

  • Монеты, которые герой будет собирать
  • Врагов, которых нужно избегать или побеждать
  • Разные типы платформ (например, движущиеся)
  • Ловушки и препятствия
  • Новые уровни
  • Звуки и музыку

Главное, не бойся экспериментировать и пробовать новые идеи! Программирование игр — это увлекательное и творческое занятие, которое развивает логическое мышление и творческие способности.

Удачи тебе в мире программирования и создания игр, юный разработчик! 🚀