Я все-же начал писать игру [Part1]
Оглавление
Предисловие
Всем привет! Последнее время я искал, чем себя занять и решил таки попробовать написать игру. Так уж получилось что я не программист, хотя и учился на инженера-программиста, но после ВУЗа пошел по другой ветке развития, а программирование осталось как хобби. Но при всем при этом за все время максимум, что я писал были всякие тетрисы, морские бои и другие не сильно обремененные геймплеем и механиками игры. Каждый раз, когда я хотел написать какую-нибудь бродилку, я наталкивался на стену продумывания механик и отсутствия возможности сделать нормальную графику. Так как я, к сожалению, далёк от геймдизайна и даже чувак с «корованами» имел явно большую фантазию — мне было тяжеловато, а невозможность сделать нормальную графику подталкивало к очередной консольной поделке. В итоге несколько раз я начинал и несколько раз почти сразу бросал эту затею. Но сейчас решил, что всё же стоит попробовать позаниматься этим чуть дольше чем один вечер. И дальше я расскажу что получилось.
Хочется отметить тот факт, что игру я стал писать не ради денег и не ради получения опыта. Мне хотелось просто устроить марафон программирования, изобретать велосипеды, сооружать костыли, рефакторить и радоваться каждой удачной идее. Хотелось просто для себя пройти тот путь, который люди проходили на заре становления компьютерных игр. Постараться делать большинство вещей самостоятельно, не прибегая к каким-либо готовым решениям. Поэтому я решил отказаться от каких-либо движков. Взял питон, а в качестве визуальной оболочки — PyQT, библиотеку по отрисовке оконных приложений. Там можно рисовать джипеги из файлов. Пока, думаю, хватит и этого.
С графикой я тоже решил не запариваться слишком сильно, поэтому открыл www.pixilart.com и выбрал в качестве базового для себя шаблон 15х15 пикселей (не спрашивайте почему, просто так решил). 15 пикселей это замечательно. Я не умею в пиксель арт, а при разрешении например 32х32 пришлось бы уже что-то уметь. В любом случае позднее можно будет легко перерисовать все ассеты в более приемлемом качестве или стилистике.
Я сел и начал думать
Итак, что же я решил сделать: 2д игру, пошаговую (пока), вид сверху, но не изометрия (пока). Стилистика - пиксель арт т.к. "а что еще я могу"? Сеттинг — средневековье/фэнтези (подземелья, сундуки, магия, и вот это вот всё). Попытаться реализовать самые базовые идеи: герой, монстры, дроп, характеристики, шмотки, что-нибудь еще… На этом мои идеи закончились. Еще минута раздумий без дела и я бы это всё бросил. Поэтому…
Я сел и начал писать
Описал класс Game. Кучу вспомогательных функций и самую главную tick которая будет выполняться каждый ход, пересчитывая все игровые события.
Описал класс DungeonLevel. Он будет хранить список объектов и сам уровень и в общем-то больше ничего мне пока не надо. Я решил что уже на этом этапе можно начинать что-то загружать из файла, а не хардкодить. Поэтому по классике изобразил карту 10х10 вырисовывая ее единичками и ноликами в блокноте. Так можно быстро менять уровни и добавлять необходимые для отладки элементы. В коде загрузки уровня просто прописал что 1 — это стена, а 0 — пол.
Описал основной игровой объект GameObject и его свойства: проходимость и перемещаемость. Докинул координаты и скорость по двум осям. Наследовал от него Wall и Floor и вписал каждому отдельный спрайт. От игрового объекта получил игрока Player. Ему уже понадобились параметры направления взгляда (по факту не ради взгляда, а чтобы визуально отображать куда игрок направлен и для нахождения объектов для взаимодействия). Прописал кнопки управления и назначил на них движение.
В принципе на этом этапе уже можно выпускать игрока на карту и радоваться жизни, биться лбом о стены и радоваться их непроходимости.
Следующий адекватный объект (после игрока, стен и пола) который я решил реализовать — это дверь. Всегда актуально, всегда эффективно. Дверь ограничивает пространство, а еще может быть заперта ключом или просто закрыта на читос. Значит еще необходим и объект «ключ» которым можно было бы такие двери открывать.
Уже тут всё завертелось, закружилось, так как если есть ключ — его нужно как-то и куда-то поднять, значит у игрока должен быть инвентарь… а у объектов — свойство item (объект подбираемый). Главное по началу не сильно углубляться в детали: )
Потратив некоторое время я сделал и дверь, и ключ, и инвентарь…
В дальнейшем я перерисовал все спрайты на более визуально приятные. Чуть привык к рисованию по пикселям и периодически когда надоедало залипать в код — переключался и рисовал какой-нибудь спрайт. Это оказалось не менее залипательно.
Вообще вся специфика моей разработки заключалась в реализации необходимого минимума для поставленной микроцели с небольшим обдумыванием на пару моментов вперед. Именно поэтому в последствии я постоянно добавляю объектам новые свойства, что в конечном счете приводит к переписыванию некоторых уже имеющихся решений, зато порой это приводит к более интересным реализациям, что положительно сказывается на визуальном восприятии кода.
Что же получилось в целом
Итак, чтобы не описывать все мои приключения с объектами и типами данных, скажу, что же готово на данный момент:
- Уровни грузятся из текстового файла. Пока очень условно. Думаю потом перевести на json, должно быть интересно.
- Камера следует за игроком (уровень не ограничен видимой областью)
- У игрока и некоторых объектов есть инвентарь из которого при желании может выпадать лут. А игрок при желании может выбрасывать что-нибудь из инвентаря на пол.
- Игра пока имеет два статуса: в игре и в инвентаре. В инвентаре можно копаться по панели из пяти предметов. Юзать их либо выбрасывать.
- Реализованы зачатки каких-либо уведомлений. Это или просто надписи при использовании объектов или чтение записок.
- Реализованы зачатки скриптов при попадании объекта в область действия. Есть скрипт условия и скрипт при срабатывании условия.
Объекты которые уже реализовал
Стены, пол, дверь с замком под конкретный ключ. Ключ под конкретный замок
Пики точёные. Срабатывают по зашитому паттерну. Отнимают какое-то кол-во хп.
Банки лечения. Пока только лечение. Но потом конечно добавлю и бафы, и резисты и всё остальное.
Ящики. Их можно пинать. В некоторых может находиться лут.
Записки на стенах — записки на стенах.
Записка подбираемая - ну как же без записочек в игре? История же! ЛОР! Возможно, в будущем они получат какое-то развитие.
Удалось реализовать нажимную плиту. Это объект, который триггерит отдельный скрипт на нажатие и на «отжатие».
Есть целый один NPC который пока не умнее ящика. Просто стоит. Поэтому и спрайт я ему нарисовал подходящий:
Декоративные объекты — просто спрайты по сути с возможностью задания проходимости/непроходимости.
Лестница: игрок может перемещаться между уровнями. По факту лестница указывает на конкретный уровень и конкретную лестницу на нем. Потом нужно будет сделать телепорты и чуть расширить сложность объекта.
Заключение и планы на будущее
В заключении покажу как это сейчас примерно выглядит если совместить это всё вместе:
Мне было вполне себе интересно это делать и возможно я потрачу еще некоторое время и реализую что-нибудь еще.
Примерный список планов который может измениться в любую минуту:
Адекватный редактор уровней
- Новые ловушки/интерактивные объекты (если придумаю)
- Базовая диалоговая система («да/нет/сарказм» мне более чем подойдет)
- Дневник персонажа (привет Morrowind)
- Монстры (тут уже сложнее т.к. надо будет систему агрессивности и зачатки ИИ писать)
- Там где монстры — там пойдёт сразу урон, защита, оружие.
- Придётся сделать куклу персонажа и вещи влияющие на характеристики
- Попробую добавить источники света и освещение…
- Скорее всего буду перерисовывать какие-то спрайты
Вот такие вот мысли вслух. Оставайтесь на связи. И возможно, если я не заброшу эту затею через пару дней, в будущем появится еще один пост с прогрессом.