Немного о собственном опыте знакомства со средствами для создания игр на ретроплатформах

Vanity of razzle_dazzle

Преподавательница программирования в школе, в которой я учился, начала с вещей правильных, но неинтересных, подкупая учеников тем, что если они смогут создать такую программу, им больше не придётся решать типовую задачу снова и снова. Если вы не занимаетесь каким-то однотипным видом деятельности, а просто решаете задачки из учебника, то обнаружите, что даже в пределах одной темы задачки разные. Возникает вопрос, сколько же программ надо написать, да и все эти var'ы, int'ы, синий экран смерти ТурбоПаскаля (и это во времена winXP!), блок-черт-бы-их-побрал-схемы совсем не способствуют изначальной заинтересованности. Всё это выглядит как алхимия, какое-то тайное знание, но при этом знание скучное, сухое. Удивителен пример химии — школьников на днях открытых дверей зазывают, чтобы показать превращение красной жидкости в зелёную, и это действительно работает, хотя в итоге оказывается, что в химии есть свои var'ы и int'ы, ты как-то свыкаешься с этой идеей, прокручивая в голове опыт с превращением жидкостей. А ведь что стоило преподавательнице программирования запустить простой цикл с экраном, меняющим цвет, или показать простенькую игрушку а-ля понг.

Освоив худо-бедно основы программирования, сделав пару игрушек, приходит осознание того, что это всё, конечно, здорово, но при простенькой графике, минимуме эффектов игра просит не такой уж слабый компьютер — и, например, на моём самом первом компьютере «Мариуполис» просто отказался бы запускаться. А ведь он в сотни, а кое-где и в тысячи раз мощнее какой-нибудь NES. Заставить старую платформу с микроскопическим объёмом памяти воспроизводить игру — вот это настоящее таинство! И вправду, первый взгляд на программы, написанные на ассемблере (а подавляющее большинство игр для старых платформ на нём и писались), создают впечатление тайнописи. Я был не готов к жонглированию регистрами, но с удивлением обнаружил, что это нужно далеко не всегда. Как оказалось, существует инструментарий, позволяющий программировать игры для старых платформ на высокоуровневых языках.


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

А давайте разработаем формат записи игровых сессий?

Программирование

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

В 80-е/90-е годы, когда в ходу были аркадные автоматы с видеоиграми, в играх делали специальные режим под названием Attraction mode, в котором, чтобы привлечь посетителей залов аркадных автоматов (отсюда и название), игра играла сама в себя, для чего со стороны одного либо двух игроков выполнялись предварительно записанные действия.

Надо отметить (я не знал, пока не поинтересовался плотно), что Attraction mode не всегда включала в себя демонстрацию именно геймплея. Есть ряд игр, где нам показывают таблицу рекордов (High Scores), или предысторию игры (Cutscenes). Robocop 3, например, просто чередует главное меню с рекордами, но трек играет на протяжении около 4 минут, что для NES порядочно много — большинство треков укладывалсь в те сложные времена секунд в 30-40 максимум. Но как это всё делать, я думаю, и так понятно, а вот как заставить игру играть в себя...

Итак, цель поста: Разработать удобный, открытый и свободный формат хранения игровых сессий. Также я для наглядности привёл здесь текущий формат игровых сессий Замка Невозврата 2.

Интересно? Заходите под кат.


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

Еще раз немного про изометрию, перерасчет координат и вращение камеры

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

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

Масштабирование всей игры без мыла и дрожания (финальная версия)

GameMaker

Пост относится только к GM8.1. У Студии есть такая же проблема, решается ли она — не читал, но какое-то обсуждение на официальном форуме было. Да скорее всего решается, просто функции другие и надо пересоздавать сёрфейс если он вдруг пропал (вечная беда главная фишка Студии).

Техника, которую я описываю в этом посте, собирает в себе опыт Йеовского копания в этом вопросе в 2011 году, ответ (2013) и дополненный ответ (2014) от некоего юзера Blue на gamedev.stackexchange.com, который на самом деле основывается на бородатом ответе на форумах Гейм Мейкера времён 2008-2010 (уже не удаётся найти через поисковик), и мой собственный, отработанный на Castle of no Escape и окончательно отфильтрованный при попытке встроить это «безмыльное» масштабирование в Princess Remedy in a World of Hurt.

Суть проблемы: при использовании встроенного масштабирования в GM8.1, на многих системах получаем мыло, тогда как нужны чёткие квадратные (или хотя бы неразмытые) пикселы.


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

КсиТехнология-02 — послойное рисование спрайтов в заданной палитре

GameMaker

Спойлер
показать

(анимация очень цветастая, большая и быстрая — осторожно! специально спрятал в спойлер)

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

В Shovel Knight для этого использовали пиксельные шейдеры. Но в ГМ8.1, который я использую сейчас для Castle of no Return 2, и тем более в ГМ6.0, который я использовал во время придумывания этой технологии в 2008 году, когда Дрейк делал уже третью часть своей фан-игры по Мегамену, шейдеров никаких нет. Думаете, я остался доволен? Думаете, они нужны? Нихрена подобного! Подробности — под катом.


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

Синусоидальный эффект графического изображения

Графика

 

 

//draw_sprite_sine(angle, amplitude)

for (i=0 i<sprite_height i+=1)
draw_sprite_part_ext
(
sprite_index,image_index,
0,
i,
sprite_width,
1,
x-sprite_get_xoffset(sprite_index)+sin((argument0+i)*degtorad(argument1))*argument1,
y-sprite_get_yoffset(sprite_index)+i,
1,
1,
random(c_white),
image_alpha
)

GM 8.1, но должно работать и в GM:S, draw_sprite_part_ext там есть.

Тут ещё помимо самого эффекта я докрутил сверху рандомную перекраску строк, ну это уж знающие люди разберутся.

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

Разрабатываемые проекты

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

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

  1. Игра запускает внешнюю программу, в моём случае это мой самописный HTTPChecker.
  2. Программа идёт на мой субдомен, сейчас это r0.kolenka.su, и читает там файл, соответствующий конкретной игре. В файле написано, какая версия самая последняя, точнее там название файла самой последней версии, которое включает в себя номер версии.
  3. Если полученный ответ не совпадает со внутренней версией, то игроку предлагается выбор — обновлять или нет. Если да, игра снова обращается к HTTPChecker'у, только теперь уже чтоб скачать новую версию.
  4. В директории игры появляется новый файл. Старый файл запихивается в папку старых версий, новый переименовывается в просто %название игры%.exe, без версии.

Чтобы не заморачиваться с ручным обновлением файла, написал бат-файл где всё автоматически логинится на ФТП, загружает туда новую версию игры, и PHP-файл, который даёт HTTP-ответ, что, мол, такая-то версия последняя.

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


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

LD DL — моя программа для Ludum Dare… Уже устарела!

Ludum Dare

Когда-то (чуть более двух с половиной лет назад до публикации этого поста) я писал для Ludum Dare веб-кроулер* для сгруппированного сбора ссылок на игры участников ЛД. Смысл был в том, чтобы получить например все игры для Windows, и автоматизированно скачать их все с помощью менеджера закачек. Ну, если не со всего ЛД, то хотя бы 50-100 игр для того чтобы их действительно оценить, не закачивая что-то новое каждый раз вручную — это слишком отвлекает, а у всех вменяемых участников всё равно есть свои собственные readme-файлы, чтобы сориентироваться в игре без того чтобы читать страницу игры на ЛД. Я, например, всё равно копирую ридми в эту страницу, так быстрее, да и другого назначения я не вижу в ней.

Конечно, при реализации моей программы не всё вышло так, как хотелось. Точнее, ключевой её аспект прогорел - часть ссылок вела не на сами файлы, а на страницы файлообменников для скачивания файлов, поэтому по ссылке качалась веб-страница, а не игра; однако, это дало мне неплохое понятие о том, как работают эти системы вообще. И, как бы то ни было, я выложил это всё на обозрение сообщества, и они оценили. Тут можно видеть, как широка фантазия людей на предмет того, как подписывать свои ссылки — мне пришлось отдельно запрограммировать скачивание всех ссылок с содержанием заданной строки, а не с жёстко заданной строкой, потому что «Windows», «Windows Executable», «Windows (Post Jam)», «Windows (exe)» и ещё вагон прочих — это были совершенно разные вещи для программы. Кто-то подписал«Windows + Source», а кто-то — «Windows — Source». Что забавно.


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

4 способа написать код, который меня раздражает (с пояснениями)

Программирование

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

 

switch-case с константами

Не тортТорт

В работе:

switch (variable)
{
    case 0: text=«raz» break;
    case 1: text=«dva» break;
    case 2: text=«tri» break;
}

Особое извращение — сделать скрипт, который делает только это присваивание.

В инициализации:

text_value[0]=«raz»
text_value[1]=«dva»
text_value[2]=«tri»

В работе:

text=text_value[variable]

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

Случай похуже:

Не тортТорт

В работе:

switch (variable)
{
    case 0: text=«raz» draw_text(0,0,text) break;
    case 1: text=«dva» draw_text(0,0,text) break;
    case 2: text=«tri» draw_text(0,0,text) break;
}

В инициализации:

text_value[0]=«raz»
text_value[1]=«dva»
text_value[2]=«tri»

В работе:

text=text_value[variable]

В рендере:

draw_text(0,0,text)

Копипастить повторяющиеся участки кода это плохо. Практически везде и всегда. Чем конкретно? Если вы захотите поменять действие, которое происходит после вычисления, то вам придётся поменять каждую ветку case. А если их 10? 50?

 

Фигурные скобки с одним условием для одной команды

 

if (condition)
{
    i=0
}

Зачем? Обычной индентации (отбивки) ведь вполне достаточно.

А вот дальше уже начинается жесть.


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

MiniTekx

Компьютерная генерация

Зашёл я значит сегодня в АндерГамин, а там мне и говорят:

[26 сен 15 21:32] * Каждый день праздник * Xitilon: спорим твой tekx не может генерировать шум наподобие http://imgs.steps.dragoart.com/how-to-draw-venus-step-2_1_000000014358_5.jpg
[26 сен 15 21:34] * Каждый день праздник * Xitilon: ИЛИ МОЖЕТ?

Может.

Дальше речь зашла о том, чтобы генерировать такие текстуры в ГМ, но производительность такого рода вычислений в нём аховая, что я уже давно проверял. Поэтому сошлись на том, что я сделаю консольный вариант с ограниченным функционалом, для того чтобы его вызывать из игры на фоне, а игра на ГМ подхватывала результат из выделенной для этого (или текущей) папки. Писал с нуля, интерфейса никакого нет, функции примерно как у старых версий Tekx, хотя так-то никто кроме меня не заметит разницы — никто толком и не знал его всего функционала, ха-ха. В любом случае, для заданной цели этого достаточно.

MiniTekx 0.6 здесь.

Параметры: ширина, высота, цвет1, цвет2, количество точек, итерации генератора, bitcrush, замыканине текстуры на себя, фасет (вещественное число, не использовать фасет = 1)