Как написать простейшую игру

Как начать писать игры

Время на прочтение
9 мин

Количество просмотров 346K

Оригинал: Starting out on Game Programming

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

Вы только что закончили ваш первый курс по С++ и хотите начать делать игры. Кто-то указал вам на этот сайт и вы, возможно, поэкспериментировали немного с руководством. Вы изучили несколько лаконичных примеров, но не нашли руководства о том, как сделать целую игру. И на то есть причина.

Руководства хороши для обучения чему-то шаг за шагом, например тому, как перемещать изображение точки по экрану. Для того чтобы собрать игру воедино, вам нужны навыки решения возникающих проблем, приобретаемые лишь с опытом. Это не то, чему можно научиться из руководств. Лучший способ научиться делать игры — это начать их делать.


Выбор проекта

Итак, с чем же начать? Проще ответить с чего начинать не стоит, а именно с больших проектов, типа полноценной 3D FPS, MMO или даже длинного платформера 16-битной эпохи. Самая распространенная ошибка начинающих разработчиков это начать с большого проекта основанного на Крутой Идее или взять проект, который кажется простым, и закончить с полузаконченной кучей спагетти-кода. Поначалу следует создавать небольшие проекты.

В ранних проектах ваша основная цель учеба, а не реализация Крутых Идей. Поддерживая проект небольшим, вы можете сфокусироваться на изучении новых техник, а не тратить кучу времени на управление кодом и рефакторинг. Несмотря на то, что ваша Крутая Идея может быть офигительно офигенной, реальность индустрии разработки такова, что чем больше проект, тем больше вероятность совершить ошибку в архитектуре. И чем больше проект, тем дороже обходится эта ошибка. Помните историю Дедала и его сына Икара? Дедал создал крылья из воска и перьев для своего сына. Он предупредил Икара не подлетать на них слишком близко к солнцу. Но Икар проигнорировал предупреждение и крылья расплавились, и тогда-то гравитация и настигла его.

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

Принимая во внимание все выше написанное, вот пара советов с чего начать.


Графика и обработка событий

Если вы никогда не программировали ничего связанного с графикой или GUI, вам следует начать с чего то маленького, чтобы «обмочить ноги». Моим первым проектом были крестики-нолики, так что даже у меня было скромное начало. Пара идей для первого проекта:

Цель вашего первого проекта перейти от консольной разработки к разработки событийных графических приложений. Он так же научит вас фундаментальным основам игровой логики и архитектуры. Я рекомендую что-нибудь пошаговое, потому что игры с движением это совсем другой зверь.

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

Есть один момент, на который я хочу указать тем, кто будет делать крестики-нолики или четыре в ряд. Не стоит сейчас сильно беспокоиться об искусственном интеллекте. Сделать игру только для двух игроков или для игры с компьютером, который делает случайные ходы вполне достаточно для начала.

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


Синхронизация, движение, столкновения, анимация

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

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

Duck Hunt и Pong — хорошие проекты для тех, кто уже имеет опыт в программировании графики и событий. В них есть простое обнаружение столкновений и все важные основы игр в реальном времени.

Space Invaders и Galaga — хороший выбор для второго/третьего проекта. В них есть уровни, поэтому вам нужно будет узнать как передвигаться от уровня к уровню, при помощи конечного автомата. Вы можете прочитать про конечные автоматы здесь(англ.). Игры в стиле «перестреляй их всех» так же требуют создать простые шаблоны поведения для врагов, что является шагом в сторону искусственного интеллекта.

Тетрис хорош для второго/третьего проекта. В нем совсем немного логики нужной для создания игры-головоломки. Это игра приличного размера, так что вам придется научиться разделять вашу программу на несколько исходных файлов, о чем вы можете больше прочитать здесь(англ.). Не недооценивайте Тетрис. Я недооценил и только посмотрите на это жуткое месиво в коде Lazy Blocks.


Переинженеринг

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

Когда я был начинающим я переинженерил AI для крестиков-ноликов. Я хотел сделать игру с непобедимым AI. Мне удалось достигнуть этого, запрограммировав компьютер на знание всех возможных ловушек. Звучит круто не правда ли? Это заняло почти 40 000 тысяч строк в основном скопированного кода и месяц моего свободного времени.
Позже я выучил структуры данных и узнал про алгоритм Минимакс, который при меньшем размере кода не только делал нужное, но еще и делал это лучше.

Так что учитесь на моих ошибках и не будьте излишне амбициозны. Концентрируйтесь на обучении тому как делать игры, а не просто делайте их.


Планирование, анализ столкновений, физика, уровни, искусственный интеллект

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

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

Теперь про вашу следующую игру. Break Out и Puzzle Bobble хороши для третьего проекта, потому что они включают в себя продвинутое распознавание столкновений и физику. Физика важна, поскольку дает игре реалистичное ощущение. Даже в Super Mario Brothers есть ощущение гравитации и инерции. Бильярд отличный проект для тех, кто хочет напрячь извилины физикой.

В играх типа бильярда вам нужно не только обнаруживать столкновения, но и обрабатывать их в определенном порядке. Обработка столкновений разительно отличается от их обнаружения. Хотя создание бильярда или 2D платформера может показаться простым делом, анализ столкновений в правильном порядке — запутанный процесс, и не должен быть недооценен.

Break out и Puzzle Bobble так же включают дизайн уровней и требуют загрузки и освобождения их ресурсов. Хорошим опытом будет создание редактора уровней для игры. Редакторы позволяют вам легко создавать уровни и не вынуждают впаивать их в приложение. У меня есть статья(англ.) про создание редактора уровней.

Так же вы возможно хотите попрактиковаться в написании искусственного интеллекта (AI). Один из вариантов — вернуться к крестикам-ноликам или четырем в ряд и написать непобедимый AI. Теперь вы уже должны знать структуры данных и сможете использовать знания о деревьях для использования алгоритма Минимакс. С этим алгоритмом вы можете просчитать все возможные исходы крестиков-ноликов и создать непобедимый AI. Забавно расстраивать им своих друзей. Так же вы возможно захотите сделать разные уровни сложности. Игра не приносит радости, если в нее нельзя выиграть.

Pac Man — отличный способ попрактиковаться в написании AI. Нужно будет знать структуры деревьев/графов и алгоритмы поиска, типа A*, для того чтобы призраки могли пройти через лабиринт. Так же нужно будет сделать чтобы призраки работали в команде. Все это пригодится когда вы будете делать игры со сложным AI, типа стратегий в реальном времени. Об основах AI можно прочитать тут(англ.).


Платформеры, Action/Adventure, RPG, RTS, движки

Теперь, когда вы получили опыт создания хорошо спланированной игры, вы готовы к созданию Action/Adventure/Платформера. Это будет кульминация графики, движения, анимации, анализа/обнаружения столкновений, физики, AI, программной архитектуры и всего остального, что вы изучите к этому моменту. Тем кто более амбициозен, можно предложить сделать стратегию в реальном времени(RTS) или ролевую игру(RPG). Будьте осторожны, потому что RPG и RTS действительно огромные проекты.

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

RTS также сложны архитектурно, а так же требуют много AI. Вам нужно будет делать поиск пути для юнитов, получение ими команд, разное поведение в зависимости от полученных команд. Если вы никогда до этого не делали AI, будет лучше начать с клона Pac Man’а для начала.

Вероятно вам впервые придется делать движок для вашей игры. Чего следует избегать, так это создания универсального движка. Создавая движок не пытайтесь сделать его подходящем для любой игры. Если ваша игра требует x, y и z, делайте движок который умеет x, y и z. Движки создают исходя из того что нужно для конкретной игры, а не из того что любой игре может потенциально понадобится.

Другая распространенная среди новичков ошибка — это попытка создать движок в качестве первого проекта. И обычно это универсальный движок. Вам не нужен движок с фантастической графикой для создания Pong’а или Space Invaders. Программируя, легко закопаться в деталях. Концентрируйтесь на общей картине и завершайте свои игры.


Сеть

Кажется все хотят сделать следующую большую MMO. Создание онлайн игр не то, во что можно быстро вникнуть. Я понял это когда попытался сделать онлайн покер сразу после завершения крестиков-ноликов.

Добавление сети значительно усложняет игру. Когда один игрок что-то делает, вы должны послать информацию об этом всем остальным. Это все равно что если бы ваша правая рука не знала о том, что делает левая. Так же вам придется выбирать между загрузкой сервера и тем что он может контролировать. Чем больше делает серверная часть, тем меньше возможностей жульничать у клиента, но это также означает большую нагрузку на сервер. Для action и других игр с высоким темпом геймплея, вам придется беспокоится о сетевой задержке и потере пакетов.

Вам следует полностью закончить хотя бы одну хорошо спланированную игру, перед тем как пробовать делать сетевую игру. В качестве первого сетевого проекта, попробуйте сделать что-нибудь, что не критично к скорости. Например простой чат-сервер/клиент будет хорошей практикой. Так же можно вернуться к крестикам-ноликам/четырем в ряд и добавить в них возможность играть в по сети. Как вариант попробуйте сделать сетевую карточную или настольную игру.

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


3D игры

Перед тем как делать 3D игры, вам следует сделать хотя бы одну хорошо спланированную игру и иметь хорошее понимание трехмерной векторной математики, линейной и Ньютоновской физики. Тут вам придется иметь дело с вершинами, текстурами, освещением, тенями, опредением взаимодействия с объектами в трехмерном пространстве, загрузку моделей и прочими сложно звучащими вещами.

Хорошая новость в том, что если вы уже сделали 4 или 5 игр, вы уже знаете основы необходимые для создания игры. Вы уже хорошо знакомы с процессом разработки и знаете свои возможности как программиста. Неважно трехмерный шутер или двухмерный, он по прежнему шутер. 2D RPG или 3D RPG по прежнему RPG.

Не считайте это оправданием пропустить 2D и сразу перейти к 3D. Прежде чем научиться бегать, нужно научиться ходить.


Быстрый способ

Говорите, что вы учитесь быстрее если сразу возьметесь за дело и будете просто писать вашу 3D MMOFPSRTSRPG и научитесь тому, что нужно по мере необходимости? Чтож, вот пару советов, которые вам помогут:

  1. Идите на местный рынок
  2. Купите целую рыбину. Рекомендую взять лосося или треску, хотя и сом тоже подойдет. Форель, кстати, тоже довольно эффективна
  3. Идите домой и включите компьютер
  4. Запустите вашу любимую IDE
  5. Теперь возьмите купленную рыбу и влупите себе по голове
  6. Повторите пункт 5, пока мысли о быстром способе не покинут вас

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


Путешествие начинается

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

  1. Выберите свой темп
  2. Доделывайте игры до конца
  3. Концентрируйтесь на обучение, а не просто на создании

Удачи вам на пути разработки игр!

Это статья для новичков в геймдеве. Для тех, кто хочет сделать игру, но не знает с чего начать.

Я постараюсь, по шагам, объяснить весь процесс от желания до релиза. Погнали!

Кто я такой?

Я гейм-дизайнер с 10-летним стажем. Работал в многих компаниях, например в Playgendary. Делал разное: и казуалки для мобилок, и танковый шутер для PC.

Теперь я инди-разработчик. Живу за счёт продажи своих игр. Выпустили 4 игры для PC и Консолей. Сейчас разрабатываю игру They Are Here: Alien Abduction Horror — хоррор от 1-го лица, про похищение пришельцами.

They Are Here: Alien Abduction Horror

Шаг 1. Запасись энтузиазмом

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

Как пополнять запас энтузиазма? Смотри документалки, читай истории успеха разработчиков. Это мотивирует!

Смотри по сторонам: на другие игры, фильмы, кино, на новые технологии. Желание изучить что-то новое или сделать что-то похожее — это то, что нужно.

Шаг 2. Собери команду или сделай всё сам!

Одному — проще. Проще придумать идею и принимать решения. Не надо спорить и описывать задачи. Сделать игру одному — возможно. Я например сделал 4 игры один.

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

Короче — есть команда, круто! Нет команды — делай всё сам, это не трудно.

Типичный инди-разработчик

Шаг 3. Сформулируй цель разработки

Очень важно понять — для чего тебе всё это?

Ну например:

1. Трудоустройство в геймдев компанию.

Продукт — портфолио. Приоритет — качество исполнения.

Вопросы: На какую должность хотим устроиться? В какую компанию(и)? Какими играми занимается компания(и)? Чему нужно научиться?

2. Научиться делать игры, освоить навык.

Продукт — опытный образец. Приоритет- новые знания.

Вопросы: Какой навык освоить? Как сделать какую-то конкретную штуку?

3. Рассказать о чём то важном.

Продукт — манифест. Приоритет — донести идею до масс.

Вопросы: Поймут ли мою идею? Как сделать продукт более массовым?

4. Сделать игру о которой мечтал.

Продукт — мечта. Приоритет — воплотить своё видение.

Вопросы: Что я хочу видеть? Чем можно пренебречь? Как закончить проект?

5. Построить свой бизнес.

Продукт — актив. Приоритет — получить доход.

Вопросы: Какие игры лучше продаются? Сколько времени займет разработка? Как сократить это время?

Цель может быть не одна. Цели могут меняться от игры к игре.

Короче — ты должен ответить на вопрос — зачем я делаю эту игру?

А рально, зачем?

Шаг 4. Вспомни, что ты умеешь или любишь

Например, я и моя жена — фанаты фильмов ужасов про пришельцев. Типа «Знаки», «Мрачные небеса», «Секретные материалы». Поэтому нам проще работать над идеями и сценарием для They Are Here

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

Тян одобряет отталкиваться от умений и увлечений

Короче — твои умения и увлечения — это твои преимущества. Учитывай их при выборе платформы, движка, жанра игры. А пока, просто подумай над этим.

Шаг 5. Выбери платформу

Если просто, то есть 2 пути: Мобилки или ПК + Консоли.

Исходя из целей и умений нужно будет выбрать что-то одно. Это разные платформы, с разными играми, аудиторией и монетизацией.

Путь 1. Мобики

Аудитория:

  • Массовая аудитория. Дети, пенсионеры, скучающие продавщицы. Это не геймеры. Всё должно быть очень понятно и просто.
  • Играют по 1 — 5 минут. В перерывах, в очередях, на работе. Чтобы «убить время».
  • Ценится простая яркая графика.
  • Упор на простой, но залипательный кор-геймплей.

Плюсы:

  • Некоторые жанры (головоломки, аркады) — наиболее просты в разработке. Можно сделать небольшой прототип (1-5 уровней) и показать его работодателю, например.
  • Не требуется красивая или сложная графика. Главное — чтобы было понятно.
  • Простой геймплей и гейм-дизайн.
  • Будет плюсом, если сам привык к мобильным девайсам и играм.

Минусы:

  • Очень. Высокая. конкуренция. Игр миллионы и почти все они — бесплатные. Игроки приходят только с рекламы. Нет рекламы — нет игроков. Нет денег.
  • Монетизация. Нужно встраивать рекламу или внутри-игровые покупки в игру. Знать куда и как. Тестировать чтобы всё это работало.
  • Аналитика. Нужно понимать что такое LTV. Почему он должен быть > чем CPI. Встраивать аналитику в игру.
  • Будь готов делать по 20 прототипов или улучшать продукт, пока LTV не станет > CPI.
  • Заработать денег небольшой команде, можно только с издателем. Я лично не знаю других путей.

Короче — мобилки, это огромный супер-маркет. На полке лежит то, что окупает рекламу. Это конкуренция рекламных бюджетов. Если хочешь заработать на мобилках, то советую делать гипер-казуалки и работать с издателем.

Если пофиг на доход — классная, лёгкая платформа.

Если решишься, узнай подробнее про:

  • Гипер-казуальные игры (всё по теме гейм-дизайна и производства).
  • Как найти издателя гипер-казуальных игр.
  • Казуальная графика.
  • Low-poly графика.
  • Казуальные игроки (сложность казуальных игр и туториалы).
  • Аналитика мобильных игр (CPI, LTV, Retention).
  • Монетизация мобильных игр.
  • Оптимизация мобильных игр.
  • Google Play и App Store. Регистрация аккаунта разработчика. Правила и рекомендации. SEO.
  • Рекламные медиаторы и сети (Iron Source, AdMob и т.п.).
  • Сервисы рыночной аналитики мобильных игр (Sensor Tower, App Annie).

Путь 2. ПК + Консоли

Аудитория:

  • Хардкорные геймеры.
  • Играют по несколько часов. Дома. Чтобы погрузиться в игру.
  • Ценится реалистичная или стильная графика.
  • Упор на интересную историю или глубокий геймплей.

Плюсы:

  • Меньше конкуренция, чем на мобилках. Особенно на консолях.
  • Легче получить игроков и отзывы.
  • Можно хорошо заработать портировав игру на консоли, с помощью издателя.
  • Не надо возится с аналитикой и монетизацией.
  • С детства понятная платформа (ПК / Консоль) и аудитория (Геймеры).
  • Аудитория любит авторские, творческие, интересные игры.
  • Будет плюсом, если сам играешь на компе или приставке.

Минусы:

  • Плохо заходят простенькие игры (головоломки, аркады). Геймеры хотят получить опыт, вжиться в роль. Залипнуть надолго. Игра не должна выглядеть как что-то на пару минут.
  • Игры дольше в производстве. Но можно хитрить — делать маленькие игры, которые выглядят как большие, а также использовать готовые ассеты.
  • Нужно поработать над интересной идеей. Найти отличительные черты (USP), которые выделят проект.
  • Нужно продумать интересную историю или геймплей.
  • Более сложный геймдизайн.
  • Большая требовательность к качеству графики.

Короче — ПК, а особенно Консоли это элитный бутик. На полке лежит то, что пользуется спросом. Это конкуренция качества. Если хочешь заработать, то сделай интересную игру, и обязательно портируй её на консоли (через издателя). Подумай как сэкономить на производстве!

Если решишься, узнай подробнее про:

  • Геймдизайн компьютерных игр.
  • Нарратив, сторителлинг.
  • Как питчить игры.
  • Фичи игры / USP.
  • Что такое вертикальный срез.
  • Steam. Регистрация аккаунта разработчика. Оформление страницы. Тэги. Правила и рекомендации.
  • Маркетинг и продвижение инди-игр на Steam (рекомендую http://howtomarketagame.com/) Как сделать крутой постер, трейлер, скриншоты, ГИФки.
  • Портирование игр на консоли.
  • Издатели игр на консолях.
  • Конкурсы и фестивали инди-игр.
  • Работа с инфлюенсерами (ютуберами, стримерами).
  • Реалистичная графика.
  • Стилизованная графика.
  • Сервисы аналитики тэгов и жанров (SteamDB, Steamspy, SteamCharts, Game Data Crunch).
  • Сервисы рассылки ключей (Keymailer, Woovit)

Шаг 6. Узнай про геймдизайн и производство игр

Интересуйся тем Как делают игры (классный подкаст в твои наушники)

Рекомендую погуглить про:

  • Игровые механики, жанры и сеттинги.
  • Геймдизайн. Есть книга Джесси Шелла, она хорошая, но большая. Можешь гуглить про конкретный жанр.
  • Кор-геймплей и Мета-геймплей.
  • Левел-дизайн. Лучше гуглить про отдельный жанр.
  • Пользовательский интерфейс (UI) в играх.
  • Ассеты и маркетплейсы.

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

Шаг 7. Выбери движок и глянь уроки

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

Про выбор движка написано много статей — погугли.

Если ты один, и не знаешь языков программирования, рекомендую Unreal Engine 4.

  • Там есть Blueprints — это визуальное программирование. Это проще чем писать код.
  • Красивый рендер «из коробки».
  • Есть большой маркетплейс с гововыми ассетами
  • Это популярный коммерчесский движок, на котором сделано очень много игр.
  • Можно сделать игру под все платформы. Можно встроить рекламу, инапы, аналитику.
  • Много уровков. Рекомендую Unreal Engine Rus
  • Классный интерфейс.
  • Куча встроенных функций.
  • Бесплатный до ляма баксов дохода.
Unreal Engine 4 Blueprints

Перед началом работы над игрой, сделай пару очень простых подделок «в стол».

Сделай змейку, пинг-понг и т.п. Пофиг на качество, пофиг на геймдизайн. Главное — попрактиковаться «на кошках», пощупать функции движка.

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

Короче — почитай про выбор движка. Потрать время на его изучие.

Шаг 8. Выбери жанр

Жанр — это твоя ниша. Жанр — это очень важно. Есть жанры, в которые никто не играет. А для некоторых нужно изучить много дополнительного материала.

Лучше выбрать жанр который:

  • Популярен на платформе. Игры этого жанра часто покупают или скачивают. Используй сайты для аналитики жанров.
  • Не слишком сложен в производстве. мморпг — не твой выбор.
  • Нравится тебе или команде. Ты разбираешься в нём или много играл в детстве.
Продажи игр в разных жанрах

Как только ты определилися с жанром — гугли всё по производству игр в этом жанре. Геймдизайн, графика, уровни, звуки. На что сделать акцент?

Поиграй в лучшие игры в этом жанре. Посмотри видео об этом жанре.

Короче — выбери жанр и узнай про него всё что можешь!

Шаг 9. Придумай идею, концепцию, USP

Идея — ядро твоей игры. Зерно, из которого вырастет проект.

Какая идея хорошая?

  • Понятная. Должна быть понятна каждому. Например, твоей маме.
  • Интересная. Уже хочется поиграть в это! Люди любят риск и новый опыт, который хотят, но не могут пережить в реальной жизни. Например GTA — это симулятор крутого парня, которым все хотят быть, но не могут.
  • Популярная. Это не артхаус, не что-то странное или специфичное. Идея обращается к понятным образам из жизни или массовой культуры.
  • Выделяющаяся. Такого раньше не было. Или было, но давно. Или в другом жанре. Или в другом стиле. Или плохо сделано.

Что поможет тебе в выборе идеи?

  • Каталог игр на твоей платформе. Смотри что популярно. Думай как это изменить, подать под другим углом. Хмм…игра про постройку железной дороги в топе. А что если, мы играем за машиниста?
  • Сайты-сервисы с аналитикой тэгов и жанров на платформе. Можно отследить популярность жанра, количество игр в нем. Можно скрестить отдельные тэги между собой.
  • Массовая культура. Фильмы, книги, комиксы, короткометражки, гифки, картинки из интернета.

Скорее всего у тебя будет рождаться много идей. Записывай их. Дай полежать. А потом выбери ту, что не даёт тебе покоя и кажется лучшей.

Когда родил идею

Про питч

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

На основе Питча, описываем концепт игры. Более развернутое описание игры на одну страничку. За кого мы играем? В чем цель? Что можно делать? Какие эмоции вызываем?

Про USP

Продумай ключевые фичи — USP, которые будут продавать твой проект. Они вытекают из твоей идеи.

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

Ключевые фичи (USP) Панка: вызывающее поведение, агрессивная музыка и странные прически.

Зацени мои USP, чувак!

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

Например, у They Are Here — это пришельцы, кукурузные поля как фильме Знаки, и НЛО.

Кароче — почитай про идею, концепцию, питч, USP игры. Сформулируй чёткое видение твоего проекта и доноси это видение до всех. Без него — всё развалится и поплывет.

Шаг 10. Составь список ассетов и задач

Ассеты — это кирпичики, из которых состоят игры.

Составь список того, что нужно сделать. Хотя-бы крупными мазками. Сделать уровнь, найти музыку, вставить персонажа. А еще надо 20 видов мечей.

Оцени время, а потом умножь его на 2. Даже если тебе кажется это глупым. Умножь его в 2 раза!

Если видишь, что проект большой — отрезай всё ненужное. Ненужное — всё, что не показывает идею. Или редко появляется на экране.

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

Прикинь, что для мобильных гипер-казуалок нужно сделать минимум 30 минут геймплея. А для ПК и Консолей, лучше сделать игру на 2 часа. Если можешь больше — круто!

Настоятельно рекомендую!

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

Шаг 11. Организуй процесс

Записывай, всё что надо сделать. Каждую мелочь. Иначе — забудешь.

Ставь задачи. Себе и команде. Рекомендую Trello (проще) или Asana (функциональнее).

Cобирай инфу по проекту в одном месте. Можно юзать доски типа “Miro” или вики типа Notion.

Если ты один, или у вас небольшая команда, не парься над большой и красивой документацией. Лучше покажи пример, начерти схему, объясни на пальцах ЧЁ НАДО сделать.

Референс — лучшее описание задачи для художника! Например, я сказал жене — хочу обложку как у Слендера, но с пришельцем. Этого — достаточно!

Собирай и храни нужную инфу. Ссылки на классные статьи. Контакты возможных партнёров. Скриншоты багов. И т.п.

Шаг 12. Сделай демку

Демо-версия / Вертикальный срез / MVP — очень близкие по смыслу понятия. Это маленький кусочек игры финального качества.

Маленькая, но качественная демка

Демо-версия решает множество задач:

  • Поможет записать видео, скриншоты, гифки
  • Покажет окупаемость мобильной игры
  • Поможет устроиться на работу
  • Ускорит набор вишлсистов в Steam
  • Получит отзывы от игроков и стримеров
  • Можно участвовать в фестивалях и конкурсах
  • Только с ней можно найти издателя.

Короче — сделай демонстрационную версию игры. Это твоя визитная карточка. Показывай её всем. Говори — я сделаю так-же, только больше.

Шаг 13. Фигачь! Прорывайся к релизу!

Не буду вдаваться в подробности о релизе. Всё зависит от игры и платформы.

Лучше дам рекомендации как дожить до релиза:

  • Не меняй идею на ходу. Сильно. По чуть-чуть можно.
  • Не начинай другие проекты. Не распыляйся. Делай, что запланировал.
  • Составь график работы. Работай над игрой постоянно. Хотя бы по 3 дня в неделю, по 2 часа в день. Больше — быстрее!
  • Надоела разработка? Поиграй в похожие игры. Посмотри похожие фильмы. Найди, что было бы круто сделать.
  • Всё равно надоела? Мечтай о релизе. Представь как это будет здорово и вечно!
  • Показывай свою работу — пиши посты, пости гифки, давай поиграть стримерам. Твоя цель — получить позитивную обратную связь. Ну или отрицательную.
  • Узнавай что-то новое про производство игр. Слушай подкасты, смотри доклады. Это мотивирует, помогает в производстве.
Будь как этот парень

Спасибо, что дочитал!

Эта статья — вводная. Тебе много предстоит узнать и загуглить на каждом шаге.

Короче — ты можешь сделать это! Реально!

Главное — желание!

Что вы делаете, когда вы играете в какую-то игру и несколько раз не можете пройти одно и то же место? Можно просто найти уже готовое прохождение. Это, конечно, здорово, но что, если вы застряли в разработке игры? Какой гайд прочитать? Так пусть наша статья станет вашим пошаговым руководством к разработке вашей первой игры, если вы все еще не начали ее писать. Если уже начали, то вам все равно не помешает прочитать наши советы — быть может, увидите что-нибудь новое.

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

01

Это была самая первая игра, причем запрограммированная для калькулятора TI-83 Plus. Позднее она была переписана автором на Java во время обучения в старших классах. Примечательно, что игра так и не была закончена.

Ко всеобщему сожалению, не доводить игры до логического конца — одна из самых распространенных проблем начинающих разработчиков. Соответственно, возникает вопрос: как повысить свою продуктивность и все-таки закончить начатый проект? Ответ прост: прочтите наше «прохождение» разработки игры.

Основные этапы

Если вы разрабатываете игру сами (а начинающие программисты обычно пишут как раз в одиночку), то процесс написания можно разделить на 4 основных этапа (или уровня, как и в играх):

  • планирование;
  • прототипирование;
  • программирование;
  • релиз.

Каждый следующий уровень в видеоигре сложнее, чем предыдущий. Здесь все также: каждый следующий этап имеет свои трудности и проблемы, с которыми вы неизбежно встретитесь. Это пошаговое руководство поможет вам не остановиться ни на одном этапе разработки игры. Мы приведем различные цитаты и мнения профессионалов, целиком прошедшие тот путь, который мы только начинаем.

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

Уровень 1: Планирование

Помните, сделав 90% игры, вы думаете, что потратили 90% своего времени. А доделывая оставшиеся 10%, вы тратите еще столько же «оставшегося» 90% времени. Составляйте план, учитывая это. — Ян Шрейбер

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

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

02

Как уже говорилось выше — уделяйте внимание деталям. Записали новую фичу для реализации? Отметьте рядом, как она будет работать, как будет влиять на игрока и непосредственно на игровой процесс. И помните, секрет успешной разработки — решать существующие проблемы, пока они не накопились.

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

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

Основная проблема первого этапа — притупить свое желание кодить и начать планировать. Написать код вы всегда сможете, для этого у вас будет целый этап. Спланируйте как можно больше аспектов вашей игры.

А боссом этого уровня являются вопросы. Просмотрите на все свои заметки и убедитесь в том, что у вас нет каких-либо непонятных пунктов: ни в используемых инструментах, ни в алгоритмах и прочем. Если же у вас действительно все вопросы решены, то вы смело можете считать, что уровень «Планирование» закончен. Но если остались непонятные аспекты — решите их, прежде чем переходить дальше.

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

Уровень 2: Прототипирование

Дизайн это процесс, а не результат. — Кристофер Симмонс

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

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

Если вы получаете удовольствие от какой-либо игры, то вы захотите поиграть в нее снова, независимо от того, сколько очков или денег вы там набрали. — Стэн Яроцки

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

Вы помните секретные телепорты в игре Super Mario Bros? Игрок мог найти хорошо спрятанные трубы, прыгнув в которые можно было пропустить несколько уровней. Так и здесь. Правда, мы не полностью пропускаем прототипирование, а совмещаем его с планированием.

03

Хотим заметить, что первые два этапа взаимозаменяемы. Быть может, вы хотите проверить основную механику вашей игры, прежде чем потратите кучу времени на детали? А может, вы хотите попробовать какую-то возможность в вашей игре? Это основные причины, почему есть смысл в том, чтобы поменять порядок первых двух этапов.

Хорошая игра — это поток интересных задач, решаемых игроком. — Брюс Шелли

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

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

Уровень 3: Программирование

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

Чтобы начать этот этап, вам стоит определиться с целевой платформой вашей игры. Будет эта игра для консолей, а, может быть, мобильная или вовсе браузерная? Определившись с платформой, выберите необходимый инструментарий и язык программирования.

На самом деле эти два шага можно выполнить в обратном порядке. Имея какую-либо среду разработки (или язык программирования), вы можете проанализировать ее возможности и решить, что вы сможете написать.

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

«Я не умею рисовать» — используй клипарт. «Я не умею создавать звуки» — ищи MIDI файлы. «Я не умею программировать» — никого это не волнует, не программируй! — Роб

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

Но вы не должны унывать! Лучшее решение этих проблем — отвлечься от проекта на несколько дней. Вы очистите ваш ум и позволите новым идеям посетить его. Также неоднократно замечено, что «утро вечера мудренее». Застряли? Не знаете как решить проблему? Ложитесь спать, а на завтрашнее утро вы, возможно, сразу поймете причину ваших неудач. Не работайте до изнеможения и не изнуряйте себя: работа над проектом должна быть в удовольствие.

Если вы пытаетесь и не можете решить действительно сложную проблему — остановитесь. Решите более простую проблему, которая выполняет те же действия, что и сложная. — Даниель Кук

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

Уровень 4: Релиз

Никогда не сдавайся. — Элис Тейлор

Наконец-то мы добрались и до релиза. Конечно же, этот уровень не такой сложный, как предыдущий, но и легкомысленно относится к нему не стоит. На этом этапе вы должны убедить людей играть в вашу игру и давать вам обратную связь (вы же хотите улучшить свой проект?). Основываясь на отзывах игроков, внесите в ваше приложение те изменения, которые сделают игру более увлекательной по вашему мнению.

Главная проблема этого этапа — критика. Всегда найдутся те, кому попросту не понравится ваша игра. Это нормально. Не стоить из-за таких людей опускать руки. Ориентируйтесь лучше на тех, кто играет в ваше приложение и предлагает вам добавить в нее новые возможности.

Начиная создавать игру, не смотрите на результаты других. Создайте то, что хотите вы. — Роб

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

Каждый разработчик когда-нибудь напишет «плохую» игру. Если вы еще не написали — напишете. Все мы напишем. — Бренда Ромеро

И помните, дорога к успеху вымощена многократными неудачами. Никогда не сдавайтесь!

Вывод

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

А теперь соберитесь и напишите свою игру!

Перевод статьи «Making Your First Game: A Walkthrough for Game Developers»

#Руководства

  • 11 окт 2018

  • 24

Как программировать игры: языки, движки и все, что нужно знать начинающему разработчику

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

 vlada_maestro / shutterstock

Евгений Кучерявый

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

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

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

  • Написать всё с нуля — сложный способ, но лучше начать с него, чтобы разобраться с языками.
  • Использовать движки — вариант полегче. Даже новичок, вооружившись мануалами из интернета, способен создать игру на одной из популярных платформ.
  • Найти заготовки — готовых шаблонов порой достаточно, чтобы выдать игру за свою, поменяв компоненты на свои.

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

Подойдут любые, от Python и C до Pascal и Java. От выбора зависит то, сколько времени уйдёт на игру и для какой платформы будет релиз. Также язык влияет на производительность.

На C++, например, пишут для любой платформы, а вот PHP или JavaScript лучше подходят для браузерных игр. Если же вы используете один из движков, то лучше вдобавок изучать C# — на нём прописывают скрипты. Главное — не недооценивать языки. Движок Unity дружит и с JavaScript, а MineCraft был написан на Java.

Среди современных выделим:

CryEngine

Crysis, Far Cry, Sniper II: Ghost Warrior.

Unreal Engine

Gears of War 4, Dead Pool, Mortal Kombat X, Tekken 7

Unity

Outlast, Assassin’s Creed: Identity, Temple Run, Deus Ex: The Fall.

Большой популярностью пользуется Unity, он рассчитан как на 2D-, так и на 3D-игры. Он подходит под разные платформы и языки. На нём создается большинство мобильных и инди-игр. Он бесплатный, но если вы зарабатываете на своих играх больше 100 тысяч долларов в год, то придётся делиться ими с разработчиками Unity.

Допустим, вы выбрали язык и движок, составили план. Что дальше? Продумайте всё от и до. В зависимости от выбранного вами пути (чистый язык или использование движка) будет отличаться и то, что вас ждёт на разных этапах разработки.

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

Физика — это то, как мир игры реагирует на действия игрока или объектов внутри мира. Вот какие могут быть физические действия:

  • ходьба;
  • езда;
  • прыжки;
  • удары;
  • выстрелы;
  • падение предметов и так далее.

Если пишете сами, то для обычного прыжка придется:

  • проверить, находится ли игрок на земле;
  • менять координату Y, чтобы игрок поднимался вверх;
  • закончить подъём через какое-то время;
  • начинать и продолжать падение до тех пор, пока под ногами игрока не окажется земля.

Не говоря уже о том, что нужно работать над анимацией всего этого.

function jump() {
If(gamer.jumpTimer >= 1) {
   gamer.y++; 
   gamer.jumpTimer --;
   } else {
      If(gamer.y >= ground.y) {
         gamer.y--;
      }
   }
}

В движках уже прописана физика, и нужно лишь подогнать её под свои нужды. Для примера:

  • Вы поместили объект в рабочую область Unity.
  • Указали, что для него нужно использовать физику.
  • При запуске игры объект упадёт.

И для этого не придётся писать код вообще — всё уже предусмотрено.

Игровая механика — это то, какими способами игрок взаимодействует с миром. Совокупность игровых механик составляет игровой процесс. Например, вы уже реализовали возможность ходьбы и прыжков. Эта игра, скорее, платформер.

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

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

  • если добавить стрельбу, то будет экшн;
  • если игрок будет безоружен, — стелс;
  • если ещё и замки нужно взламывать, то это уже головоломка или пазл.

Будучи программистом, придётся уделять много времени механике.

Раньше графика создавалась с помощью программного кода, потом придумали текстуры и спрайты, а для 3D-игр используются модели. Подготовив все текстуры и модели, нужно добавить их в игру.

В движке достаточно просто загрузить нужные файлы и прикрепить их к нужным моделям. Иначе — прописывать всё вручную, в том числе и анимацию.

Пример анимации двумерного персонажа

Для анимации 2D-объектов создаётся текстура по типу той, что на изображении выше. Она разбивается на равные части, которые сменяют друг друга. То есть игрок сначала видит первый кадр, который потом сменяется на второй, а затем на третий — это создает иллюзию движения.

Анимация в действии

Если брать 3D-модель, то используется скелетная анимация — модель как бы нанизывается на специальный каркас (скелет) с подвижными частями. Движение этих частей прописывается в коде.

На скриншоте видно, как персонаж сгибает руку в местах с точками (вершинами). Таких точек может быть очень много, если требуется сложная анимация — жесты, мимика и так далее.

Создаётся анимация так: прописываются точки координат или захватываются движения реального актера.

Первый способ сложный, но дешёвый, потому что от программиста требуется только прописать движения — сдвинуть точку A1 на координаты (50,240).

Второй проще, потому что достаточно одеть актеров в специальные костюмы с маячками, отснять это и перенести в игру. Но тут, конечно, придётся оплатить костюмы, павильон, работу операторов, постановщиков и актёров.

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

Например, если в шутере есть оружие с большим уроном, у него должна быть долгая перезарядка. Если урон маленький, перезарядка может быть быстрой. У бронированных врагов малая подвижность, а шустрые противники умирают с нескольких ударов или выстрелов.

Если геймплей предусматривает взаимодействие с NPC, то им нужно прописать модели поведения: реакцию на действия игрока, агрессивность, возможность вести диалоги или торговать.

Работа с ИИ — одна из самых сложных, потому что стоит учитывать множество ситуаций, для которых задумана реакция. Например, когда вы пытаетесь пройти в дверь, ваш компаньон обязательно должен преградить вам путь, чтобы жизнь малиной не казалась.

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

  • Персональные компьютеры.
  • Приставки.
  • Мобильные устройства.
  • Браузер.

У каждой из этих платформ своя аудитория с вполне конкретными предпочтениями. На мобильных устройствах предпочитают головоломки (2048, 94%, Cut the Rope), аркады (Subway Surf, Temple Run, Angry Birds) и казуалы (Talking Cat Tom, Kitty Kate Baby Care, Hair Stylist Fashion Salon).

На компьютерах играют в MMORPG (Lineage II, World of Warcraft, Skyrim) или шутеры (Battlefield, Call of Duty, Counter-Strike).

Приставки подходят для гонок (Need for Speed, Blur, Burnout Paradise), приключенческих игр (Assassin’s Creed, Portal, The Walking Dead) и так далее.

В браузерах собирают пазлы и строят фермы.

Конечно, можно сделать и головоломку для PS4, и гонку для браузера — никто никого не ограничивает.

Будьте готовы к тому, что ваша первая игра не станет шедевром. Но не расстраивайтесь, потому что такие проекты отлично подходят для обучения.

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

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

Участвовать

Научитесь: Профессия Разработчик игр на Unity с нуля до Middle
Узнать больше

Для работы проектов iXBT.com нужны файлы cookie и сервисы аналитики.
Продолжая посещать сайты проектов вы соглашаетесь с нашей
Политикой в отношении файлов cookie

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

— Я придумал игру, создай мне её.
— А почему ты сам её не создашь?
— Я не умею.

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

С чего начать?

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

  1. Это РПГ в средневековом стиле (банально, не правда ли? =) )
  2. Она должна быть 3D, а не 2D (тут, кстати, довольно интересно, потому как в основном весь интернет пестрит роликами с 2D играми)
  3. Вид камеры от третьго лица
  4. Характеристики изменяются сами с повышением уровня, с упором на используемое оружие.
  5. Лимит уровней — 30
  6. Предметы привязаны к уровню персонажа (персонаж четвертого уровня не сможет использовать предмет пятого уровня) 
  7. Движок, на котором всё будет работать (в моём случае это Unity: по работе с ним самое большое количество уроков на мой взгляд)

Думаю, что данный план вполне подойдёт для создания шедевра ААА класса =).

Начнём создавать шедевр

В первую очередь регистрируемся на сайте Unity, скачиваем и устанавливаем движок последней версии. Далее перевоплощаемся в человека, который совершенно ничего не знает о движке и о создании игр.

Идём в интернет и спрашиваем «как нам начать использовать Unity?».

Запускаем Unity Hub.

Выбираем NEW и далее 3D проект, пишем название и местоположение проекта.

И открывается сама программа.

И тут, наверное, знатоки начнут кидаться картошкой со словами «Зачем столько воды? Все и так это знают» НО! Материал предназначен в первую очередь для тех, кто ничего не умеет, а не для гуру геймдева =).

Дальше снова идём в интернет либо проходим туториал в самой программе, чтобы научиться основам работы с движком. Для того, чтобы воспользоваться туториалом в программе, нужно в окне Unity Hub нажать на строчку Learn и выбрать любой из проектов. Я советую пройти все уроки и посмотреть несколько роликов по созданию игр.

Как создать модели для игры?
  1. Научиться моделированию (сложно, долго, но интересно)
  2. Купить готовый пак моделей (быстро и просто, но за деньги)

Я выбрал второй вариант. Отправляемся в AssetStore. Если у вас не активировалась ваша учетная запись, повторно входим в личный кабинет. И начинаем искать подходящие паки. Я нашел то, что нужно, примерно за 3 минуты по поиску knight. В паке, помимо моделей самих персонажей, были модели окружения. Купил за 10 долларов, нажал Import, поставил все галочки, и пропала проблема, неумения моделировать. 1/4 игры готово.

Сцена

Дальше начинается самое нудное. Нужно собрать рабочую зону (scene, сцену, кому как привычнее называть).

Я привык сначала прописывать персонажей, анимацию, и прочую ненужную (очень нужную) ерунду в начале работы, а уже после того как основные механики готовы, я собираю уровень (локацию, игровую зону). Для начала давайте в сцену поставим кусок земли, на которой будет стоять наш персонаж, и начнём работать с анимацией.

Поскольку мы с вами в этом деле новички, снова лезем в интернет и смотрим, как нам поставить поверхность в игровую зону. Выбираем GameObject -> 3D Object -> Cube, после масштабируем его до простой площадки.

Далее добавляем персонажа (рыцаря, демона, ниндзю, тяночку, или кто вам больше по душе). Персонажа берем из папки Prefabs: мы уже знаем (вспоминаем, чему нас научили во вкладке Learn), что туда сохраняют полностью готовые объекты, персонажей и так далее.

И вот он, наш герой, который будет покорять всех и вся.

Анимация

Помните в рейде «Цитадель Ночи» в World of Warcraft был босс Алуриэль? Когда она произносила заклинания, то кричала «Аннигиляция, репликация, детонация, АНИМАЦИЯ!!!». Нам необходимо с криком «Анимация!» наброситься на интернет и понять, как её сделать.

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

  1. Идём на сайт www.mixamo.com
  2. Регистрируемся
  3. Получаем огромное количество анимации на все случаи жизни

Что нужно в первую очередь? По мне — так научиться ходить и бегать. Возьмём анимацию ходьбы и бега.

  • В поисковике анимации набираем walking, выбираем понравившуюся анимацию, и ставим галочку In Place
  • Далее нам нужно подгрузить FBX модель от купленного пака для того, чтобы анимация не баговала (иногда такой модели может не быть в паке, но сейчас 99% разработчиков дают модель при покупке любого пака бесплатно либо она может лежать на официальном сайте). Тыкаем на upload character и загружаем модель FBX со смешным названием Mixamo_Guy_Naked.fbx.
  • Видим, что наш FBX заменил стандартную модель миксамо, и при желании можно кастомизировать анимацию, но этого делать мы, конечно же, не будем. Меня всё устраивает. Я жмякаю кнопку Download, выбираю Frames per Second 60 — анимация ходьбы готова.
  • Проделываем туже процедуру с анимацией бега (и другими, в зависимости от того, сколько вы их хотите добавить в данный момент)

Теперь создаём папку Animation в Unity и добавляем туда нашу анимацию. Начинаем настройку.

  • Выбираем анимацию, в inspector переходим на вкладку Rig, в строке Animation Type выбираем Humanoid и тыкаем Apply.
  • Заходим во вкладку Configure, если выползет окно, нажимаем save. В первую очередь нажимаем на вкладку Head, и в строке Jaw вместо Eyebrows ставим none (на вопрос «Почему?» скажу, что у нас просто нет бровей). Далее выбираем Left Hand и в строку Little Proximal, Little Intermediate, Little Distal ставим none, далее Middle Proximal — Finger_01, Middle Intermediate — Finger_02, Middle Distal — Finger_03. Мы делаем это, потому что у нашей FBX модели есть только указательный палец, а остальные три идут как один.
  • Проделываем всё то же самое с Right Hand, пальцы там будут иметь названия Finger_011, Finger_021, Finger_031, Apply, Done.
  • Повторяем всё выше написанное с каждой новой анимацией.
  • В Inspector анимации переходим во вкладку Animation. В строке Clips выбираем mixamo.com, меняем название над Source Take на Walking, выставляем галочки напротив Loop Time, Bake into Pose(Y,XZ), Apply. С анимацией Running проделываем то же самое, НО! Не забываем поменять название на Running.
  • Создаём Animator Controller, тыкаем правой кнопкой, в диалоговом окне выбираем Create -> Animator Controller
  • Заходим в Animator Controller, тыкаем правой кнопкой Create State -> Empty, выбираем появившийся бочонок New State, Смотрим в inspector и в строке Motion выбираем анимацию ходьбы walking, добавляем второй бочонок и в нём выбираем анимацию Running. И тут я понимаю, что у меня нет анимации бездействия (стоять на месте), быстро бегу в миксамо, выбираю анимацию бездействия Idle и добавляю её в проект =)
  • Сейчас необходимо правильно объединить анимацию. Бочонок Idle должен быть первым, чтобы персонаж без действий проигрывал анимацию Idle. Тыкнем по бочонку правой кнопкой и выберем Set as Layer Default State. Как видим, он теперь стал желтый и идёт сразу после Entry. Теперь подключаем анимацию Walking и Running, используем Make Transition и протягиваем стрелочки от бочонков друг к другу.
  • И лайфхак: чтобы не было задержек между переходами анимации, заходим в настройки транзисторов (белых стрелочек) и убираем галочки Has Exit Time, жмякаем на Setting и выставляем Transition Duration(s), Transition Offset на 0.
  • Смотрим в параметры Animator — туда где написано List is Empty, нажимаем на плюсик, добавляем Bool и переименовываем его в Idle, создаем второй Bool и называем его Running.
  • Выбираем транзистор, который идёт от Idle к Running, справа в строке Conditions нажимаем плюс и добавляем Idle = false, на обратном транзисторе Idle = true. С транзисторами Idle — Walking проделываем ту же процедуру. С транзисторами Running — Walking проделываем аналогичную процедуру, но в этот раз используем параметр Running.

Вот мы и победили нашу анимацию! УРА! Теперь нам нужно подключить её к нашему персонажу. Вперед, к финишной прямой!

Выбираем персонажа, inspector, окно Animator, и в строке Controller нажимаем на кругляшок. Появится выбор, где мы и увидим нашу Animation, выбираем её и нажимаем на кнопку Play в Unity. Если вы всё сделали правильно, то сейчас должны наблюдать как ваш персонаж стоит, и у него проигрывается анимация Idle. То есть, он стоит и немного покачивается.

 С анимацией разобрались, пора включать снова человека, который ничего не умеет =)

Скрипт W A S D

Анимация у нас есть, теперь нужно заставить нашего персонажа двигаться. Покопавшись в интернете, я узнал, что можно просто добавить компонент Character Controller. Так и сделаем — тыкнем Add Component, в поиск вбиваем Character Controller и добавляем его, в строке Center выставляем Y=1 (нужно, чтобы «яйцо» покрывало всего персонажа. Если у вас получилось меньше или больше, то просто настройте его вручную).

И снова прочесав гигантской расческой интернет, я всё же нашел скрипт, который у меня заработал. Значит, пора его добавить в Unity. Жмякаем правой кнопкой, Create -> C# Script. Назовём его Move. Добавим туда такой код:

Тут код

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(CharacterController))]

public class Move: MonoBehaviour
{

public float speed = 3.0F;
public float rotateSpeed = 3.0F;
void Update()
{
float horizontal = Input.GetAxis(«Horizontal»);
float vertical = Input.GetAxis(«Vertical»);

CharacterController controller = GetComponent<CharacterController>();
transform.Rotate(0, horizontal * rotateSpeed, 0);
Vector3 forward = transform.TransformDirection(Vector3.forward);
float curSpeed = speed * vertical;
controller.SimpleMove(forward * curSpeed);

if (controller.velocity == Vector3.zero)
{
GetComponent<Animator>().SetBool(«Idle», true);
}
if (controller.velocity != Vector3.zero)
{
GetComponent<Animator>().SetBool(«Idle», false);
}
}
}

Тут я немного поясню скрипт.

Верхние четыре строчки — это подключение библиотек, public class — название скрипта. Если у Вас скрипт называется Moving или что-то в этом роде, то поменяйте название. Учтите, к регистру скрипт тоже придирчив.

public float speed = 3.0F; public float rotateSpeed = 3.0F; — это скорость персонажа, настраивается по желанию. Далее идёт подключение управления Character Controller и, соответственно, анимации.

Перетаскиваем скрипт в Inspector персонажа и проверяем. It’s ALIVE!!!!!

Но есть нюанс: поворачивается наш персонаж слишком быстро и не подключена анимация бега. Скорость поворота лечится просто — выставляем в строке Rotate Speed 0.5, и наш персонаж больше не использует чит-крутилку из CS GO. Теперь сделаем, чтобы наш персонаж все-таки побежал. Снова интернет, хотя, по мне, тут можно и логически додумать, как всё провернуть, но всё же я нашел строчку кода, чтобы всё заработало. Добавляем в наш код такую строчку

Нажмите, чтобы развернуть

if (Input.GetButtonDown(«Fire3»))
GetComponent<Animator>().SetBool(«Running», true);
else if (Input.GetButtonUp(«Fire3»))
GetComponent<Animator>().SetBool(«Running», false);

Если у Вас возникли вопросы, что такое Fire3, то ответ прост: это LShift, а проверить это можно, зайдя File->Build Setting->Player Setting->Input Manager. Эту информацию также не составило труда найти в интернете.

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

Нажмите, чтобы развернуть

if (Input.GetKey(KeyCode.LeftShift))
{
speed = 6.0f;
}
else
{
speed = 3.0f;
}

В итоге весь скрипт у нас получился такого вида

Нажмите, чтобы рассмотреть весь скрипт

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(CharacterController))]

public class Move: MonoBehaviour
{

public float speed = 3.0F;
public float rotateSpeed = 3.0F;
void Update()
{
float horizontal = Input.GetAxis(«Horizontal»);
float vertical = Input.GetAxis(«Vertical»);

CharacterController controller = GetComponent<CharacterController>();
transform.Rotate(0, horizontal * rotateSpeed, 0);
Vector3 forward = transform.TransformDirection(Vector3.forward);
float curSpeed = speed * vertical;
controller.SimpleMove(forward * curSpeed);

if (Input.GetKey(KeyCode.LeftShift))
{
speed = 6.0f;
}
else
{
speed = 3.0f;
}

if (controller.velocity == Vector3.zero)
{
GetComponent<Animator>().SetBool(«Idle», true);
}
if (controller.velocity != Vector3.zero)
{
GetComponent<Animator>().SetBool(«Idle», false);
}
if (Input.GetButtonDown(«Fire3»))
GetComponent<Animator>().SetBool(«Running», true);
else if (Input.GetButtonUp(«Fire3»))
GetComponent<Animator>().SetBool(«Running», false);
}

}

Всё проверили, всё работает, осталось только прикрепить камеру к персонажу. Без заморочек просто перетаскиваем Main Camera в нашего персонажа, далее её настраиваем как нам удобно, проверяем и празднуем ПОБЕДУ!

Заключение

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

Я считаю, что не имея никаких знаний и денег, а только немного терпения, можно самому создать свою игру. Если вас смущает покупка пака из Asset Store, то всегда можно найти бесплатные паки. Я порылся в интернете и нашел как минимум 6 ресурсов, которые их предоставляют. Советую помимо интернета начать изучение какого-либо направления гейм дева.

Все описанное в этой статье было собрано без специальных знаний с помощью интернета.

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

Логика игры

Есть игровое поле — простой прямоугольник с твёрдыми границами. Когда шарик касается стенки или потолка, он отскакивает в другую сторону. Если он упадёт на пол — вы проиграли. Чтобы этого не случилось, внизу вдоль пола летает платформа, а вы ей управляете с помощью стрелок. Ваша задача — подставлять платформу под шарик как можно дольше. За каждое удачное спасение шарика вы получаете одно очко.

Алгоритм

Чтобы реализовать такую логику игры, нужно предусмотреть такие сценарии поведения:

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

Хитрость в том, что всё это происходит параллельно и независимо друг от друга. То есть пока шарик летает, мы вполне можем двигать платформу, а можем и оставить её на месте. И когда шарик отскакивает от стен, это тоже не мешает другим объектам двигаться и взаимодействовать между собой.

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

Весь кайф в том, что мы всё это задаём один раз, а потом объекты сами разбираются, как им реагировать друг на друга и что делать в разных ситуациях. Мы не прописываем жёстко весь алгоритм, а задаём правила игры — а для этого классы подходят просто идеально.

По коням, пишем на Python

Для этого проекта вам потребуется установить и запустить среду Python. Как это сделать — читайте в нашей статье.

Начало программы

Чтобы у нас появилась графика в игре, используем библиотеку Tkinter. Она входит в набор стандартных библиотек Python и позволяет рисовать простейшие объекты — линии, прямоугольники, круги и красить их в разные цвета. Такой простой Paint, только для Python.

Чтобы создать окно, где будет видна графика, используют класс Tk(). Он просто делает окно, но без содержимого. Чтобы появилось содержимое, создают холст — видимую часть окна. Именно на нём мы будем рисовать нашу игру. За холст отвечает класс Canvas(), поэтому нам нужно будет создать свой объект из этого класса и дальше уже работать с этим объектом.

Если мы принудительно не ограничим скорость платформы, то она будет перемещаться мгновенно, ведь компьютер считает очень быстро и моментально передвинет её к другому краю. Поэтому мы будем искусственно ограничивать время движения, а для этого нам понадобится модуль Time — он тоже стандартный.

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

Запишем всё это в виде кода на Python:

# подключаем графическую библиотеку
from tkinter import *
# подключаем модули, которые отвечают за время и случайные числа
import time
import random
# создаём новый объект — окно с игровым полем. В нашем случае переменная окна называется tk, и мы его сделали из класса Tk() — он есть в графической библиотеке 
tk = Tk()
# делаем заголовок окна — Games с помощью свойства объекта title
tk.title('Game')
# запрещаем менять размеры окна, для этого используем свойство resizable 
tk.resizable(0, 0)
# помещаем наше игровое окно выше остальных окон на компьютере, чтобы другие окна не могли его заслонить
tk.wm_attributes('-topmost', 1)
# создаём новый холст — 400 на 500 пикселей, где и будем рисовать игру
canvas = Canvas(tk, width=500, height=400, highlightthickness=0)
# говорим холсту, что у каждого видимого элемента будут свои отдельные координаты 
canvas.pack()
# обновляем окно с холстом
tk.update()

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

Шарик

Сначала проговорим словами, что нам нужно от шарика. Он должен уметь:

  • задавать своё начальное положение и направление движение;
  • понимать, когда он коснулся платформы;
  • рисовать сам себя и понимать, когда нужно отрисовать себя в новом положении (например, после отскока от стены).

Этого достаточно, чтобы шарик жил своей жизнью и умел взаимодействовать с окружающей средой. При этом нужно не забыть о том, что каждый класс должен содержать конструктор — код, который отвечает за создание нового объекта. Без этого сделать шарик не получится. Запишем это на Python:

# Описываем класс Ball, который будет отвечать за шарик 
class Ball:
    # конструктор — он вызывается в момент создания нового объекта на основе этого класса
    def __init__(self, canvas, paddle, score, color):
        # задаём параметры объекта, которые нам передают в скобках в момент создания
        self.canvas = canvas
        self.paddle = paddle
        self.score = score
        # цвет нужен был для того, чтобы мы им закрасили весь шарик
        # здесь появляется новое свойство id, в котором хранится внутреннее название шарика
        # а ещё командой create_oval мы создаём круг радиусом 15 пикселей и закрашиваем нужным цветом
        self.id = canvas.create_oval(10,10, 25, 25, fill=color)
        # помещаем шарик в точку с координатами 245,100
        self.canvas.move(self.id, 245, 100)
        # задаём список возможных направлений для старта
        starts = [-2, -1, 1, 2]
        # перемешиваем его 
        random.shuffle(starts)
        # выбираем первый из перемешанного — это будет вектор движения шарика
        self.x = starts[0]
        # в самом начале он всегда падает вниз, поэтому уменьшаем значение по оси y
        self.y = -2
        # шарик узнаёт свою высоту и ширину
        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()
        # свойство, которое отвечает за то, достиг шарик дна или нет. Пока не достиг, значение будет False
        self.hit_bottom = False
    # обрабатываем касание платформы, для этого получаем 4 координаты шарика в переменной pos (левая верхняя и правая нижняя точки)
    def hit_paddle(self, pos):
        # получаем кординаты платформы через объект paddle (платформа)
        paddle_pos = self.canvas.coords(self.paddle.id)
        # если координаты касания совпадают с координатами платформы
        if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
            if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]:
                # увеличиваем счёт (обработчик этого события будет описан ниже)
                self.score.hit()
                # возвращаем метку о том, что мы успешно коснулись
                return True
        # возвращаем False — касания не было
        return False
    # обрабатываем отрисовку шарика
    def draw(self):
        # передвигаем шарик на заданные координаты x и y
        self.canvas.move(self.id, self.x, self.y)
        # запоминаем новые координаты шарика
        pos = self.canvas.coords(self.id)
        # если шарик падает сверху  
        if pos[1] <= 0:
            # задаём падение на следующем шаге = 2
            self.y = 2
        # если шарик правым нижним углом коснулся дна
        if pos[3] >= self.canvas_height:
            # помечаем это в отдельной переменной
            self.hit_bottom = True
            # выводим сообщение и количество очков
            canvas.create_text(250, 120, text='Вы проиграли', font=('Courier', 30), fill='red')
        # если было касание платформы
        if self.hit_paddle(pos) == True:
            # отправляем шарик наверх
            self.y = -2
        # если коснулись левой стенки
        if pos[0] <= 0:
            # движемся вправо
            self.x = 2
        # если коснулись правой стенки
        if pos[2] >= self.canvas_width:
            # движемся влево
            self.x = -2

Платформа

Сделаем то же самое для платформы — сначала опишем её поведение словами, а потом переведём в код. Итак, вот что должна уметь платформа:

  • двигаться влево или вправо в зависимости от нажатой стрелки;
  • понимать, когда игра началась и можно двигаться.

А вот как это будет в виде кода:

#  Описываем класс Paddle, который отвечает за платформы
class Paddle:
    # конструктор
    def __init__(self, canvas, color):
        # canvas означает, что платформа будет нарисована на нашем изначальном холсте
        self.canvas = canvas
        # создаём прямоугольную платформу 10 на 100 пикселей, закрашиваем выбранным цветом и получаем её внутреннее имя 
        self.id = canvas.create_rectangle(0, 0, 100, 10, fill=color)
        # задаём список возможных стартовых положений платформы
        start_1 = [40, 60, 90, 120, 150, 180, 200]
        # перемешиваем их
        random.shuffle(start_1)
        # выбираем первое из перемешанных
        self.starting_point_x = start_1[0]
        # перемещаем платформу в стартовое положение
        self.canvas.move(self.id, self.starting_point_x, 300)
        # пока платформа никуда не движется, поэтому изменений по оси х нет
        self.x = 0
        # платформа узнаёт свою ширину
        self.canvas_width = self.canvas.winfo_width()
        # задаём обработчик нажатий
        # если нажата стрелка вправо — выполняется метод turn_right()
        self.canvas.bind_all('<KeyPress-Right>', self.turn_right)
        # если стрелка влево — turn_left()
        self.canvas.bind_all('<KeyPress-Left>', self.turn_left)
        # пока игра не началась, поэтому ждём
        self.started = False
        # как только игрок нажмёт Enter — всё стартует
        self.canvas.bind_all('<KeyPress-Return>', self.start_game)
    # движемся вправо 
    def turn_right(self, event):
        # будем смещаться правее на 2 пикселя по оси х
        self.x = 2
    # движемся влево
    def turn_left(self, event):
        # будем смещаться левее на 2 пикселя по оси х
        self.x = -2
    # игра начинается
    def start_game(self, event):
        # меняем значение переменной, которая отвечает за старт
        self.started = True
    # метод, который отвечает за движение платформы
    def draw(self):
        # сдвигаем нашу платформу на заданное количество пикселей
        self.canvas.move(self.id, self.x, 0)
        # получаем координаты холста
        pos = self.canvas.coords(self.id)
        # если мы упёрлись в левую границу 
        if pos[0] <= 0:
            # останавливаемся
            self.x = 0
        # если упёрлись в правую границу 
        elif pos[2] >= self.canvas_width:
            # останавливаемся
            self.x = 0

Счёт

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

От счёта нам нужно только одно (кроме конструктора) — чтобы он правильно реагировал на касание платформы, увеличивал число очков и выводил их на экран:

#  Описываем класс Score, который отвечает за отображение счетов
class Score:
    # конструктор
    def __init__(self, canvas, color):
        # в самом начале счёт равен нулю
        self.score = 0
        # будем использовать наш холст
        self.canvas = canvas
        # создаём надпись, которая показывает текущий счёт, делаем его нужно цвета и запоминаем внутреннее имя этой надписи
        self.id = canvas.create_text(450, 10, text=self.score, font=('Courier', 15), fill=color)
    # обрабатываем касание платформы
    def hit(self):
        # увеличиваем счёт на единицу
        self.score += 1
        # пишем новое значение счёта 
        self.canvas.itemconfig(self.id, text=self.score)
        

Игра

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

Смысл игры в том, чтобы не уронить шарик. Пока этого не произошло — всё движется, но как только шарик упал — нужно показать сообщение о конце игры и остановить программу.

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

# создаём объект — зелёный счёт 
score = Score(canvas, 'green')
# создаём объект — белую платформу
paddle = Paddle(canvas, 'White')
# создаём объект — красный шарик 
ball = Ball(canvas, paddle, score, 'red')
# пока шарик не коснулся дна 
while not ball.hit_bottom:
    # если игра началась и платформа может двигаться
    if paddle.started == True:
        # двигаем шарик
        ball.draw()
        # двигаем платформу
        paddle.draw()
    # обновляем наше игровое поле, чтобы всё, что нужно, закончило рисоваться
    tk.update_idletasks()
    # обновляем игровое поле, и смотрим за тем, чтобы всё, что должно было быть сделано — было сделано
    tk.update()
    # замираем на одну сотую секунды, чтобы движение элементов выглядело плавно
    time.sleep(0.01)
# если программа дошла досюда, значит, шарик коснулся дна. Ждём 3 секунды, пока игрок прочитает финальную надпись, и завершаем игру
time.sleep(3)
# подключаем графическую библиотеку
from tkinter import *
# подключаем модули, которые отвечают за время и случайные числа
import time
import random
# создаём новый объект — окно с игровым полем. В нашем случае переменная окна называется tk, и мы его сделали из класса Tk() — он есть в графической библиотеке 
tk = Tk()
# делаем заголовок окна — Games с помощью свойства объекта title
tk.title('Game')
# запрещаем менять размеры окна, для этого используем свойство resizable 
tk.resizable(0, 0)
# помещаем наше игровое окно выше остальных окон на компьютере, чтобы другие окна не могли его заслонить. Попробуйте 🙂
tk.wm_attributes('-topmost', 1)
# создаём новый холст — 400 на 500 пикселей, где и будем рисовать игру
canvas = Canvas(tk, width=500, height=400, highlightthickness=0)
# говорим холсту, что у каждого видимого элемента будут свои отдельные координаты 
canvas.pack()
# обновляем окно с холстом
tk.update()
# Описываем класс Ball, который будет отвечать за шарик 
class Ball:
    # конструктор — он вызывается в момент создания нового объекта на основе этого класса
    def __init__(self, canvas, paddle, score, color):
        # задаём параметры объекта, которые нам передают в скобках в момент создания
        self.canvas = canvas
        self.paddle = paddle
        self.score = score
        # цвет нужен был для того, чтобы мы им закрасили весь шарик
        # здесь появляется новое свойство id, в котором хранится внутреннее название шарика
        # а ещё командой create_oval мы создаём круг радиусом 15 пикселей и закрашиваем нужным цветом
        self.id = canvas.create_oval(10,10, 25, 25, fill=color)
        # помещаем шарик в точку с координатами 245,100
        self.canvas.move(self.id, 245, 100)
        # задаём список возможных направлений для старта
        starts = [-2, -1, 1, 2]
        # перемешиваем его 
        random.shuffle(starts)
        # выбираем первый из перемешанного — это будет вектор движения шарика
        self.x = starts[0]
        # в самом начале он всегда падает вниз, поэтому уменьшаем значение по оси y
        self.y = -2
        # шарик узнаёт свою высоту и ширину
        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()
        # свойство, которое отвечает за то, достиг шарик дна или нет. Пока не достиг, значение будет False
        self.hit_bottom = False
    # обрабатываем касание платформы, для этого получаем 4 координаты шарика в переменной pos (левая верхняя и правая нижняя точки)
    def hit_paddle(self, pos):
        # получаем кординаты платформы через объект paddle (платформа)
        paddle_pos = self.canvas.coords(self.paddle.id)
        # если координаты касания совпадают с координатами платформы
        if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
            if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]:
                # увеличиваем счёт (обработчик этого события будет описан ниже)
                self.score.hit()
                # возвращаем метку о том, что мы успешно коснулись
                return True
        # возвращаем False — касания не было
        return False
    # метод, который отвечает за движение шарика
    def draw(self):
        # передвигаем шарик на заданный вектор x и y
        self.canvas.move(self.id, self.x, self.y)
        # запоминаем новые координаты шарика
        pos = self.canvas.coords(self.id)
        # если шарик падает сверху  
        if pos[1] <= 0:
            # задаём падение на следующем шаге = 2
            self.y = 2
        # если шарик правым нижним углом коснулся дна
        if pos[3] >= self.canvas_height:
            # помечаем это в отдельной переменной
            self.hit_bottom = True
            # выводим сообщение и количество очков
            canvas.create_text(250, 120, text='Вы проиграли', font=('Courier', 30), fill='red')
        # если было касание платформы
        if self.hit_paddle(pos) == True:
            # отправляем шарик наверх
            self.y = -2
        # если коснулись левой стенки
        if pos[0] <= 0:
            # движемся вправо
            self.x = 2
        # если коснулись правой стенки
        if pos[2] >= self.canvas_width:
            # движемся влево
            self.x = -2
#  Описываем класс Paddle, который отвечает за платформы
class Paddle:
    # конструктор
    def __init__(self, canvas, color):
        # canvas означает, что платформа будет нарисована на нашем изначальном холсте
        self.canvas = canvas
        # создаём прямоугольную платформу 10 на 100 пикселей, закрашиваем выбранным цветом и получаем её внутреннее имя 
        self.id = canvas.create_rectangle(0, 0, 100, 10, fill=color)
        # задаём список возможных стартовых положений платформы
        start_1 = [40, 60, 90, 120, 150, 180, 200]
        # перемешиваем их
        random.shuffle(start_1)
        # выбираем первое из перемешанных
        self.starting_point_x = start_1[0]
        # перемещаем платформу в стартовое положение
        self.canvas.move(self.id, self.starting_point_x, 300)
        # пока платформа никуда не движется, поэтому изменений по оси х нет
        self.x = 0
        # платформа узнаёт свою ширину
        self.canvas_width = self.canvas.winfo_width()
        # задаём обработчик нажатий
        # если нажата стрелка вправо — выполняется метод turn_right()
        self.canvas.bind_all('<KeyPress-Right>', self.turn_right)
        # если стрелка влево — turn_left()
        self.canvas.bind_all('<KeyPress-Left>', self.turn_left)
        # пока платформа не двигается, поэтому ждём
        self.started = False
        # как только игрок нажмёт Enter — всё стартует
        self.canvas.bind_all('<KeyPress-Return>', self.start_game)
    # движемся вправо 
    def turn_right(self, event):
        # будем смещаться правее на 2 пикселя по оси х
        self.x = 2
    # движемся влево
    def turn_left(self, event):
        # будем смещаться левее на 2 пикселя по оси х
        self.x = -2
    # игра начинается
    def start_game(self, event):
        # меняем значение переменной, которая отвечает за старт движения платформы
        self.started = True
    # метод, который отвечает за движение платформы
    def draw(self):
        # сдвигаем нашу платформу на заданное количество пикселей
        self.canvas.move(self.id, self.x, 0)
        # получаем координаты холста
        pos = self.canvas.coords(self.id)
        # если мы упёрлись в левую границу 
        if pos[0] <= 0:
            # останавливаемся
            self.x = 0
        # если упёрлись в правую границу 
        elif pos[2] >= self.canvas_width:
            # останавливаемся
            self.x = 0
#  Описываем класс Score, который отвечает за отображение счетов
class Score:
    # конструктор
    def __init__(self, canvas, color):
        # в самом начале счёт равен нулю
        self.score = 0
        # будем использовать наш холст
        self.canvas = canvas
        # создаём надпись, которая показывает текущий счёт, делаем его нужно цвета и запоминаем внутреннее имя этой надписи
        self.id = canvas.create_text(450, 10, text=self.score, font=('Courier', 15), fill=color)
    # обрабатываем касание платформы
    def hit(self):
        # увеличиваем счёт на единицу
        self.score += 1
        # пишем новое значение счёта 
        self.canvas.itemconfig(self.id, text=self.score)
# создаём объект — зелёный счёт 
score = Score(canvas, 'green')
# создаём объект — белую платформу
paddle = Paddle(canvas, 'White')
# создаём объект — красный шарик 
ball = Ball(canvas, paddle, score, 'red')
# пока шарик не коснулся дна 
while not ball.hit_bottom:
    # если игра началась и платформа может двигаться
    if paddle.started == True:
        # двигаем шарик
        ball.draw()
        # двигаем платформу
        paddle.draw()
    # обновляем наше игровое поле, чтобы всё, что нужно, закончило рисоваться
    tk.update_idletasks()
    # обновляем игровое поле и смотрим за тем, чтобы всё, что должно было быть сделано — было сделано
    tk.update()
    # замираем на одну сотую секунды, чтобы движение элементов выглядело плавно
    time.sleep(0.01)
# если программа дошла досюда, значит, шарик коснулся дна. Ждём 3 секунды, пока игрок прочитает финальную надпись, и завершаем игру
time.sleep(3)

Пишем игру на Python

Что дальше

На основе этого кода вы можете сделать свою модификацию игры:

  • добавить второй шарик;
  • раскрасить элементы в другой цвет;
  • поменять размеры шарика; поменять скорость платформы;
  • сделать всё это сразу;
  • поменять логику программы на свою.

JavaScript – очень гибкий язык, поскольку начиная с JavaScript ES5 каждый новый стандарт добавляет в язык все больше функциональности. За это приходится платить некоторыми старыми костылями, вокруг которых нужно «плясать», но преимущества все равно перевешивают – на чистом JavaScript можно написать практически что угодно, и гайд ниже вам это продемонстрирует, поскольку мы будем писать 2d игру «Змейку». Заметим, что выучить JavaScript с нуля на этом гайде не получится – все же нужны некоторые предварительные знания. Кроме того, предупредим, что нам понадобится чистый HTML (включая HTML5 canvas) и CSS, хотя 95% времени все же будет посвящено языку JavaScript.

Шаг предварительный: дизайн

Шаг 2: размещаем еду, перехватываем нажатия клавиш

Шаг 3: пишем основную функцию

Где взять гайды по разработке игр?

Подготовка: HTML и CSS

Перед тем, как размещать код, нам нужно создать стандартный HTML-файл index.html. Выглядеть он должен следующим образом:

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<meta name="viewport", content="width=device-width, initial-scale=1.0">

<link rel="stylesheet" href="snake.css">

<script src="snake.js"></script>

</head>

<body>

<canvas id="board"></canvas>

</body>

</html>

Здесь нет никакой магии: в head мы указываем всю мета-информацию, выставляем правильную ширину и подключаем CSS и скрипт, в котором будет расположена игра. В теле создаем канву, которая и будет основой нашей игры.

CSS выглядит вот так:

body {

text-align: center;

}

Это позволяет разместить нашу канву по центру экрана.

Шаг предварительный: дизайн

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

У нас есть некоторое поле с клетками, представляющее собой двухмерный массив. Изначально в случайных ячейках появляется еда, игрок появляется в фиксированной ячейке. Для простоты примера не будем делать отдельную кнопку «Старт», игра начнется при первом нажатии на любую стрелочку. Змейка управляется через стрелочки, она двигается в направлении, соответствующем стрелочке, нажатой последней. Змейка двигается с определенной скоростью и не может остановиться. Если змейка сталкивается с едой – она «съедает» ее: еда удаляется с экрана, змейка «прирастает» на 1 сегмент, на экране в незанятой клетке появляется новая еда. Если голова змейки сталкивается с другим сегментом змейки, игра заканчивается. Если голова змейки сталкивается с краем экрана, игра заканчивается.

Окончание игры сопровождается надписью «Вы проиграли!».

Шаг 1: создаем глобальные переменные и функцию main

Учитывая, что у нас – небольшой проект, будет очень удобно создать все необходимые переменные в глобальной области видимости, после чего обращаться к ним напрямую (в больших проектах так делать не стоит, потому что может случиться так, что вы случайно перекроете область видимости). Что нам нужно? Нам нужны переменные для: размера блока в пикселях, количества рядов и строк, служебные переменные для доступа к канве и ее содержимому, размеры и скорость змейки, массив для частей змейки, координаты еды, флаг окончания игры.

var blockSize = 25;

var rows = 20;

var cols = 20;

var board;

var context; 

var snakeX = blockSize * 5;

var snakeY = blockSize * 5;

var velocityX = 0;

var velocityY = 0;

var snakeBody = [];

var foodX;

var foodY;

var gameOver = false;

Опять же, с учетом того, что наш проект – маленький, будет неплохой идеей начать разработку с самой главной функции, в ней написать всю последовательность действий, после чего уже реализовывать функции более низкого уровня (вызываемые этой главной функцией). Начинать функцию будем по триггеру window.onload, в самой функции будем: 1) захватывать канву; 2) задавать размеры игрового поля в пикселях; 3) размещать еду; 4) подключать listener для нажатия кнопки; 5) реализовывать игровую механику с обработкой по фреймам. Код:

window.onload = function() {

board = document.getElementById("board");

board.height = rows * blockSize;

board.width = cols * blockSize;

context = board.getContext("2d"); 

placeFood();

document.addEventListener("keyup", changeDirection);

// update();

setInterval(update, 1000/10); //100 milliseconds

}

1000/10 означает, что игра будет обновляться 10 раз в секунду, если хотите уменьшить/увеличить скорость – поиграйте с этим параметром.

Шаг 2: размещаем еду, перехватываем нажатия клавиш

У нас есть 2 небольшие функции, которые можно реализовать прямо сейчас – размещение еды и нажатие клавиши. С размещением еды все очень просто:

function placeFood() {

//(0-1) * cols -> (0-19.9999) -> (0-19) * 25

foodX = Math.floor(Math.random() * cols) * blockSize;

foodY = Math.floor(Math.random() * rows) * blockSize;

}

Вызываем функцию генерации случайных чисел, через нее получаем номер блока, умножаем на ширину блока – получаем x и y новой еды.

С направлением все чуть сложнее:

function changeDirection(e) { if (e.code == "ArrowUp" && velocityY != 1) { velocityX = 0; velocityY = -1; } else if (e.code == "ArrowDown" && velocityY != -1) { velocityX = 0; velocityY = 1; } else if (e.code == "ArrowLeft" && velocityX != 1) { velocityX = -1; velocityY = 0; } else if (e.code == "ArrowRight" && velocityX != -1) { velocityX = 1; velocityY = 0; } }

Мы считаем ускорение как смещение относительно текущей точки на координатной оси на 1 или -1 (1 – это вправо или вниз, -1 – влево или вверх). Мы анализируем ввод и для каждой стрелочки меняем ускорение тем или иным образом. Проверка после && в условии нужна для того, чтобы исключить случаи, когда, например, змейка движется вправо, а мы нажали стрелочку влево – если позволить змейке поменять направление движения таким образом, то она тут же наткнется сама на себя.

Поэтому мы проверяем, что нажата стрелочка влево и при этом змейка не движется вправо.

Шаг 3: пишем основную функцию

В серьезных игровых движках, типа Unity и UE, функция update доступна для каждого элемента, и update исполняется каждый фрейм. Мы же хотим создать браузерную игру своими силами, поэтому используем

setInterval(update, 1000/10);

После чего пишем основной код в update(). Сначала отрисовываем игровое поле и блок еды:

context.fillStyle="black";

context.fillRect(0, 0, board.width, board.height);

context.fillStyle="red";

context.fillRect(foodX, foodY, blockSize, blockSize);

Теперь проверяем, находится ли голова змейки и еда на одной точке, если находится – еду нужно «съесть» и сгенерировать новую:

if (snakeX == foodX && snakeY == foodY) {

snakeBody.push([foodX, foodY]);

placeFood();

}

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

for (let i = snakeBody.length-1; i > 0; i--) {

snakeBody[i] = snakeBody[i-1];

}

if (snakeBody.length) {

snakeBody[0] = [snakeX, snakeY];

}

Теперь реализовываем саму змейку:

context.fillStyle="lime";

snakeX += velocityX * blockSize;

snakeY += velocityY * blockSize;

context.fillRect(snakeX, snakeY, blockSize, blockSize);

for (let i = 0; i < snakeBody.length; i++) {

context.fillRect(snakeBody[i][0], snakeBody[i][1], blockSize, blockSize);

}

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

if (snakeX < 0 || snakeX > cols*blockSize -1 || snakeY < 0 || snakeY > rows*blockSize - 1) {

gameOver = true;

alert("Game Over");

}

for (let i = 0; i < snakeBody.length; i++) {

if (snakeX == snakeBody[i][0] && snakeY == snakeBody[i][1]) {

gameOver = true;

alert("Game Over");

}

}

Наконец, в самое начало функции нужно добавить проверку геймовера – если значение равно true, то нужно закончить игру и ничего больше не делать.

if (gameOver) {

return;

}

Все, имеем полностью работоспособную игру.

Шаг 4: тестируем

Все файлы нужно собрать в одной папке, после чего – открыть html-файл. Нажмите любую стрелочку – и увидите следующее:

Где взять гайды по разработке игр?

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

  • Канал ChrisCourses – огромное количество длинных и детальных гайдов по разработке самых сложных игр (вплоть до RPG про Покемонов)
  • Мультиплеерная игра на JavaScript с дополнительной библиотекой
  • Простой гайд по созданию игры на русском языке
  • Аналог Flappy Bird на JS
  • Игра, код которой умещается в 100 символов

Вывод

  • JS хорошо подходит для создания простых браузерных игр.
  • Вы можете самостоятельно по гайдам создавать такие простые игры, как змейку, гонки, Aliens Invaders, PacMan и другие.
  • Более сложные игры могут потребовать от вас пользоваться сторонними библиотеками.
  • В любом случае вам нужно хорошо знать JS, без этих знаний вы не сможете разрабатывать игры самостоятельно.

Понравилась статья? Поделить с друзьями:
  • Как написать простейший парсер
  • Как написать простейший калькулятор на питоне
  • Как написать прокуратуру жалобу на дпс
  • Как написать простейший калькулятор на python
  • Как написать проклятие на человека