Мы с другом (а по совместительству одноклассником) решили написать курсовую работу «Танки» (самую обычную, 2D).
Однако не такие обычные, а танки в лабиринте.
В общем, все задумывалось как грандиозный и улучшенный клон одноименной флеш-игрушки.
И не будь придурком, игру можно написать за один день.
Ну, может, конфетку из этого не сделаешь, может, в ней будет много багов.
Но если вам завтра нужно показать прототип проекта, дайте клавиатуру в руки — и вперед! Изначально план был примерно такой (все написано на C#, WindowsForms, графика - GDI+, сервер - WCF):
- Разобраться в алгоритме генерации лабиринта (точнее, декомпилировать упомянутую выше флешку и скопировать оттуда код);
- Нарисуйте всё + один (пока — свой) танк;
- Заставьте танк двигаться (как и в оригинальной игре);
- Подключите службу WCF, которая будет обслуживать лабиринт клиентов;
- Добавить в сервис второй танк и синхронизацию движений между игроками;
- Добавить полет снаряда;
- Прикрепите базу данных, добавьте графику, перенесите проект из Windows Forms в WPF.
Хотя жить можно.
Забегая вперед, скажу, что это все-таки невозможно.
Мы начали не с той ноги.
Времени у нас было предостаточно – три недели, но так уж получилось (ну да, ну да, тут не надо.
), что мы сели делать это за 4 дня до дедлайна.
Почему пост называется «Как написать игру за 1 день»? Потому что мы фактически написали это за один день.
Лабиринт
Практически сразу начались трудности — как сгенерировать лабиринт? Лабиринт непрост; алгоритм «заполнитель как есть» здесь не будет работать.Это не «идеальный» лабиринт; он имеет несколько путей вокруг одного препятствия и может содержать закрытые области.
Декомпиляция оригинальной игры ничего не дала, потому что.
код был нечитаемым.
Вернее, читаемо, но то ли создатель постарался, догадавшись, что найдутся такие умельцы, как мы, то ли декомпилятор получил кривой код. Но разбираться в миллионе переменных с именами _loc2, _loc4, _loc6 и желания у меня не было.
типа того, к тому же время поджимало.
Мне пришлось думать самому.
После нескольких часов раздумий и большого количества чая в голове промелькнуло слово «рекурсия» — и алгоритм был изобретен.
В коде лабиринт был представлен двумерным массивом структур MazeCell, который, в свою очередь, имел два поля — нижнюю границу ячейки и верхнюю границу (оба поля — простые логические значения, изначально имеющие значение true).
Код, возможно, выложу чуть позже, а пока объясню суть: нужно не строить лабиринт, а ломать его.
Те.
Сначала мы определяем количество ячеек (комнат) в лабиринте и устанавливаем для них все препятствия (оба поля установлены в значение true).
Затем определяем две ячейки, где находятся наши танки.
Обязательным условием является прямой доступ из одного резервуара в другой.
На карте могут быть закрытые области, но танки должны находиться либо за их пределами, либо оба должны находиться внутри такой области.
Поэтому здесь вступает в действие рекурсия — берём ячейку правого резервуара и идём к левому, передавая в качестве параметра следующую ячейку.
Добравшись до танка, идем обратно по тому же маршруту, но на этот раз разрушая нужные стены в клетках, через которые проходим.
И, наконец, заключительный этап — мы просто бежим по лабиринту (напомню, это обычный двумерный массив) и ломаем случайные стены в случайных ячейках.
Всё, лабиринт готов, осталось его только нарисовать, настоящие мелочи! Алгоритм был реализован через пару дней.
Поэтому мы написали игру за 1 день.
Движение
Особых сложностей с рисованием не возникло, так что писать просто не о чем.В том-то и дело - движение.
Заставить танк двигаться по диагонали было не так-то просто.
Честно говоря, мы так и не дошли до этого дела.
Точнее, он движется по диагонали, но КАК он это делает, лучше не видеть.
Плюс при смене направления танк на полсекунды замирает на месте и только потом движется куда надо.
У нас не было времени или инструментов для проверки теории, но я думаю, это потому, что мы обрабатывали нажатия кнопок в событии формы.
KeyDown , хотя надо бы их ловить по таймеру.
Сервис WCF, второй танк и синхронизация движений между игроками
Вот здесь и начались проблемы.Как мы поняли позже, начинать работу нужно было именно с этой точки, а потом подстраивать под нее лабиринт, клиентов и все остальное, и вот почему.
Основная проблема — двумерный массив.
WCF не работает с двумерными массивами .
Нам пришлось изрядно покрутиться, чтобы преобразовать это чудо в List .
Ну а если бы мы решили изменить архитектуру, проще было бы сделать обычный массив.
На поиск ошибки ушло много времени, но еще больше на ее исправление.
Переписывать почти весь класс лабиринта не было ни сил, ни времени, поэтому мы просто сделали небольшую обертку, которая при необходимости разворачивала список в массив, а после сворачивала его обратно в список.
Но это еще не все — WCF полон подводных камней, на которые мы наткнулись в ходе работы.
Если вы не практикуетесь, вы обязательно их обнаружите.
Сюда входят потоки на стороне сервиса, куча разных параметров для контракта и передача пользовательских классов клиенту (Внимание! Напомню тем, кто забыл — такие классы не могут иметь методов, это исключительно контракт данных! ).
В целом, это было весело.
Теперь о координатах.
Мы решили (и правильно сделали) передавать от клиента к клиенту не весь лабиринт, а только изменяемые характеристики — координаты танков.
Танк ушёл, координаты изменились — отправляем новую позицию противнику, а его клиент сам всё перерисует. То же самое планировали сделать и со снарядами.
Доработка: База данных, Графика, WPF
Мы просидели за игрой весь день и почти всю ночь - я лег спать в 3:30 ночи, потому что.Я почти уткнулся носом в клавиатуру и ни о чем не мог думать.
Мой друг посидел еще час и тоже пошел спать.
Защита назначена на 9 часов утра.
К 3:30 мы уже почти установили клиент и запустили сервер.
Не успели добавить базу, нормальную графику и WPF. Мы представили проект? Нет. Мы слишком сильно спотыкались в сервисе, потому что… У нас мало практики в этой области, приходилось много экспериментировать, что отнимало много времени.
Но теперь мы почти эксперты в WCF. За курсовую работу нам поставили тройку, сказав, что идея очень крутая, но реализация хромает (и мы этого не отрицаем).
Но реально ли выполнить такой проект за 1 день? Да, более того.
Главное – верить в себя, как бы банально это ни звучало.
И желание творить.
За время работы мы трижды сделали «крайне маловероятное» и дважды — «невозможное».
Саму игру тоже можно считать «невозможной».
Да, мы программируем уже около двух лет (то есть учимся), но это первый проект такого масштаба.
Когда мы подали заявку, мы вообще не понимали, как писать игру.
Вернее, мы понимали, но для нас на тот момент это было невозможно.
Но если вы попытаетесь поверить в себя, даже невозможное станет возможным.
Просто это может занять немного больше времени.
К этой же «невозможности» относится и передача двумерного массива из сервиса WCF клиенту.
Да, напрямую это сделать нельзя, но всегда можно как-то выкрутиться.
А что касается «выучить C# за день»… Ну, выучить его, конечно, не получится, но в экстремальных условиях вы точно сможете быстро вникнуть в суть проблемы и набраться опыта.
За 24 часа мы проделали колоссальный объём работы и более того, это повод для моей маленькой гордости.
Тем не менее, мы сделали прототип игры, и сделали это за 1 день.
Если бы у нас было больше практических навыков, мы бы успели установить даже нормальную базу.
Негативный опыт — это тоже опыт, теперь у нас есть навыки планирования, проектирования систем и много знаний по сервисам WCF. Так что удачи вам, главное стараться и не бояться! Теги: #C++ #история #история #разработка #разработка игр #разработка веб-сайтов #.
NET #разработка игр
-
Linkmeup. Выпуск 0
19 Oct, 24 -
[Ненависть] Боль. Формат Русмарк
19 Oct, 24 -
Интересная Ошибка В Php 5.3.
19 Oct, 24 -
Особенности Общения С Роботами
19 Oct, 24