Как сделать столкновение в pygame
Перейти к содержимому

Как сделать столкновение в pygame

  • автор:

pyGame столкновение спрайтов

Пишу на Python.
Такая проблема,
Есть два квадрата двигающиеся навстречу друг другу,первый квадрат 10×10 второй 60×60.
Нужно проверить когда маленький квадрат коснется большого.Делаю так:

class Sprite: def __init__(self,xpos,ypos,filename): self.x=xpos self.y=ypos self.bitmap=image.load(filename) def set_position(self,xpos,ypos): self.x=xpos self.y=ypos def render(self): screen.blit(self.bitmap,(self.x,self.y))

функция для проверки:

def collSprite(s1_x,s1_y,s2_x,s2_y,size1,size2): if (s1_x <(s2_x+size1+size2)) and (s1_x >(s2_x-size1)) and ($ return 1 else: return 0
first=Sprite(0,100,'data/1.png')#маленький квадрат second=Sprite(200,100,'data/2.png')

и в цикле после увелечения координат квадратов делаю проверку:

if collSprite(first.x,fisrt.y,second.x,second.y,10,60): print('Bang!')

Это вырезка из кода на самом деле создается два массива из таких квадратов которые движутся навстерчу друг другу,этот алгоритм работает,но почему через раз.
Может кто предложит более изящный вариант?

#1
21:33, 13 ноя 2010

def collSprite(s1_x,s1_y,s2_x,s2_y,size1,size2): if (s1_x <(s2_x+size1+size2)) and (s1_x >(s2_x-size1)) and ($ return 1 else: return 0

Ты не написал всю процедуру. Посмотри здесь как правильно двигать спрайт и создавать анимацию.

  • Funny_Sailor
  • Постоялец

#2
14:26, 14 ноя 2010

Прошу прощения,криво вставилась,вот полный код функции проверки столкновения:

def collSprite(s1_x,s1_y,s2_x,s2_y,size1,size2): if (s1_x <(s2_x+size1+size2)) and (s1_x >(s2_x-size1)) and (s1_y > (s2_y - size1)) and (s1_y < (s2_y+size1+size2)): return 1 else: return 0

Спасибо за статью.теоретические знания почерпнул :)

Я пишу на Python.

Двигаю спрайты просто увлечением координат в цикле.

Прошло более 4 лет
#3
23:50, 5 июля 2015

Столкновения в pygme можно реализовать и с помощью контейнера grupe и метода pygame.sprite.spritecollide. Этот способ хорошо использовать когда нужно найти столкновения нескольких объектов с каким то одним: blocks_hit_list = pygame.sprite.spritecollide(player, block_list, False) мы получим список с спрайтом( из списка block_list), который столкнулся с спрайтом "player" - подробно тут-http://programmingnew.my1.ru/blog/urok_7_zakhvat_dvizhushhegosja_… 2015-06-28-11

Если у вас спрайты не симметричны(т.е. ширина не равна высоте). то полный скрипт функции столкновения можно представить так:
def Intersect(x1,x2,y1,y2,w1,w2,h1,h2):# ----функция столкновения
if (x2x1-w2) and (y2y1-h2):
return 1
else:
return 0
где w1,w2- ширины
h1,h2 - высоты объектов

разные варианты взаимодействий. отскока и столкновений объектов видела тут http://programmingnew.my1.ru/blog

#4
23:58, 5 июля 2015

Изображение

Nikelen

Как сделать столкновение в pygame

В этом листке-проекты мы создадим и визуализируем модель двумерного газа. Также мы поставим над этим газом некоторые эксперименты: посмотрим на броуновское движение, диффузию и т.п.

pygame

Делать визуальную модель мы будем при помощи библиотеки pygame. Для того, чтобы её установить, нужно выполнить команду pip install pygame --user в anaconda prompt или терминале. В Windows с большой вероятностью команда потерпит неудачу из-за отсутсвия компилятора языка C. Поэтому можно сразу отправиться на страницу собранных для windows пакетов и скачать оттуда подходящий whl -файл (в имени pygame‑1.9.4‑cp36‑cp36m‑win_amd64.whl 36 — это версия питона 3.6, win32/win_amd64 — это битность ОС). Дальше для установки пакета нужно будет из anaconda prompt или терминала выполнить команду вида
pip install "Y:\path\to\whl\pygame‑1.9.4‑cp36‑cp36m‑win_amd64.whl" --user
и дело в шляпе!

Библиотека pygame достаточно обширная, но нам от неё будет нужно не слишком много. Почти всё, что нужно, это — рисование элементарных фигур. Остальное вы будете делать руками.

Пример программы на pygame с шариками

from random import randint, uniform import pygame import sys SCREEN_SIZE = WIDTH, HEIGHT = (600, 400) # Готовим 100 шариков в случайных местах случайного радиуса и цвета N = 100 circs = [ < 'xy': [uniform(0, WIDTH), uniform(0, HEIGHT)], 'r': randint(2, 10), 'color': [randint(0, 255), randint(0, 255), randint(0, 255)] >for __ in range(N)] circs.sort(key=lambda circ: -circ['r']) # Сортируем, чтобы большие не заслоняли маленьких # Немного pygame-магии pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE) fps = pygame.time.Clock() # Обновляем коодинаты всех шариков def update(): for circ in circs: circ['xy'][0] += uniform(-5, 5) / circ['r'] circ['xy'][1] += uniform(-5, 5) / circ['r'] # Чистим экран и отрисовываем каждый шарик def render(): screen.fill((0, 0, 0)) # Заливаем всё чёрным for circ in circs: pygame.draw.circle(screen, circ['color'], list(map(int, circ['xy'])), circ['r'], 0) pygame.display.update() fps.tick(60) # Не обновляем экран чаще, чем 60 раз в секунду # Главный цикл: пока на нажали крестик обновляем и отрисовываем while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() update() render()

A: Прямолинейное движение

Модифицируйте программу так, чтобы все круги двигались прямолинейно со случайными скоростями, зафиксированными на момент старта.

B: Отскоки от стен

Сделайте так, чтобы шарики из предыдущей задачи отскакивали от стенок:

Упругое столкновение двух шаров на плоскости

Пусть масса первого шарика — $m_1$, радиус — $r_1$, его скорость до столкновения — $\vec = (v_, v_)$, скорость после столкновения — $\vec = (w_, w_)$. А ещё обозначим через $\vec$ вектор от точки контакта шаров до центра первого шара. Для второго шарика всё то же самое, только с индексом 2. Тогда закон сохранения момента требует, чтобы $$ m_1 \vec + m_2 \vec = m_1 \vec + m_2 \vec.$$ Закон сохранения энергии требует, чтобы $$ \frac + \frac = \frac + \frac. $$ Закон сохранения момента импульса более хитрый. Он требует, чтобы $$ [\vec, m_1\vec] + [\vec, m_2\vec] = [\vec, m_1\vec] + [\vec, m_2\vec]. $$ Всё вместе это даёт систему из 4 уравнений на 4 неизвестных — $x$- и $y$-компоненты новых скоростей шариков.

К счастью, если массы и радиусы шаров равны, то решать эту систему не потребуется. Перейдём в систему отсчёта первого шарика. В ней он покоится, а второй шарик натыкается на него со скоростью $\vec-\vec$. После столкновения вся часть этой скорости, направленная вдоль линии центров, достанется первому шарику, а ортогональная ей — второму. То есть после столкновения первый шар полетит вдоль линии центров, а второй — в направлении касательной.

Чтобы доказать это, пригодится система отсчёта общего центра масс, двигающая со скоростью $\dfrac+m_2\vec>=\dfrac+\vec>$. Центр масс в ней неподвижен. Дальше попробуйте разобраться сами.

C: Столкновения — 1: все шарики одинаковы

Реализуйте столкновение одинаковых шаров. Алгорим, работающий за время $O(n^2)$, где $n$ — число шаров, подойдёт.

D: Столкновения — 2: одинаковые массы

Реализуйте столкновение шаров разного радиуса, но одинаковой массы. Алгорим, работающий за время $O(n^2)$, где $n$ — число шаров, подойдёт.

E: Столкновения — 3: общий случай

Рассчитайте столкновение шаров произвольного радиуса и произвольной массы. Можно либо решить систему уравнений (сложно), либо предварительно дополнительно пошаманить с системами отсчёта (станет проще), либо ещё подумать и сразу написать ответ без решения системы.

  • масса первого шара $m_1$,
  • масса второго шара $m_2$,
  • пара чисел — скорость первого шара $\vec$,
  • пара чисел — скорость второго шара $\vec$,
  • пара чисел — координаты вектора из точки контакта в центр первого шара $\vec$,
  • пара чисел — координаты вектора из точки контакта в центр второго шара $\vec$.

Вычислите скорости первого и второго шара после их упругого столкновения.

1.0 1.0 10.0 0.0 -10.0 0.0 -1.0 0.0 1.0 0.0
-10.0 0.0 10.0 0.0
99.0 1.0 10.0 0.0 -10.0 0.0 -9.0 0.0 1.0 0.0
9.6 0.0 29.6 0.0

100 100 -5.944050560528412 -8.564544641233914 -3.126256984519088 7.602630729293933 0.6381731882506756 9.98254824345279 -0.6381731882506472 -9.982548243452786

-4.903238699022251 7.716231190674263 -4.167068846025249 -8.678145102614243

900 100 6.275207281781148 1.8525669980804769 -2.4707106152583087 12.334611148103816 -15.828382139122077 25.495324853000263 5.276127379707354 -8.49844161766675

4.849142448095183 4.149579154894633 10.36387288791537 -8.338498263223586

F: Столкновения — 4: общий случай

Реализуйте столкновение шаров произвольного радиуса и произвольной массы.

G: Броуновское движение

Сделайте модель броуновского движения.

H: Перегородки

Добавьте возможность расположить в поле произвольное количество прямолинейных перегородок. От них шарики-молекулы тоже должны отскакивать. Границы «сосуда» теперь можно сделать из этих перегородок.

I: Диффузия газов

Сделайте «сосуд», состоящий из двух одинаковых камер. В перегородке между камерами должно быть маленькое отверстие. В левую камеру поместите «горячие» красные молекулы. В правую камеру поместите очень-очень холодные синие молекулы. Проведите несколько экспериментов: с разной разницей «температур» и разным размером отверстия.

J: Сопло ракетного двигателя

В этом эксперименте мы будем изучать сопло ракетного двигателя. Сам двигатель в этой задаче — это просто квадрат с маленьким отверстием, смотрящим направо. Внуть квадрата нужно поместить много-много очень-очень горячих молекул. В этом эксперименте можно отключить взаимодействия молекул друг с другом, оставив только взаимодействия со стенками. После того, как половина молекул вылетет из «двигателя», симуляцию нужно остановить и посчитать среднюю проекцию вылетевших молекул на ось $Ox$ (так как только эта часть момента нужна ракете). Попробуйте приделать к отверстию «сопло», для начала просто рупор. И сравнить результат. Попробуйте объяснить, почему это происходит.

K: Сопло Лаваля

Попробуйте «изобразить» сопло Лаваля и провести эксперимент из предыдущей задачи для него. Скорее всего, ничего интересного не получится, но вдруг? Это было бы очень круто 🙂

L: Распределение Максвелла

Вернёмся к обычному «ящику» с молекулами. Отрисовывайте на каждом кадре распределение молекул по модулю скоростей. Да-да, график придётся рисовать «руками» по пикселям. Изучите типичные скорости в вашем газе. Разбейте диапазон от 0 до максимальной скорости на, скажем, 100 частей. Посчитайте для каждой, сколько молекул имеют модуль скорости из этой части. И нарисуйте соответствующую гистрограмму. Изучите её вид при разной «температуре» газа.

M: Атмосфера

Добавьте в высокий-высокий ящик гравитацию. Разбейте правую стенку сосуда, скажем, на 100 частей. Для каждой посчитайте «давление». И нарисуйте гистрограмму.

Как сделать столкновение в pygame

�� Самоучитель по Python для начинающих. Часть 21: Основы разработки игр на Pygame

�� Самоучитель по Python для начинающих. Часть 21: Основы разработки игр на Pygame

import pygame import random pygame.init() screen_width = 600 screen_height = 600 screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("Змейка") green = (0, 255, 0) red = (255, 0, 0) font = pygame.font.SysFont("Arial", 20) clock = pygame.time.Clock() # основные параметры игры cell_size = 20 snake_speed = 5 snake_length = 3 snake_body = [] for i in range(snake_length): snake_body.append(pygame.Rect((screen_width / 2) - (cell_size * i), screen_height / 2, cell_size, cell_size)) snake_direction = "right" new_direction = "right" apple_position = pygame.Rect(random.randint(0, screen_width - cell_size), random.randint(0, screen_height - cell_size), cell_size, cell_size) game_over = False while not game_over: for event in pygame.event.get(): if event.type == pygame.QUIT: game_over = True elif event.type == pygame.KEYDOWN: if event.key == pygame.K_UP and snake_direction != "down": new_direction = "up" elif event.key == pygame.K_DOWN and snake_direction != "up": new_direction = "down" elif event.key == pygame.K_LEFT and snake_direction != "right": new_direction = "left" elif event.key == pygame.K_RIGHT and snake_direction != "left": new_direction = "right" # новое направление движения snake_direction = new_direction # управление змейкой if snake_direction == "up": snake_body.insert(0, pygame.Rect(snake_body[0].left, snake_body[0].top - cell_size, cell_size, cell_size)) elif snake_direction == "down": snake_body.insert(0, pygame.Rect(snake_body[0].left, snake_body[0].top + cell_size, cell_size, cell_size)) elif snake_direction == "left": snake_body.insert(0, pygame.Rect(snake_body[0].left - cell_size, snake_body[0].top, cell_size, cell_size)) elif snake_direction == "right": snake_body.insert(0, pygame.Rect(snake_body[0].left + cell_size, snake_body[0].top, cell_size, cell_size)) # проверяем, съела ли змея яблоко if snake_body[0].colliderect(apple_position): apple_position = pygame.Rect(random.randint(0, screen_width - cell_size), random.randint(0, screen_height-cell_size), cell_size, cell_size) snake_length += 1 if len(snake_body) > snake_length: snake_body.pop() # проверка столкновения со стенами if snake_body[0].left < 0 or snake_body[0].right >screen_width or snake_body[0].top < 0 or snake_body[0].bottom >screen_height: game_over = True # проверка столкновения с собственным телом for i in range(1, len(snake_body)): if snake_body[0].colliderect(snake_body[i]): game_over = True screen.fill((0, 0, 0)) # рисуем змейку for i in range(len(snake_body)): if i == 0: pygame.draw.circle(screen, green, snake_body[i].center, cell_size / 2) else: pygame.draw.circle(screen, green, snake_body[i].center, cell_size / 2) pygame.draw.circle(screen, (0, 200, 0), snake_body[i].center, cell_size / 4) # рисуем яблоко pygame.draw.circle(screen, red, apple_position.center, cell_size / 2) # выводим количество яблок score_text = font.render(f"Съедено яблок: ", True, (255, 255, 255)) screen.blit(score_text, (10, 10)) pygame.display.update() clock.tick(snake_speed) pygame.quit() 

Подведем итоги

Мы рассмотрели самые простые приемы разработки игр в Pygame – возможности этой библиотеки намного обширнее. К примеру, для быстрой разработки в Pygame используются спрайты – объекты для определения свойств и поведения игровых элементов. Встроенные классы Group , GroupSingle и RenderUpdates позволяют быстро, просто и эффективно группировать, обновлять и отрисовывать игровые элементы.

В следующей главе будем изучать работу с SQL и базами данных .

  1. Особенности, сферы применения, установка, онлайн IDE
  2. Все, что нужно для изучения Python с нуля – книги, сайты, каналы и курсы
  3. Типы данных: преобразование и базовые операции
  4. Методы работы со строками
  5. Методы работы со списками и списковыми включениями
  6. Методы работы со словарями и генераторами словарей
  7. Методы работы с кортежами
  8. Методы работы со множествами
  9. Особенности цикла for
  10. Условный цикл while
  11. Функции с позиционными и именованными аргументами
  12. Анонимные функции
  13. Рекурсивные функции
  14. Функции высшего порядка, замыкания и декораторы
  15. Методы работы с файлами и файловой системой
  16. Регулярные выражения
  17. Основы скрапинга и парсинга
  18. Основы ООП: инкапсуляция и наследование
  19. Основы ООП: абстракция и полиморфизм
  20. Графический интерфейс на Tkinter
  21. Основы разработки игр на Pygame
  22. Основы работы с SQLite
  23. Основы веб-разработки на Flask
  24. Основы работы с NumPy
  25. Основы анализа данных с Pandas

Материалы по теме

  • ����️ Как написать игру на Python: 5 игровых движков
  • �� Пишем Тетрис на Python с помощью библиотеки Pygame

Как создать простую игру «Змейка» на Python и Pygame

Как создать простую игру «Змейка» на Python и Pygame

Игра «Змейка» существует уже почти 50 лет. За это время программисты успели разработать множество модификаций для разных платформ. В этой статье подробно разбираем процесс создания игры на Python с помощью библиотеки Pygame.

Освойте профессию
«Python-разработчик»

История

Прообраз классической «Змейки» появился в 1976 году в виде игры Blockade для аркадных автоматов. В нее могли играть сразу два пользователя, каждому из которых надо было передвигать по игровому полю длинную фигуру, похожую на змею. Фигура отставляла за собой шлейф, в который другому игроку нельзя было врезаться. Если все же врезаться, то игра начиналась снова, а проигрывал тот, кто первым совершит шесть столкновений с противником.

Интерфейс игры Blockade-змейка в 1976

После этого разработчики начали выпускать свои версии «Змеек» и сформировали отдельный жанр игр, в котором змея передвигается по полю и собирает объекты. За более чем 50 лет на свет вышли «Змейки» с разными правилами и режимами игры. В одних версиях направление змеи меняется каждый раз, когда она собирает объект, в других игроку приходится управлять сразу двумя змейками и следить, чтобы они не соприкасались друг с другом.

Python-разработчик
Освойте Python, самый популярный язык программирования
3 690 ₽/мес 6 150 ₽/мес

dffsdd (3)

Инструменты

Разрабатывать игру будем на Python с помощью открытого набора модулей Pygame, который построен на мультимедийной библиотеке Simple DirectMedia Layer (SDL). Pygame содержит в себе все необходимые модули для разработки игр на Python, включая работу с графикой, воспроизведение звука, управление с клавиатуры, взаимодействие с вибрацией и акселерометром. Готовые игры можно собирать под разные платформы, включая мобильный Android. Код Pygame открыт и опубликован на GitHub, поэтому более опытные разработчики могут присоединиться к развитию проекта. Из дополнительных инструментов понадобится редактор кода на Python. Чаще всего разработчики выбирают бесплатный редактор Visual Studio Code от Microsoft или полноценную среду разработки Pycharm от JetBrains. Visual Studio Code — полностью бесплатный редактор кода, доступный для Windows, macOS и Linux. Специальную версию VS Code можно запускать в браузере. Вначале компания позиционировала редактор в качестве инструмента для веб-разработки. После релиза магазина расширений появилась возможность адаптировать VS Code практически под любые современные технологии. Редактор поддерживает подсветку синтаксиса, запуск кода и отладку. Скачать установочный файл можно на официальном сайте проекта. PyCharm — полноценная среда разработки на языке Python. Включает в себя все необходимые инструменты для создания, отладки и тестирования приложений. Возможности среды можно расширять плагинами. Если с помощью VS Code можно писать код на нескольких языках, то в PyCharm есть полноценная поддержка только Python, а для других языков JetBrains выпускает отдельные среды. PyCharm доступна на Windows, macOS и Linux. Пользователи могут выбрать между бесплатным и ограниченным выпуском Community Edition или полноценным Professional с ежемесячной подпиской. Для проекта «Змейки» хватит бесплатной версии.

Установка библиотек

Установка Python 3

Сперва надо убедиться, что на компьютере установлен язык программирования Python 3. Для этого в терминале следует ввести команду python3 —version. В случае успеха система выведет номер установленной версии. Если в терминале появится ошибка или сообщение о том, что команда python3 не найдена, то Python надо будет установить. Для macOS и Linux это можно сделать с помощью одной команды в том же окне терминала.

macOS

На macOS установить Python можно из репозитория Homebrew. Сам Homebrew можно установить по инструкции с официального сайта. После этого в терминале следует ввести команду brew install python3 и дождаться завершения операции. В конце можно еще раз ввести python3 —version и убедиться, что установка прошла успешно.

Linux

В Linux установка Python производится с помощью команды sudo apt install python3. Этого хватит для автоматического скачивания актуальной версии.

Windows

В Windows язык программирования Python доступен в фирменном магазине приложений Microsoft Store. Для установки надо перейти по ссылке на страницу пакета и нажать кнопку «Получить», а затем — «Установить». Для корректной работы следует перезагрузить компьютер. Библиотека Pygame устанавливается из репозитория PyPI с помощью пакетного менеджера Pip. Он загружается вместе с Python, поэтому для установки Pygame достаточно выполнить в терминале команду pip install pygame. Если Python и Pygame уже установлены, то следует скачать редактор кода. Можно выбрать любой удобный из предложенных выше, перейти на его официальный сайт и пройти процесс установки.

Станьте разработчиком на Python и решайте самые разные задачи: от написания кода до автоматизации процессов

Дизайн

Цвета для дизайна «Змейки»

В больших студиях над играми работает множество отделов: сценаристы, режиссеры, дизайнеры, программисты, художники, тестировщики и другие высококвалифицированные специалисты. Мы разрабатываем проект в одиночку, поэтому задачи целой студии ложатся на наши плечи. Перед тем как начинать писать код, надо определиться с дизайном нашей «Змейки». Сейчас есть огромное количество вариантов этой классической игры, но мы повторим тот, который был популярен на заре зарождения жанра. Экраны тогда были монохромными, и разработчики не могли использовать обилие цветов. Мы тоже возьмем ограниченную палитру в зеленых оттенках, которая хорошо знакома по игровой консоли Game Boy от Nintendo. Всего в проекте будем использовать четыре цвета. Их коды в форматах RGB и Hex указаны на изображении.

Правила

  • игрок управляет змеей, которая собирает объекты на поле;
  • повороты змеи возможны на 90 градусов;
  • при каждом запуске змейка появляется в случайном месте игрового поля;
  • каждый собранный объект увеличивает длину змейки на один блок;
  • столкновение змеи со своим телом или границей игрового поля приводит к проигрышу;
  • игроку надо как можно дольше продержаться и собрать как можно больше объектов.

Управление реализуем с помощью клавиш WASD. Такая схема управления уже успела стать стандартом в разработке игр, поэтому пользователям не надо будет привыкать к специфическим кнопкам.

Разработка

Весь процесс разработки игры разобьем на шаги, чтобы было легче погружаться в Pygame и удобнее отслеживать процесс появления новых функций. Как выглядит готовый код игры на Python, можно посмотреть в конце статьи.

Шаг 1 — создаем новый проект и импортируем библиотеки

Для начал необходимо создать новый проект в редакторе кода. Будем рассматривать все на примере PyCharm, но все операции в таком же порядке можно проделать и в VS Code.

Для начала запускаем среду разработки и выбираем пункт меню File → New Project. В открывшемся меню указываем имя проекта и задаем директорию хранения файлов. В нашем случае проект называется snake, а все файлы хранятся в стандартной папке. Остальные пункты меню можно оставить по умолчанию.

Создание проекта игры в Python

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

  • Pygame — для доступа к основным модулям Pygame;
  • Randrange — для выбора случайного числа из заданного диапазона.
# Импортируем библиотеки import pygame as pg from random import randrange

Шаг 2 — задаем константы и инициализируем объекты

Некоторые переменные будут постоянными во всем проекте — константами. К ним будут относиться размер окна в пикселях и частота кадров (frame per second, FPS). Зададим их сразу после импорта библиотек. Важно отметить, что среди разработчиков Python константы принято писать заглавными буквами, а если в названии содержится больше одного слова, то отделять их следует символом нижнего подчеркивания. К примеру, некоторые названия констант могут выглядеть как HEIGHT или MAIN_COLOR .

В проекте «Змейки» на Python будут следующие константы:

  • WINDOW — размер окна, равный 1000 пикселей;
  • FPS — частота кадров, равная 60 кадрам в секунду.
# Константы WINDOW = 1000 FPS = 60

Теперь можно проинициализировать объекты игры. Сперва создадим объект экрана с помощью вызова функции set_mode модуля display . Функция set_mode принимает три аргумента: размер окна, флаги дополнительных параметров и глубину цвета. Последние два аргумента можно опустить и задать позже. В нашем случае создадим окно размером 1000×1000 пикселей. У нас уже есть константа размера окна, поэтому просто умножим ее на два: [WINDOW] * 2 . Также сразу же инициализируем объект, который поможет нам задать частоту обновления экрана.

# Инициализация объектов gameScreen = pg.display.set_mode([WINDOW] * 2) clock = pg.time.Clock()

Шаг 3 — создаем окно игры

Мы сделали все необходимое для того, чтобы нарисовать на экране компьютера окно нашей «Змейки». Перед этим важно отметить, что игры на Pygame работают в рамках бесконечного цикла, который существует до тех пор, пока пользователь его не закроет. В этом цикле находятся уже другие циклы и условия, предназначенные для реализации управления, обновления экрана и отрисовки объектов.

Создадим такой цикл while True , сразу же в нем установим ограничение частоты кадров, использовав константу FPS :

# Главный цикл игры while True: # Частота обновления экрана clock.tick(FPS)

Теперь мы хотим получать события и обрабатывать их. Создадим для этого цикл for . В нем будем отслеживать действия пользователя и реагировать на них. Сразу же пропишем обнаружение закрытия окна с помощью условия if event.type == pg.QUIT — если объект Pygame закрывается, то мы закрываем игровое окно.

После этого воспользуемся функцией fill() и закрасим ранее созданный экран самым светлым цветом из палитры. Это позволит поверх разместить более темную змейку и объекты, которые она будет собирать. Цвет укажем в RGB-формате. В конце добавим функцию обновления экрана flip() .

# Цикл обработки событий for event in pg.event.get(): if event.type == pg.QUIT: exit() gameScreen.fill((155, 188, 15)) pg.display.flip()

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

Окно для игры «Змейка» на Python

Шаг 4 — создаем змейку

Наша змейка должна как-то передвигаться по игровому полю, для этого ей понадобятся координаты. В коде уже есть константа WINDOW S, обозначающая размер одной стороны окна; значит теперь мы сможем задать константу TILE_SIZE для размера стороны одной плитки сетки и после задать сразу всю сетку. Далее с помощью кортежа поместим в константу RANGE разметку всего поля. Так мы сможем задавать змейке координаты для передвижения и спауна объектов.

Координаты и размеры шага для игры «Змейка» на Python

TILE_SIZE = 50 RANGE = (TILE_SIZE // 2, WINDOW - TILE_SIZE // 2, TILE_SIZE)

Теперь создадим функцию, которая определяет координаты случайной плитки на игровом поле. Вспомним из школы, что координаты на плоскости задаются с помощью двух значений — по оси X и Y. Поэтому наша функция должна находить два таких значения, основываясь на данных о разметке поля.

Обозначим лямбда-функцию get_random_position() и с помощью константы RANGE получим координаты X и Y. Префиксная запись символа звездочки (*) перед RANGE означает, что мы хотим передать в функцию randrange() все элементы кортежа. Мы не знаем, сколько их там хранится, можем заранее посчитать и сохранить количество в отдельную переменную, а можем просто воспользоваться префиксной записью перед константой и доверить это дело Python.

# Функция для определения координат (X:Y) случайной позиции на игровом поле get_random_position = lambda: [randrange(*RANGE), randrange(*RANGE)]

Убедимся, что get_random_position() каждый раз дает нам случайные координаты. Вызовем функцию и посмотрим на вывод:

> [825, 175] > [925, 925] > [725, 825] > [25, 175] > [325, 625]

Теперь у нас есть все необходимое для того, чтобы задать параметры змейки и нарисовать ее на экране. Для начала создадим переменную snake, в которой определим голову змеи с помощью экземпляра класса Rect() , который в Pygame отвечает за обозначение прямоугольных областей. В качестве параметров в конструктор класса следует передать координаты X и Y, высоту и ширину. Сразу после зададим случайную позицию головы змеи на сетке игрового поля с помощью функции get_random_position() .

Теперь нам надо создать переменные для хранения длины змеи и всех ее сегментов. Для этого создадим переменную length со значением 1 и список segments , в который поместим первый сегмент.

# Параметры змейки snake = pg.rect.Rect([0, 0, TILE_SIZE - 2, TILE_SIZE - 2]) snake.center = get_random_position() length = 1 segments = [snake.copy()]

Перейдем в цикл обработки событий и отобразим змейку на экране. В качестве цвета возьмем второй зеленый оттенок из определенной ранее палитры. Зададим его в RGB-формате.

[pg.draw.rect(gameScreen, (120, 149, 12), segment) for segment in segments]

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

Варианты появления змейки в случайном месте на игровом поле

Шаг 5 — управляем змейкой

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

  • W — движение вперед;
  • A — движение влево;
  • S — движение назад;
  • D — движение вправо.

Для начала перейдем к части кода, в которой до этого задавали параметры змейки, и добавим новую переменную snake_dir . В ней будем хранить координаты головы змеи. Зададим значение (0, 0).

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

# Обработка нажатий WASD if event.type == pg.KEYDOWN: if event.key == pg.K_w: snake_dir = (0, -TILE_SIZE) if event.key == pg.K_s: snake_dir = (0, TILE_SIZE) if event.key == pg.K_a: snake_dir = (-TILE_SIZE, 0) if event.key == pg.K_d: snake_dir = (TILE_SIZE, 0)

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

# Управляем змейкой snake.move_ip(snake_dir) segments.append(snake.copy()) segments = segments[-length:]

Сейчас можно запустить код и попробовать поуправлять змейкой. Важно отметить, что в Pygame есть неприятная особенность. Если задать в коде управление на латинской раскладке, то библиотека будет обрабатывать только нажатие латинских клавиш. Поэтому необходимо переключить язык на английский. Исправить это можно с помощью добавления кода для обработки клавиш в Unicode, но в этом проекте мы просто будем следить за раскладкой.

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

time = 0 time_step = 110

После этого модифицируем часть кода с управлением:

# Управляем змейкой time_now = pg.time.get_ticks() if time_now - time > time_step: time = time_now snake.move_ip(snake_dir) segments.append(snake.copy()) segments = segments[-length:]

Шаг 6 — добавляем еду для змейки

У нас уже есть змейка, и мы даже можем ей управлять. Теперь на игровом поле должны появляться объекты еды, которые змейка будет собирать и увеличиваться. Сам объект еды идентичен по размерам с головой змеи и также появляется в случайном месте экрана. Поэтому создадим переменную food с копией головы змеи и назначим ей случайную точку для появления с помощью функции get_random_position() :

# Параметры объектов еды food = snake.copy() food.center = get_random_position()

Отобразим еду на экране так же, как это делали со змеей. В качестве цвета возьмем самый темный из обозначенной палитры:

# Рисуем объект еды pg.draw.rect(gameScreen, (15, 56, 15), food)

При запуске кода хорошо видно, что голова змеи и еда всегда появляются в случайных местах на игровом поле:

Варианты появления еды для змейки на игровом поле

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

# Поедание if snake.center == food.center: food.center = get_random_position() length += 1

Шаг 7 — определяем столкновения

Сейчас змейка может передвигаться, поедать объекты и увеличиваться в длину, но пока в игре нет определения столкновений. У игрового поля есть границы, а в правилах мы обозначали, что при пересечении границ игра будет завершаться. В этом шаге добавим отслеживание столкновений.

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

# Столкновение с границами if snake.left < 0 or snake.right >WINDOW or snake.top < 0 or snake.bottom >WINDOW: snake.center, food.center = get_random_position(), get_random_position() length, snake_dir = 1, (0, 0) segments = [snake.copy()]

Также змейка может столкнуться со своим телом. В этом случае игра тоже должна завершиться. Для этого создадим переменную snake_collision, в которой будем определять, пересекается ли хоть один прямоугольник тела змеи с ее головой. Воспользуемся готовой функцией collidelist() класса Rect из Pygame. А после добавим переменную в условие проверки столкновения с границами:

# Столкновение с границами и телом змейки snake_collision = pg.Rect.collidelist(snake, segments[:-1]) != -1 if snake.left < 0 or snake.right >WINDOW or snake.top < 0 or snake.bottom >WINDOW or snake_collision: snake.center, food.center = get_random_position(), get_random_position() length, snake_dir = 1, (0, 0) segments = [snake.copy()]

В итоге у нас получилась классическая игра «Змейка» на Python и Pygame. Мы научились рисовать объекты на экране, менять их параметры, управлять ими с помощью клавиатуры и обрабатывать события в игровом цикле.

Весь код игры с комментариями занимает всего 78 строк:

# Импортируем библиотеки import pygame as pg from random import randrange # Константы WINDOW = 1000 FPS = 60 TILE_SIZE = 50 RANGE = (TILE_SIZE // 2, WINDOW - TILE_SIZE // 2, TILE_SIZE) # Функция для определения координат (X:Y) случайной позиции на игровом поле get_random_position = lambda: [randrange(*RANGE), randrange(*RANGE)] # Параметры змейки snake = pg.rect.Rect([0, 0, TILE_SIZE - 2, TILE_SIZE - 2]) snake.center = get_random_position() length = 1 segments = [snake.copy()] snake_dir = (0, 0) # Параметры времени и задержки time = 0 time_step = 110 # Параметры объектов еды food = snake.copy() food.center = get_random_position() # Инициализация объектов gameScreen = pg.display.set_mode([WINDOW] * 2) clock = pg.time.Clock() # Главный цикл игры while True: # Частота обновления экрана clock.tick(FPS) # Цикл обработки событий for event in pg.event.get(): if event.type == pg.QUIT: exit() # Обработка нажатий WASD if event.type == pg.KEYDOWN: if event.key == pg.K_w: snake_dir = (0, -TILE_SIZE) if event.key == pg.K_s: snake_dir = (0, TILE_SIZE) if event.key == pg.K_a: snake_dir = (-TILE_SIZE, 0) if event.key == pg.K_d: snake_dir = (TILE_SIZE, 0) gameScreen.fill((155, 188, 15)) # Столкновение с границами и телом змейки snake_collision = pg.Rect.collidelist(snake, segments[:-1]) != -1 if snake.left < 0 or snake.right >WINDOW or snake.top < 0 or snake.bottom >WINDOW or snake_collision: snake.center, food.center = get_random_position(), get_random_position() length, snake_dir = 1, (0, 0) segments = [snake.copy()] # Поедание if snake.center == food.center: food.center = get_random_position() length += 1 # Рисуем объект еды pg.draw.rect(gameScreen, (15, 56, 15), food) # Рисуем змейку [pg.draw.rect(gameScreen, (120, 149, 12), segment) for segment in segments] # Управляем змейкой time_now = pg.time.get_ticks() if time_now - time > time_step: time = time_now snake.move_ip(snake_dir) segments.append(snake.copy()) segments = segments[-length:] pg.display.flip()

Что дальше

Игру «Змейка» на Python можно продолжать улучшать и модифицировать. К примеру, в проект можно добавить следующее:

  • В игре не хватает главного меню, меню проигрыша и отображения счета. Все это можно добавить с помощью модуля pygame.font , предназначенного для работы с текстом и шрифтами. Содержимое переменной length , в которой храним длину змейки, можно выводить в углу игрового поля и обнулять при проигрыше.
  • Наша «Змейка» получилась безмолвной, и ее надо оживить звуками. Сделать это можно с помощью модуля pygame.mixer , добавив фоновую музыку, звуковые эффекты при поворотах, поедании объектов и столкновении. Так игра будет более живой и увлекательной.
  • В старых играх, а особенно в аркадных автоматах, была возможность сохранять лучшие результаты, чтобы всегда можно было понять, кого из игроков можно считать абсолютным чемпионом. В нашу «Змейку» тоже можно добавить таблицу рекордов. Для этого надо разобраться с принципами хранения данных и сортировки. К примеру, в меню можно добавить отдельное всплывающее окно с пятью лучшими результатами и имена игроков.
  • Обычная змейка довольно быстро надоедает, поэтому можно добавить несколько новых режимов. К примеру, змейка может менять направление движения каждый раз, когда съедает блок еды. А еще ей можно увеличивать скорость или добавить жизни, дающие право на ошибку.
  • Одному играть тоже скучно, поэтому можно сделать игровое поле больше и добавить на него сразу двух змеек. Управление первой настроить на клавиши WASD, а второй — на стрелки. Тогда за одним компьютером в игру смогут играть сразу два пользователя. Только важно сделать змеек разных цветов, иначе игроки будут путаться.

Python-разработчик

Освойте Python с нуля. Подготовим к трудоустройству: дадим много практики, реальные проекты для портфолио, поможем с резюме. Лучшие студенты пройдут стажировки в проектах компаний-партнеров.

Добавить комментарий

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