В привычном значении слова, у этой игры наверное нет шейдеров. Здесь весь код постпроцессинга картинки прямо в самом коде игры на Си, как и вся игра.
Сама игрушка изначально черно-белая, все ассеты тоже черно белые. Если отрендерить без кода постпроцессинга, то получится вот так:
Дальше каждый пиксель затемняется в зависимости от его глубины в кадре:
И дальше главная функция постпроцессинга опять же проходит про каждому пикселю и заменяет его на один из 8 цветов палитры, попутно применяя кое-какой дизеринг:
unsigned char pal[8][3] = {
{ 1, 63, 79 },
{ 22, 70, 96 },
{ 74, 78, 104 },
{ 131, 105, 122 },
{ 198, 129, 89 },
{ 235, 170, 94 },
{ 245, 212, 163 },
{ 255, 236, 214 }
};
void set_with_pal(unsigned int x, unsigned int y, int pal_idx) {
set(x, y, pal[pal_idx][0], pal[pal_idx][1], pal[pal_idx][2]);
}
void postproc() {
unsigned char r, g, b;
for (unsigned int x = 0; x < WIDTH; x ++)
for (unsigned int y = 0; y < HEIGHT; y ++) {
get(x, y, &r, &g, &b);
r /= 8;
r -= 3;
if (r > 32) {
r = 0;
}
if (r % 4 == 0) {
set_with_pal(x, y, r / 4);
} else if (r % 2 == 0) {
int one = (r - 2) / 4;
int two = (r - 2) / 4 + 1;
if ((y + x) % 2) {
set_with_pal(x, y, one);
} else {
set_with_pal(x, y, two);
}
} else {
int one = (r % 4 == 1) ? (r - 1) / 4 + 1 : (r - 3) / 4;
int two = (r % 4 == 1) ? (r - 1) / 4 : (r - 3) / 4 + 1;
if ((y % 2) == (r % 4 == 1) && x % 2) {
set_with_pal(x, y, one);
} else {
set_with_pal(x, y, two);
}
}
}
}
get(x, y, r, g, b) и set(x, y, r, b, g) - это соответственно функции чтобы достать и проставить пиксель (x, y)
var _w = max(argument[0],2), _h=max(argument[0],2);
ds_grid_resize(MAP_grid,_w,_h);
ds_map_clear(MAP_walls);
var l=ds_list_create(), g = ds_grid_create(_w,_h);
var len = _w*_h;
ds_grid_clear(MAP_grid,room_4);
ds_grid_clear(MAP_visit, 0);
// l - это список комнат, которые я потом перемешаю
// сперва точка старта
ds_list_add(l,room_start);
// Потом комнаты-цели, и вообще любые важные но одноразовые для уровня комнаты(магазы, алтари и т.д.)
// сколько нужно
for(var _i=0;_i<3;_i++) {
ds_list_add(l,choose(room_target_1,room_target_2));
}
// А это массив со всеми видами комнат, я его буду перемешивать
// и накидывать из него комнат, это нужно, чтобы комнаты как можно меньше раз повторялись за одну карту.
// В идеале его размер должен быть в несколько раз больше чем количество ячеек карты
ds_list_shuffle(MAP_rooms);
var _rindx = 0;
while(ds_list_size(l)<len) {
ds_list_add(l,MAP_rooms[| _rindx]);
_rindx++;
if _rindx>ds_list_size(MAP_rooms)-1 then {
ds_list_shuffle(MAP_rooms);
_rindx=0;
}
}
MAP_target_count=3;
ds_map_clear(MAP_targets);
// А теперь перемешиваем их расположение
ds_list_shuffle(l);
//По порядку забиваем в массив, отмечаем точку старта игрока
var _mx = 0, _my=0;
for(var _i=0;_i<ds_list_size(l);_i++) {
var _r = l[| _i];
if _r==room_start then {
MAP_x = _mx;
MAP_y = _my;
}
MAP_grid[# _mx, _my]=_r;
_mx++;
if _mx>=ds_grid_width(MAP_grid) then {
_mx=0;
_my++;
}
}
ds_list_clear(l);
// Генерим стенки, вот этот ут - как раз "дырявость карты"
len = floor(len*(0.5+random(0.5)));
randomize();
for(var i=0; i<len; i++) {
// Выбираем случайную комнату
var _x1=irandom(_w-1),_y1=irandom(_h-1);
var val1 = string(_x1)+"|"+string(_y1);
//Здесь будем выбирать случайное направление с учётом того что там может быть граница
if _x1>0 then ds_list_add(l,string(_x1-1)+"|"+string(_y1));
if _x1<_w-1 then ds_list_add(l,string(_x1+1)+"|"+string(_y1));
if _y1>0 then ds_list_add(l,string(_x1)+"|"+string(_y1-1));
if _y1<_h-1 then ds_list_add(l,string(_x1)+"|"+string(_y1+1));
ds_list_shuffle(l);
var val2 = l[| 0];
ds_list_clear(l);
// А это если случайно там уже есть стена = фейл-попытка
if ds_map_exists(MAP_walls,val1+"="+val2) || ds_map_exists(MAP_walls,val2+"="+val1) then continue;
// Пытаемся поставить стену
ds_map_add(MAP_walls,val1+"="+val2,true);
ds_map_add(MAP_walls,val2+"="+val1,true);
// Сбрасываем карту посещений
ds_grid_clear(g,0);
// Проверяем проходимость
mapWalk(0,0,g);
var _min = ds_grid_get_min(g,0,0,_w,_h);
// Если хотя бы одна комната не посещена, значть карта непроходима - убираем стенку
if _min==0 then {
ds_map_delete(MAP_walls,val1+"="+val2);
ds_map_delete(MAP_walls,val2+"="+val1);
}
}
ds_list_destroy(l);
ds_grid_destroy(g);
MAP_visit[# MAP_x, MAP_y] = 1;
Банальный обход сетки mapWalk
/// @description walk around the grid
/// @param x
/// @param y
/// @param visits
var _x = argument[0], _y=argument[1];
ds_grid_set(argument[2],_x,_y,1);
var _sl = string(_x)+"|"+string(_y)+"="+string(_x-1)+"|"+string(_y);
var _sr = string(_x)+"|"+string(_y)+"="+string(_x+1)+"|"+string(_y);
var _su = string(_x)+"|"+string(_y)+"="+string(_x)+"|"+string(_y-1);
var _sd = string(_x)+"|"+string(_y)+"="+string(_x)+"|"+string(_y+1);
if _x<ds_grid_width(MAP_grid)-1 && !ds_map_exists(MAP_walls,_sr) && ds_grid_get(argument[2],_x+1,_y)==0
mapWalk(_x+1,_y,argument[2]);
if _x>0 && !ds_map_exists(MAP_walls,_sl) && ds_grid_get(argument[2],_x-1,_y)==0
mapWalk(_x-1,_y,argument[2]);
if _y<ds_grid_height(MAP_grid)-1 && !ds_map_exists(MAP_walls,_sd) && ds_grid_get(argument[2],_x,_y+1)==0
mapWalk(_x,_y+1,argument[2]);
if _y>0 && !ds_map_exists(MAP_walls,_su) && ds_grid_get(argument[2],_x,_y-1)==0
mapWalk(_x,_y-1,argument[2]);
return true;
Почему 50 - потому что начиная с 50 раздача попадает в featured блок наверху страницы, куда будет случайно выдаваться на протяжении всего 4 дней. Почему 4 - потому что только последние 4 дня раздачи так происходит, это их правило.
Зачем? По количеству желающих получить твою игру, хоть и бесплатно, можно судить, игра действительно плохая и никому не нужная, или про неё просто не знает достаточно людей. Я это называю "индекс SteamGifts". Во всяком случае, у нас, у этой игры и у этой игры желающих более 10,000. А вот у какой-то казуалки, от которой сразу раздавали 300,000 ключей, желающих было всего 500, зато такое количество ключей позволяло этой казуалке выскакивать в блоке в 99% случаев, потому что чем больше ключей раздаётся - тем чаще показывается игра.
А всё-таки зачем? Затем что так люди узнают про твою игру самым дешёвым способом из возможных. Те, кому игра сильно понравилась, купят её, даже не участвуя в раздаче. Те, кому она просто понравилась, поучаствуют в раздаче и внесут в вишлист. А вишлист - значит этим людям будут показываться скидки на неё, целой капсулой. Ну и может там ещё что-то, смотря что Valve придумает или поменяет, а то они постоянно всё перелопачивают. Само собой, друзья увидят эту игру в их списке и могут покупать гифты. Ну это конечно долгая история, в основном это приходится на дни рождения и Новые Годы. Долгосрочная перспектива, в общем.
Больших надежд на это возлагать не стоит. Но попробовать - вполне.
Ещё могу предложить поменяться ключами. Мы вам 50 Замков Невозврата 2, вы нам 50 Ghost Croquet'ов. Строго для раздачи на том же СтимГифтс. В описании напишете - ключи взяты у разработчиков, а ещё зацените нашу игрушку вот здесь, и ссылку на неё. Специально пишу сюда, чтоб все видели, какой был уговор, если что.
Люди, подхваченные на раздачах, в целом относятся намного более вежливо и адекватно к полученному, чем типичные зажратые покупатели-геймеры. Да, там есть и халявщики, набивающие карточки, куда же без них. Есть просто школьники. Есть боты. Но где-то там, среди всей этой массы, есть и настоящие игроки. Я так нашёл несколько весьма интересных лично мне людей из эпохи ZX Спектрума и 90-х. Не забывайте проверять комментарии. Хотя, я думаю, у вас-то это проблем не вызовет.
Мы свою игру раздаём тупо каждые 4 дня новые 50 ключей. На продажи не влияет - каждый раз приходят новые тысячи желающих. А вот на вишлисты влияет. Там же я и переводчиков понабирал, половину как минимум. Дискуссию на Стиме мало кто видит, а тут и не купившие резко превращаются в обладателей и сарафанное радио для своих друзей.
Не, срок большой. Да и вот с авторскими правами не очень хорошо. Хотелось бы продолжить игру после конкурса разрабатывать. Буду значит Гаминатора ждать, что поделать... Но спасибо за информацию
В привычном значении слова, у этой игры наверное нет шейдеров. Здесь весь код постпроцессинга картинки прямо в самом коде игры на Си, как и вся игра.
Сама игрушка изначально черно-белая, все ассеты тоже черно белые. Если отрендерить без кода постпроцессинга, то получится вот так:
Дальше каждый пиксель затемняется в зависимости от его глубины в кадре:
И дальше главная функция постпроцессинга опять же проходит про каждому пикселю и заменяет его на один из 8 цветов палитры, попутно применяя кое-какой дизеринг:
get(x, y, r, g, b) и set(x, y, r, b, g) - это соответственно функции чтобы достать и проставить пиксель (x, y)
Если код интересует, то в моём случае это выглядит примерно так:
MAP_init
Map_generate
Банальный обход сетки mapWalk
Я бы лучше вот что предложил.
Идёшь на https://www.steamgifts.com, создаёшь раздачу своей игры на 50 ключей сроком на 4 дня.
Почему 50 - потому что начиная с 50 раздача попадает в featured блок наверху страницы, куда будет случайно выдаваться на протяжении всего 4 дней. Почему 4 - потому что только последние 4 дня раздачи так происходит, это их правило.
Зачем? По количеству желающих получить твою игру, хоть и бесплатно, можно судить, игра действительно плохая и никому не нужная, или про неё просто не знает достаточно людей. Я это называю "индекс SteamGifts". Во всяком случае, у нас, у этой игры и у этой игры желающих более 10,000. А вот у какой-то казуалки, от которой сразу раздавали 300,000 ключей, желающих было всего 500, зато такое количество ключей позволяло этой казуалке выскакивать в блоке в 99% случаев, потому что чем больше ключей раздаётся - тем чаще показывается игра.
А всё-таки зачем? Затем что так люди узнают про твою игру самым дешёвым способом из возможных. Те, кому игра сильно понравилась, купят её, даже не участвуя в раздаче. Те, кому она просто понравилась, поучаствуют в раздаче и внесут в вишлист. А вишлист - значит этим людям будут показываться скидки на неё, целой капсулой. Ну и может там ещё что-то, смотря что Valve придумает или поменяет, а то они постоянно всё перелопачивают. Само собой, друзья увидят эту игру в их списке и могут покупать гифты. Ну это конечно долгая история, в основном это приходится на дни рождения и Новые Годы. Долгосрочная перспектива, в общем.
Больших надежд на это возлагать не стоит. Но попробовать - вполне.
Ещё могу предложить поменяться ключами. Мы вам 50 Замков Невозврата 2, вы нам 50 Ghost Croquet'ов. Строго для раздачи на том же СтимГифтс. В описании напишете - ключи взяты у разработчиков, а ещё зацените нашу игрушку вот здесь, и ссылку на неё. Специально пишу сюда, чтоб все видели, какой был уговор, если что.
Люди, подхваченные на раздачах, в целом относятся намного более вежливо и адекватно к полученному, чем типичные зажратые покупатели-геймеры. Да, там есть и халявщики, набивающие карточки, куда же без них. Есть просто школьники. Есть боты. Но где-то там, среди всей этой массы, есть и настоящие игроки. Я так нашёл несколько весьма интересных лично мне людей из эпохи ZX Спектрума и 90-х. Не забывайте проверять комментарии. Хотя, я думаю, у вас-то это проблем не вызовет.
Мы свою игру раздаём тупо каждые 4 дня новые 50 ключей. На продажи не влияет - каждый раз приходят новые тысячи желающих. А вот на вишлисты влияет. Там же я и переводчиков понабирал, половину как минимум. Дискуссию на Стиме мало кто видит, а тут и не купившие резко превращаются в обладателей и сарафанное радио для своих друзей.
Вот, с гугла и надо было начать поиски или сразу с ютюба. Там и другие видео есть по теме.
Не, срок большой. Да и вот с авторскими правами не очень хорошо. Хотелось бы продолжить игру после конкурса разрабатывать. Буду значит Гаминатора ждать, что поделать... Но спасибо за информацию
у меня длинный список вкладок сайтов которые я просматриваю, чтобы выбрать картинку. )
Хотя в последние время, появился определенный лиддер по ним.
1. http://hello-zombie.tumblr.com/
2. http://rampagedreality.com/
3. http://fashionablygeek.com/
4. http://www.geek-art.net/
5. http://theawkwardgamer.tumblr.com/
6. http://magicalgametime.com/ - эту ссылку, когда-то Нурпхатор просил.
7. http://tepidsloth.com/
8. http://www.ltdartgallery.com/products