Обновить
19
0
Журат Максим@ChessMax

Пользователь

Отправить сообщение

Создание псевдотрёхмерной гоночной игры: реализация холмов и готовая игра

Время на прочтение14 мин
Охват и читатели3.6K

Часть 3. Холмы



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

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

В первой части мы использовали закон подобных треугольников для создания трёхмерной перспективной проекции:


… что привело нас к получению уравнений проецирования координаты 3d-мира в координату 2d-экрана.


… но так как тогда мы работали только с прямыми дорогами, мировым координатам нужна была только компонента z, потому что и x, и y были равны нулю.

Это хорошо нам подходит, потому что для добавления холмов нам достаточно дать сегментам дороги соответствующую ненулевую координату y, после чего уже имеющаяся функция render() волшебным образом заработает.
Читать дальше →

Создание псевдотрёхмерной гоночной игры

Время на прочтение17 мин
Охват и читатели15K

В детстве я редко ходил в залы аркадных автоматов, потому что особо в них не нуждался, ведь дома у меня были потрясающие игры для C64… но есть три аркадные игры, на которые у меня всегда находились деньги — Donkey Kong, Dragons Lair и Outrun…

… и я очень любил Outrun — скорость, холмы, пальмы и музыка, даже на слабой версии для C64.


Поэтому я решил попробовать написать олдскульную псевдотрёхмерную гоночную игру в стиле Outrun, Pitstop или Pole position. Я не планирую собрать полную и завершённую игру, но мне кажется, будет интересно заново изучить механики, при помощи которых эти игры реализовывали свои трюки. Кривые, холмы, спрайты и ощущение скорости…

Итак, вот мой «проект на выходные», который в итоге занял пять или шесть недель по выходным



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

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

Можно также поиграть

Читать дальше →

Парсите, а не валидируйте

Время на прочтение16 мин
Охват и читатели31K

Еще в декабре мне попалась одна совершенно замечательная статья на английском, посвящённая использованию системы типов языка для более широкого класса задач, для повышения надежности приложений и простоты рефакторинга. К сожалению, в тот момент я был слишком занят написанием статей по ФП, которые крайне важно было написать, пока свежи воспоминания. Но теперь, когда с этой задачей я справился, наконец дошли руки перевести эту замечательную заметку. Оригинальный язык примеров — Хаскель, но я решил переписать их на раст, для более широкого охвата аудитории. Однако язык тут совершенно неважен, советы этой статьи я применяю в ежедневной разработке на вполне себе "приземлённых" C# и TypeScript, так что если вы просто стараетесь писать надёжный и поддерживаемый код, то, вне зависимости от языка, статья вам будет в тему.


Благодарю за вычитку и помощь в переводе Hirrolot, funkill и andreevlex


Читать дальше →

Строим города по клику мыши с Houdini и Python

Время на прочтение3 мин
Охват и читатели16K


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

Эта статья как раз про подобное. Автор придумал метод постройки виртуальных городов, который в перспективе хочет превратить в полноценный инструмент левел-дизайнера.
Читать дальше →

Как вывести сайт под запад в ТОП10, не зная ничего о SEO

Время на прочтение7 мин
Охват и читатели42K
В этой статье описан личный опыт двух человек: меня и моей коллеги Марии. Опыт людей, у которых совершенно не было знаний в SEO. Во второй половине 2019 года на нас легла ноша в виде продвижения 2-х сайтов проекта Ratatype. Сайтов молодых (рождены в 2019) и на иностранный рынок, языков которого мы не знаем (Франция и Испания), да еще и с очень ограниченным бюджетом.

Что вы найдете в этой статье:

  1. Реальный кейс, который работал, работает и будет работать.
  2. Пошаговую инструкцию «Что? Зачем? Как?» на простом языке.
  3. Описание провалов, куда ж без них.
  4. Что-то интересное на рынке SEO, но это не точно.

Чего вы здесь не найдете:

  1. Трендов 2020, 2021 или любого другого года.
  2. Мнений экспертов.
  3. Предложения услуг продвижения.

Если все устраивает — прошу, следуйте ниже по тексту.
Читать дальше →

Реалистичный боевой ИИ для 2D-игры

Время на прочтение6 мин
Охват и читатели14K
image

Хотя Close Quarters преимущественно является многопользовательской игрой, в ней всё равно должны присутствовать сложные ИИ-боты, чтобы игроки продолжали играть при плохом Интернет-соединении или отсутствии других онлайн-игроков. Кроме того, боты играют важную вспомогательную роль в некоторых режимах игры. Поэтому они должны вести себя правдоподобно и демонстрировать набор сложных поведений, в том числе использование укрытий, применение предметов в подходящее время, обход с флангов, бросание гранат и убегание от них.

Окружение и ограничения


Игровое окружение состоит из полигонов. Большинство полигонов блокирует движение, область видимости и стрельбу, однако есть и «низкие» полигоны, только блокирующие движение. Окружение плотно заставлено препятствиями и укрытиями.

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

Как я сгенерировал на Python тысячу лиц для своей игры

Время на прочтение3 мин
Охват и читатели32K
На определённом этапе разработки своей игры я осознал, что мне нужна система диалогов с лицами-аватарами.

Поэтому я решил создать генератор лиц на основе знаменитой игры Papers, Please.


Генератор лиц Dukope (из Papers, Please)

Сбор данных


Я скачал примерно 50 портретов с pixabay.com (все изображения имеют лицензию CC и не требуют указания авторства).

Затем я вырезал фон каждого изображения в Photoshop (просто выбрал всё инструментом выделения многоугольника и нажал на Delete). В дальнейшем я планировал воспользоваться эффектом cutout , чтобы скрыть все недочёты.


Изображения с удалённым фоном
Читать дальше →

Как я заработал 1 000 000 $ без опыта и связей, а потом потратил их, чтобы сделать свой переводчик

Время на прочтение20 мин
Охват и читатели144K

Как все начиналось


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

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

Отложенный Alpha blending

Время на прочтение6 мин
Охват и читатели12K
В этой статье я хочу поговорить о методах смешивания растеризуемой геометрии. Классические модели смешивания полупрозрачных объектов — Alpha, Additive, Multiplicative — объединяет один и тот же принцип отрисовки: последовательно рисуем один примитив за другим, смешивая получаемые на выходе фрагментного шейдера пиксели с тем, что находится в текущем буфере. Каждый новый примитив обновляет область буфера, в которую рисуется; в случае с альфа-смешиванием объекты, которые находятся выше, заслоняют ранее отрисованные. Но что если хочется что-то сделать с группой объектов, рисуемых поверх сцены, — например, обрезать их по маске или подсветить? Тут сразу в голову приходят два решения: или внести изменения в их материал (т.е. изменить шейдер, расширить набор текстур), к примеру, добавив проекцию еще одной текстуры, которая будет отвечать за маску прозрачности. Однако если у нас много разношерстных объектов, менять каждый уникальный материал неудобно и чревато ошибками. Второй вариант — нарисовать все интересующие нас объекты в отдельный полноэкранный таргет и рисовать уже его на финальную сцену. Тут мы можем сделать с его содержимым все, что захотим, но это требует выделения лишней памяти и, что самое неприятное, — переключения рендер таргетов. Это не самая «дешевая» операция на мобильных устройствах, которую будет необходимо выполнить дважды. А если захочется вот так работать с несколькими слоями?


Читать дальше →

Upgrade компа серверным SATA SSD на 1.92TB с ресурсом записи от 2PB и выше

Время на прочтение3 мин
Охват и читатели37K


Есть люди, которые любят использовать качественные комплектующие из корпоративного сегмента в быту. Они хотят быть уверенными в том, что их SSD не накроется внезапно из-за сбоя по питанию или write amplification при ежедневном скачивании огромных 4K-торрентов на фрагментированный NTFS-раздел с размером кластера 4K или при очередной компиляции Gentoo из исходников.

Конечно, такие опасения редко сбываются на практике, однако очень приятно пользоваться SSD с Power Loss Protection (1, 2, 3), который имеет практически безграничный ресурс записи. И даже когда ёмкость его станет малой для текущих задач, он всё равно может быть использован как флэшка или как дополнительный диск, подарен или продан.

В этой статье приведён список корпоративных SSD ёмкостью 1.92ТБ, которые сейчас подешевели до уровня потребительских SSD (< $300), но обладают ресурсом записи от 2 Петабайт и выше.
Читать дальше →

Разоблачаем магию DiffUtil

Время на прочтение4 мин
Охват и читатели24K


Каждый Android-разработчик использовал RecyclerView для отображения списков и каждый сталкивался с проблемой обновления данных в списке, пока в 2016 году не появился магический класс DiffUtil. Я на пальцах объясню, как на самом деле он работает, и постараюсь рассеять его магию.

Читать дальше →

Реализация физически корректных объемных облаков как в игре Horizon Zero Dawn

Время на прочтение16 мин
Охват и читатели18K
Раньше облака в играх рисовались обычными 2D спрайтами, которые всегда повернуты в направлении камеры, но последние годы новые модели видеокарт позволяют рисовать физически корректные облака без заметных потерь в производительности. Считается, что объемные облака в игры принесла студия Guerrilla Games вместе с игрой Horizon Zero Dawn. Конечно, такие облака умели рендерить и раньше, но студия сформировала что-то вроде промышленного стандарта на исходные ресурсы и используемые алгоритмы, и в настоящее время любая реализация объемных облаков так или иначе этому стандарту соответствует.

UPD. Картинка обновлена. Изменения описаны в конце статьи.


Читать дальше →

Создание игры Tower Defense в Unity: баллистика

Время на прочтение21 мин
Охват и читатели14K
[Первая, вторая и третья части туториала]

  • Поддержка разных типов башен.
  • Создание башни-мортиры.
  • Вычисление параболических траекторий.
  • Запуск взрывающихся снарядов.

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

Туториал создавался в Unity 2018.4.4f1.


Враги подвергаются бомбардировке.
Читать дальше →

Пример Model-View-Update архитектуры на F#

Время на прочтение8 мин
Охват и читатели7.4K

Кому-то не нравился Redux в React из-за его имплементации на JS?


Мне он не нравился корявыми switch-case в reducer'ах, есть языки с более удобным pattern matching, и типы лучше моделирующие события и модель. Например, F#.
Эта статья — разъяснение устройства обмена сообщениями в Elmish.

Читать дальше →

Чистая архитектура решения, тесты без моков и как я к этому пришел

Время на прочтение6 мин
Охват и читатели16K

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

Читать дальше →

Fighting complexity in software development

Время на прочтение31 мин
Охват и читатели3.5K

What's this about


After working on different projects, I've noticed that every one of them had some common problems, regardless of domain, architecture, code convention and so on. Those problems weren't challenging, just a tedious routine: making sure you didn't miss anything stupid and obvious. Instead of doing this routine on a daily basis I became obsessed with seeking solution: some development approach or code convention or whatever that will help me to design a project in a way that will prevent those problems from happening, so I can focus on interesting stuff. That's the goal of this article: to describe those problems and show you that mix of tools and approaches that I found to solve them.

Read more →

Процедурная генерация планет

Время на прочтение19 мин
Охват и читатели41K

От переводчика:
Представляю вашему вниманию статью авторства Andy Gainey, в прошлом независимого разработчика игровых инструментов, ныне сотрудника Paradox Development Studio. На мой взгляд, автор играючи создал один из лучших процедурных генераторов планет с открытым исходным кодом.

Читать дальше →

Генерируем тайловые уровни и прячем квадраты от игрока

Время на прочтение8 мин
Охват и читатели20K

Генерация уровней в Unexplored 2


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

Нам не пришлось заново изобретать велосипед. В Unexplored 1 мы уже создали техники, которые сильно повлияли на успех первой игры. Unexplored 2 просто продолжила начатое. Фундамент нашей технологии состоит из двух частей: мы применяем многоэтапную генерацию, которая почти имитирует процесс, очень похожий на работу живого дизайнера уровней. Поверх него мы используем технику под названием "циклическая генерация подземелий", которая гораздо лучше справляется с генерацией естественно выглядящих уровней, чем большинство стандартных приложений генеративного создания контента. В этом посте я расскажу о первом аспекте. Адаптация циклической генерации подземелий к Unexplored 2 будет темой будущего поста.

Имитация «человеческого» дизайна уровней


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

Code review: вы делаете это неправильно

Время на прочтение21 мин
Охват и читатели72K

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

На рынке есть куча инструментов для ревью кода с готовыми сценариями использования, рекомендациями и правилами. GitHub, Phabricator, FishEye/ Crucible, GitLab, Bitbucket, Upsource — список можно долго продолжать. Мы в Badoo тоже в своё время с ними работали: в своей предыдущей статье  я рассказывал нашу историю ревью кода и о том, как мы пришли к изобретению собственного «велосипеда» — решения Codeisok.

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

Именно поэтому другую часть айсберга можно и не заметить.
Читать дальше →

Моноиды и их приложения: моноидальные вычисления в деревьях

Время на прочтение20 мин
Охват и читатели25K
Приветствую, Хабрахабр. Сегодня я хочу, в своём обычном стиле, устроить сообществу небольшой ликбез по структурам данных. Только на этот раз он будет гораздо более всеобъемлющ, а его применения и практичность — простираться далеко в самые разнообразные области программирования. Самые красивые применения, я, конечно же, покажу и опишу непосредственно в статье.

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

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

Моноид как концепция


Представьте себе множество чего угодно, множество, состоящее из объектов, которыми мы собираемся манипулировать. Назовём его M. На этом множестве мы вводим бинарную операцию, то есть функцию, которая паре элементов множества ставит в соответствие новый элемент. Здесь и далее эту абстрактную операцию мы будем обозначать "⊗", и записывать выражения в инфиксной форме: если a и b — элементы множества, то c = ab — тоже какой-то элемент этого множества.

Например, рассмотрим все строки, существующие на свете. И рассмотрим операцию конкатенации строк, традиционно обозначаемую в математике "◦", а в большинстве языков программирования "+": "John""Doe" = "JohnDoe". Здесь множество M — строки, а "◦" выступает в качестве операции "⊗".
Или другой пример — функция fst, известная в функциональных языках при манипуляции с кортежами. Из двух своих аргументов она возвращает в качестве результата первый по порядку. Так, fst(5, 2) = 5; fst("foo", "bar") = "foo". Безразлично, на каком множестве рассматривать эту бинарную операцию, так что в вашей воле выбрать любое.

Далее мы на нашу операцию "⊗" накладываем ограничение ассоциативности. Это значит, что от неё требуется следующее: если с помощью "⊗" комбинируют последовательность объектов, то результат должен оставаться одинаковым вне зависимости от порядка применения "⊗". Более строго, для любых трёх объектов a, b и c должно иметь место:
(ab) ⊗ c = a ⊗ (bc)
Легко увидеть, что конкатенация строк ассоциативна: не важно, какое склеивание в последовательности строк выполнять раньше, а какое позже, в итоге все равно получится общая склейка всех строк в последовательности. То же касается и функции fst, ибо:
fst(fst(a, b), c) = a
fst(a, fst(b, c)) = a
Цепочка применений fst к последовательности в любом порядке всё равно выдаст её головной элемент.

И последнее, что мы потребуем: в множестве M по отношению к операции должен существовать нейтральный элемент, или единица операции. Это такой объект, который можно комбинировать с любым элементом множества, и это не изменит последний. Формально выражаясь, если e — нейтральный элемент, то для любого a из множества имеет место:
ae = ea = a
В примере со строками нейтральным элементом выступает пустая строка "": с какой стороны к какой строке её ни приклеивай, строка не поменяется. А вот fst в этом отношении нам устроит подлянку: нейтральный элемент для неё придумать невозможно. Ведь fst(e, a) = e всегда, и если ae, то свойство нейтральности мы теряем. Можно, конечно, рассмотреть fst на множестве из одного элемента, но кому такая скука нужна? :)

Каждую такую тройку <M, ⊗, e> мы и будем торжественно называть моноидом. Зафиксируем это знание в коде:
public interface IMonoid<T> {
    T Zero { get; }
    T Append(T a, T b);
}

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

Информация

В рейтинге
Не участвует
Откуда
Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Разработчик мобильных приложений
Старший
Flutter
Flutter Bloc
MobX
Mobile
Разработка мобильных приложений