7

День 15. Аркадный автомат

Серия Создаю игру

Сегодня воскресенье, и я надеялся отдохнуть от новеллы. Позаниматься чем-то связанным с игростроем, но простым, чтобы это заняло минимум времени. Эх, как же я был наивен. Но обо всём по порядку.

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

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

Мой выбор после изучения истории пал на «ПЕРЕХВАТЧИК».

Такой вполне мог бы стоять где-нибудь заброшенным в библиотеке. Я даже придумал сайд-квест: герой попадает в местный музей, выполняет задание библиотекаря, за что та даёт ему банку с 15-копеечными монетами. После этого автомат можно запустить и играть. Но сначала нам нужно саму игру сделать.

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

Мой план был таким:

  1. Сделать рамку автомата (arcade_frame.png)

  2. Сделать экран монитора (arcade_screen.png)

  3. Сделать временную кнопку закрытия (или просто клик по экрану)

  4. Написать простой цикл игры: игрок (белый квадрат), враги (летят сверху)

  5. Добавить стрельбу по пробелу

  6. Добавить столкновения (игрок — враг)

  7. Добавить счёт

Чтобы ничего не напутать, я создал новый проект в Ren'Py и отдельный файл в Visual Studio, где прописал первую заглушку игры. Файл поместил в папку game нового проекта.

# ЗАГЛУШКА: экран (чёрный прямоугольник)

add Solid("#000000") xysize (1024, 768) xalign 0.5 yalign 0.5 yoffset -20

# Игровая область (пока текст)

frame:

background None

xalign 0.5

yalign 0.5

yoffset -20

xsize 1024

ysize 768

vbox:

xalign 0.5

yalign 0.5

spacing 30

text "ПЕРЕХВАТЧИК" size 60 color "#ffffff" outlines [(2, "#333", 0, 0)]

text "Тестовый экран" size 40 color "#88ff88"

text "Кликните мышкой, чтобы выйти" size 24 color "#ffffff"

# Кнопка выхода (просто текст)

textbutton "X" action Return() xalign 0.95 yalign 0.05

label test_interceptor:

scene black

"Подходите к старому игровому автомату..."

call screen interceptor_game

"Вы отошли от автомата."

return

Файл script.rpy в новом проекте я полностью почистил, оставив только две строчки.

label start:

jump test_interceptor

При запуске появился экран.

При нажатии кнопки «Начать» запустился экран игры. Пока всё работает.

Отлично! Экран появился — это прогресс. Кнопка «X» работает как выход. Но это пока лишь заглушка. Самой игры ещё нет.

Продолжаем и теперь пишем код для самолётика.

Это база. Дальше нужно добавить:

  • Движение врагов

  • Пули

  • Проверку столкновений

  • Увеличение счёта

  • Game Over

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

1. Движение игрока (влево-вправо)

if ev.type == pygame.KEYDOWN:

if ev.key == pygame.K_LEFT:

self.player_x -= 30

if self.player_x < 0:

self.player_x = 0

elif ev.key == pygame.K_RIGHT:

self.player_x += 30

if self.player_x > self.game_width - self.player_width:

self.player_x = self.game_width - self.player_width

2. Стрельба по пробелу

elif ev.key == pygame.K_SPACE:

self.shoot()

3. Появление врагов сверху

self.spawn_timer += 1

if self.spawn_timer > 30:

self.spawn_timer = 0

enemy_x = random.randint(0, self.game_width - self.enemy_width)

self.enemies.append([enemy_x, -self.enemy_height])

4. Проверка столкновений (пуля → враг)

if (bullet[0] < enemy[0] + self.enemy_width and

bullet[0] + self.bullet_width > enemy[0] and

bullet[1] < enemy[1] + self.enemy_height and

bullet[1] + self.bullet_height > enemy[1]):

self.bullets.remove(bullet)

self.enemies.remove(enemy)

self.score += 10

5. Game Over при столкновении игрока с врагом

if (enemy[0] < self.player_x + self.player_width and

enemy[0] + self.enemy_width > self.player_x and

enemy[1] < self.player_y + self.player_height and

enemy[1] + self.enemy_height > self.player_y):

self.playing = False

Вышло достаточно залипательно, но пока не работал счётчик очков.

Как выяснилось, счётчик не обновлялся, потому что Ren'Py не перерисовывал экран при изменении переменной score в классе. Нужно было явно вызывать renpy.redraw() и передавать актуальное значение счётчика в экран.

Дальше пошли мучительные исправления. Что бы я ни делал — счётчик не работал. Но когда я добавил картинки, всё каким-то чудесным образом само починилось.

Графику я начал с самолётика.

Вырезал из оригинальной игры самолётик. Правда, там он вытянутый, а у меня квадратный.

Обвёл его примерно по контуру.

И отразил.

Ну и доработал немного свой шедевр, вырезав кабину для пилота. Размер — 48×48 px.

Вражеский самолётик я перевернул и покрасил в красный. Он уже 40×40 px.

Экран автомата я пока просто сделал рандомной картинкой из интернета — проверить, работает или нет.

Ну и кнопочка выхода. Два варианта обычная и при наведении.

А вот и результат сегодняшнего дня.

Выглядит странно, но я доволен, потому что всё работает!

Спасибо за внимание. Всё, сил нет, пошёл отсыпаться 😴

Жду комментариев какой я рукожоп)

Правила сообщества

ОБЩИЕ ПРАВИЛА:

- Уважайте чужой труд и используйте конструктивную критику

- Не занимайтесь саморекламой, пишите качественные и интересные посты

- Никакой политики


СТОИТ ПУБЛИКОВАТЬ:

- Посты о Вашей игре с историей её разработки и описанием полученного опыта

- Обучающие материалы, туториалы

- Интервью с опытными разработчиками

- Анонсы бесплатных мероприятий для разработчиков и истории их посещения;
- Ваши работы, если Вы художник/композитор и хотите поделиться ими на безвозмездной основе

НЕ СТОИТ ПУБЛИКОВАТЬ:

- Посты, содержащие только вопрос или просьбу помочь
- Посты, содержащие только идею игры

- Посты, единственная цель которых - набор команды для разработки игры

- Посты, не относящиеся к тематике сообщества

Подобные посты по решению администрации могут быть перемещены из сообщества в общую ленту.

ЗАПРЕЩЕНО:

- Публиковать бессодержательные посты с рекламой Вашего проекта (см. следующий пункт), а также все прочие посты, содержащие рекламу/рекламные интеграции

- Выдавать чужой труд за свой

Подобные посты будут перемещены из сообщества в общую ленту, а их авторы по решению администрации могут быть внесены в игнор-лист сообщества.


О РАЗМЕЩЕНИИ ССЫЛОК:

Ссылка на сторонний ресурс, связанный с игрой, допускается только при следующих условиях:

- Пост должен быть содержательным и интересным для пользователей, нести пользу для сообщества

- Ссылка должна размещаться непосредственно в начале или конце поста и только один раз

- Cсылка размещается в формате: "Страница игры в Steam: URL"

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества

Недвижимость и ремонт

Теги

Популярные авторы

Сообщества