В DizzyAge сделано так.
Каждый обьект, наносящий повреждения (а стало быть могущий причинить смерть персонажа) имеет свой код (тип смерти).
Когда Диззи погибает, вызывается или стандартный обработчик восстановления PlayerRespawn(), или, если для данного кода смерти был специальный обработчик, то вызывается специальный.
В стандартном обработчике PlayerRespawn(), координаты Диззи восстанавливаются из переменных P_XSAFE и P_YSAFE. В них хранятся последние запомненные координаты 'стабильного' положения Диззи, т.е. безопасного. Например, когда диззи падает, эти координаты не обновляются. Когда катится головой вниз, хоть он и касается земли, но тоже не обновляются. А вот если встал лапками на твердую землю и при этом в этом месте нет обьектов отнимающих жизнь, то обновляются. Т.е. здесь стоять безопасно, а, стало быть, если чего, то воосстановиться можно отсюда.
Вот пример си-подобного кода из движка с обновлением этих координат:
Перевожу на русский: Если Диззи находится в статусе СТОИТ или ИДЕТ (а есть еще статусы ПРЫГАЕТ, ПАДАЕТ и т.д.), кроме того его позиция стабильная и безопасная (об этом позже), а так же никакой опасный обьект не сбросил флаг безопасности P_SAFE, то обновляем текущие координаты P_XSAFE и P_YSAFE.Код:// Check Respawn Position
status = PlayerGet(P_STATUS);
if( ( status==STATUS_IDLE || status==STATUS_WALK ) &&
IsPlayerSafe() && IsPlayerStable() &&
PlayerGet(P_SAFE) &&
PlayerGet(P_LIFE)>0 )
{
// remember relevant info to use in case of a respawn event
PlayerSet(P_XSAFE,PlayerGet(P_X));
PlayerSet(P_YSAFE,PlayerGet(P_Y));
MusicStore();
}
Безопасность позиции определяется так:
По-русски: Если внутри прямоугольника с Диззи находятся безопасные материалы ВОЗДУХ, ВОДА, ОБЛАКА и т.д.), то функция дает положительный ответ. Соответственно, присутствие других материалов (приносящих смерть, или выталкивающих Диззи выше, например, нахождение внутри твердого обьекта), дают отрицательный ответ.Код:func IsPlayerSafe()
{
matmask = (1<<MAT_AIR)|(1<<MAT_WATER)|(1<<MAT_CLOUD)|(1<<MAT_CLIMB)|(1<<MAT_WIND); // only those are allowed inside player's box
return ( 0 == ( PlayerGet(P_MATINSIDE) & (~matmask) ) ); // no other materials are allowed
}
Стабильность позиции определяется так:
По-русски: Если под лапками персонажами есть как минимум один из материалов ТВЕРДОЕ, ТРАМПЛИН и т.д., то позиция считается стабильной.Код:func IsPlayerStable()
{
matmask = (1<<MAT_BLOCK)|(1<<MAT_JUMPFIX)|(1<<MAT_JUMPPRO)|(1<<MAT_CLIMB); // at least one material with hard density must be under the player
return ( 0 != ( PlayerGet(P_MATUNDER) & matmask ) );
}
Кроме этого, как уже упоминалось выше, любому обьекту, причиняющему повреждения может быть создана своя функция типа PlayerRespawn(). Например, для водоема, в котором никогда нельзя восстанавливаться под водой (например, из-за того, что по сюжету в него можно сигануть без ласт, и застрять), может быть написана функция, в которой координаты игрока после смерти берутся не из P_XSAFE и P_YSAFE, а другие, например, координаты на берегу возле водоема.
Вот и весь алгоритм движка.

