MetroidvaniaФорум

Мои наброски тяп-ляп

#0
20:41, 14 ноя 2013

Я пытаюсь думать про свою дву-мерную игру аля Кастельвания-2.

Буду здесь складывать свой бред.

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

#1
21:36, 14 ноя 2013

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

Было-бы круто, если-бы парсер читал более человечный текст свойств.
Например..
5  int  //  мин-урон
10  int  // макс-урон
20  int  // хит-поинты // 10-500
0.5  float// чего-нибудь
Такой текст удобно читать в редакторе кода

#2
22:18, 14 ноя 2013

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

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

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

Движение по рельсу требует сверки позиции юнита с набором Магнитов и других рельсов.
Иногда, юнита нужно оторвать от рельса, или тормознуть продвижение по рельсу.

Проверка ровных отрезков вмеру лёгкая (но есть капля мутности).
Для проверки колизий кривых отрезков, надо их делать прямо-угольными триугами.

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

Автор этапа обязан сам оформить рельс каждому свободному элементу этапа.
Допустим, у таких элементов будет изначальный габарит-квад (bbox),
который можно переделать на личный рельс по силуэту.

#3
22:18, 14 ноя 2013

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

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

номер = получить_клетку( герой.опорная_позиция() );
верш1 = получить_от_клетки( номер);
верш2 = получить_от_клетки( номер +1);
если( фиговая( верш2 ) ) прервать; // вероятно, справа кончилось Поле ячеек.

если( верш1.игрек  как  верш2.игрек)
{
  вычислить_по_ровному_игреку( герой, верш1.игрек );
  прервать;
}

верш3 = создать_пустую;
если( верш1.игрек < верш2.игрек)
{
  верш3.игрек = верш1.игрек;
  верш3.икс = верш2.икс;
}
иначе
{
  верш3.игрек = верш2.игрек;
  верш3.икс = верш1.икс;
}

вычислить_по_триугу( герой, верш1, верш2, верш3 );
прервать;

#4
22:19, 14 ноя 2013

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

// вычислить_по_триугу( герой, верш1, верш2, верш3 )

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

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

// Имеется ввиду клетка_куда_попадают_ноги_героя, чтобы не пропустить героя вниз.
// Подобные вычисления можно провести, чтобы не пропустить героя "куда-то вверх".

Создать  Добавка_икса  = Герой.икс - Икс_левой_грани_клетки;
Создать  Добавка_игрека = Добавка_икса  *  Хранимый_тангенс_клетки;
Создать  Полный_игрек  = Высота_нижней_грани_клетки + Добавка_игрека;
Если( Герой.игрек < Полный_игрек )
Тогда надо поставить героя на Рельсу. // Герой.игрек = Полный_игрек;

// ---
Событие постановки "на рельсу" можно придумать как угодно.
А кое-какое продвижение по рельсу есть здесь..
http://www.gamedev.ru/flame/forum/?id=174531#m6
Искать название процедуры:
void Fgr_privMoveOnDuga

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

Вероятно, все рельсы в Файло-месте, можно при загрузке построить.

#5
22:20, 14 ноя 2013

// Если быстро нажимать атаку

Если игрок не хочет отжимать кнопку Атаки, то рутина управления пускай сама Рапидит,
придерживаясь какого-то интервала.
Можно делать на складывании флоата (дробного числа).
Но лично я привык вычислять интервалы вычитанием (стачиваю к нолю) целого числа.

Снова пробуем цирковой псевдо-код (могут быть баги)..

По_факту_очередного_начала_обновления_игрового_кадра
Начало процедуры

К_нолю( герой.ожидание_атаки ); // остаток мил-секунд ожидания минус колво мил-секунд рисования прошлого кадра

// хочет_атаковать() // внутри этой процедуры выясним прижатые кнопки или их комбинации

Если( герой.хочет_атаковать()  и  герой.ожидание_атаки  как  ноль)
{
  герой.ожидание_атаки_заново( герой.произвести_атаку() );
}

К_нолю( герой.сила_прыжка );

// хочет_прыгать() // внутри этой процедуры выясним прижатые кнопки или их комбинации

Если( герой.хочет_прыгать()  и  герой.сила_прыжка  как  ноль)
{
  герой.сила_прыжка_заново( герой.произвести_прыжок()  );
}


Конец процедуры

#6
1:45, 15 ноя 2013

slatazan
> Было-бы круто, если-бы парсер читал более человечный текст свойств.
> Например..
> 5 int // мин-урон
> 10 int // макс-урон
> 20 int // хит-поинты // 10-500
Может, тип там ни к чему?

#7
18:34, 15 ноя 2013

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

#define frs_( a)  frs >> p->a;  get1310( frs);

int Read_File_Part( std::ifstream& frs, t_Obj* p )
{
  if(! p) return 0;
  getline( frs, s); // комент // начало очередной энтити
  frs_( active)
  frs_( vers)
  // и остальное
return 1;
}
#8
16:57, 17 ноя 2013

slatazan
> Парсеру пофигу на буквы после первого пробела.
Не знал этого, буду привыкать.

#9
20:43, 17 ноя 2013

Sohei
int  это целое число.
float  это дробное число.

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

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

Копаться в ресурсах можно будет только через "родной редактор конструктора".

#10
0:50, 23 ноя 2013

Делаю модуль рюкзака (должен подойти к любому проекту).
Вытаскивать и облагораживать кусок кода из своего проекта - это не легко )))

// "p" это указатель на предмет.

// Предметы попадают в рюкзак, и только потом их можно экипировать.
p = Hero.Bag.get_norm( номер_кнопки ); // Игрок кликнул по топору в Нормальном разделе рюкзака.
Hero.Bag.Replace( p, SLOTBAG_EQUIP); // Пробуем экипировать. Сам предмет должен знать ячейку.


// --- пример попытки засчитать квэст
if( ! Hero.Bag.FindEmpty1() ) return; // нет места в рюкзаке - сдай квэст позже.
// int FindMain( int itemX_name, int needKlv, int include_equip = 0, int boolResult = 0);
int t = Hero.Bag.FindMain( itemReag_Drova1, Delo_KlvNeed, 1, 1); // найти дрова.
if(t)
{  // void FindMain_ButKill( int itemX_name, int needKlv, int include_equip);
  Hero.Bag.FindMain_ButKill( itemReag_Drova1, Delo_KlvNeed, 1); // найти дрова, и удалить их.
  Log( "Работа исполнена." );  Delo_Status += 1;
  if( Hero.Bag.addCrt( itemPot1_Mana1, 2) ) Log( "Получи награду." ); // создать две бутылки.
}

// ---
void SaveTo( FILE* ff);
void LoadFrom( FILE* ff);
MetroidvaniaФорум

Тема в архиве.