Доступ к готовым решениям

Переход в группу "Пользователь"

300.00
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

Мануал Лазаем по лестницам и стенам

OKStyle

Адвокат по делам семейным
Administrator
Wiki Team
Регистрация
4 Мар 2011
Сообщения
7,094
Лучшие ответы
226
Репутация
2,455
Награды
11
Суть системы: игрок может лазать по лестницам и стенам, по любым поверхностям и вообще везде, где вы захотите. Реализовано в виде связки анимций, телепорта и работы с текстдравами. Пока готовится к релизу мой ФС, решил накидать такое решение, чтобы потом не было вопросов типа: "как добавить ещё лестницы?", "как выставить угол?" и т.п. Конструктив системы был взят с моего решения Chinatown Wars Teleport.

Для начала создадим необходимые переменные. У нас это связка текстдравов и координаты одной из поверхностей.
PHP:
new Text:BlackScreen[6], Float:LadderCoords[2][4] = {
    {-1844.9794, 581.0343, 35.1683, 237.8849}, // подножие поверхности
    {-1844.0436, 580.2306, 242.0142, 237.8849} // конечная точка
};
Как вы видите, угол поворота игрока тоже включён в массив. Пренебрегать им крайне не рекомендуется, т.к. сама система распределения поворотов и анимаций строится именно на нём.

Создадим текстдравы, элементы которых мы обозначили выше. На всякий пожарный добавил пикап с инфой (здание находится в СФ - с чёрными стенами, возле Cluckin' Bell):
PHP:
CreatePickup(1239, 23, -1844.9794, 581.0343, 35.1683, -1);

Create3DTextLabel("Встаньте на пикап\nи нажмите ~k~~SNEAK_ABOUT~", 0x008080FF, -1844.9794, 581.0343, 35.1683, 40.0, 0, 0);

BlackScreen[0] = TextDrawCreate(642.0, 1.0, "~n~");
TextDrawLetterSize(BlackScreen[0], 0.5, 49.5);
TextDrawUseBox(BlackScreen[0], 1);
TextDrawBoxColor(BlackScreen[0], 0x000000AA);
TextDrawTextSize(BlackScreen[0], -2.0, 0.0);

BlackScreen[1] = TextDrawCreate(642.0, 1.0, "~n~");
TextDrawLetterSize(BlackScreen[1], 0.5, 49.5);
TextDrawUseBox(BlackScreen[1], 1);
TextDrawBoxColor(BlackScreen[1], 0x000000BB);
TextDrawTextSize(BlackScreen[1], -2.0, 0.0);

BlackScreen[2] = TextDrawCreate(642.0, 1.0, "~n~");
TextDrawLetterSize(BlackScreen[2], 0.5, 49.5);
TextDrawUseBox(BlackScreen[2], 1);
TextDrawBoxColor(BlackScreen[2], 0x000000CC);
TextDrawTextSize(BlackScreen[2], -2.0, 0.0);

BlackScreen[3] = TextDrawCreate(642.0, 1.0, "~n~");
TextDrawLetterSize(BlackScreen[3], 0.5, 49.5);
TextDrawUseBox(BlackScreen[3], 1);
TextDrawBoxColor(BlackScreen[3], 0x000000DD);
TextDrawTextSize(BlackScreen[3], -2.0, 0.0);

BlackScreen[4] = TextDrawCreate(642.0, 1.0, "~n~");
TextDrawLetterSize(BlackScreen[4], 0.5, 49.5);
TextDrawUseBox(BlackScreen[4], 1);
TextDrawBoxColor(BlackScreen[4], 0x000000EE);
TextDrawTextSize(BlackScreen[4], -2.0, 0.0);

BlackScreen[5] = TextDrawCreate(642.0, 1.0, "~n~");
TextDrawLetterSize(BlackScreen[5], 0.5, 49.5);
TextDrawUseBox(BlackScreen[5], 1);
TextDrawBoxColor(BlackScreen[5], 0x000000FF);
TextDrawTextSize(BlackScreen[5], -2.0, 0.0);
Кому нужно - напишите отдельный код выгрузки текстдравов, пикапа и 3д-текста.

Теперь самое интересное. У меня начало движения начинается по нажатию клавиши (можете сделать и команду).
PHP:
if(newkeys & KEY_WALK) // если клавиша - идти пешком
{
    for(new i = 0; i < sizeof(LadderCoords); i++) // пробегаемся по массиву с координатами
    {
        if(IsPlayerInRangeOfPoint(playerid, 1, LadderCoords[i][0], LadderCoords[i][1], LadderCoords[i][2])) // если находимся в радиусе ближайших координат
        {
            SetPlayerPos(playerid, LadderCoords[i][0], LadderCoords[i][1], LadderCoords[i][2]); // выравниваем позицию
            SetCameraBehindPlayer(playerid); // сбрасываем камеру
            SetPVarInt(playerid, "Iteration", 15); // выставляем задержку перед телепортом на конечные координаты
            SetTimerEx("Ladder", 100, 0, "i", playerid); // запускаем систему подъёма
            SetPVarInt(playerid, "LadderID", i); // указываем порядковый номер лестницы/поверхности
            break; // обрываем цикл, т.к. ближайшие координаты найдены и нужные нам действия уже выполняются
        }
    }
}
Ну и сами управляющие таймеры:
PHP:
forward Ladder(playerid);
public Ladder(playerid)
{
    new iter = GetPVarInt(playerid, "Iteration"), ladderid = GetPVarInt(playerid, "LadderID");
    if(iter > 0)
    {
        switch(iter)
        {
            case 12:
            {
                new Float:a;
                GetPlayerFacingAngle(playerid, a);
                if(a > LadderCoords[ladderid][3] - 181.0 && a < LadderCoords[ladderid][3] + 1.0) // если угол в правую сторону
                {
                    SetPlayerFacingAngle(playerid, LadderCoords[ladderid][3] + 90.0); // выставляем нужный угол для адекватной анимации
                    ApplyAnimation(playerid, "DOZER", "DOZER_Align_LHS", 3.5, 0, 1, 1, 1, 1000, 1);
                }
                else
                {
                    SetPlayerFacingAngle(playerid, LadderCoords[ladderid][3] - 90.0);
                    ApplyAnimation(playerid, "DOZER", "DOZER_Align_RHS", 3.5, 0, 1, 1, 1, 1000, 1);
                }
                SetTimerEx("NoAnim", 1000, 0, "i", playerid); // выставляем таймер сброса анимации, чтобы не было фриза по её окончанию
            }
            case 6: TextDrawShowForPlayer(playerid, BlackScreen[0]); // отсюда начинается затемнение экрана текстдравами
            case 5:
            {
                TextDrawHideForPlayer(playerid, BlackScreen[0]);
                TextDrawShowForPlayer(playerid, BlackScreen[1]);
            }
            case 4:
            {
                TextDrawHideForPlayer(playerid, BlackScreen[1]);
                TextDrawShowForPlayer(playerid, BlackScreen[2]);
            }
            case 3:
            {
                TextDrawHideForPlayer(playerid, BlackScreen[2]);
                TextDrawShowForPlayer(playerid, BlackScreen[3]);
            }
            case 2:
            {
                TextDrawHideForPlayer(playerid, BlackScreen[3]);
                TextDrawShowForPlayer(playerid, BlackScreen[4]);

            }
            case 1:
            {
                TextDrawHideForPlayer(playerid, BlackScreen[4]);
                TextDrawShowForPlayer(playerid, BlackScreen[5]);
                SetPlayerPos(playerid, LadderCoords[ladderid + 1][0], LadderCoords[ladderid + 1][1], LadderCoords[ladderid + 1][2]); // Выставляем игроку конечную позицию
            }
        }
        SetPVarInt(playerid, "Iteration", iter - 1); // понижаем итерацию (круг обхода таймера)
        SetTimerEx("Ladder", 100, 0, "i", playerid); // заново запускаем таймер
    }
    else if(iter == 0) // если итерации закончились
    {
        SetPlayerFacingAngle(playerid, LadderCoords[ladderid][3]); // выставляем нужный угол (обычно такой же, как и в начальной точке)
        TextDrawHideForPlayer(playerid, BlackScreen[5]); // прячем текстдрав
        ApplyAnimation(playerid, "PED", "CLIMB_Stand", 4.1, 0, 1, 1, 1, 1000, 1); // проигрываем конечную анимацию
        SetTimerEx("NoAnim", 500, 0, "i", playerid); // выставляем таймер очистки анимации
        DeletePVar(playerid, "LadderID"); // Удаляем ненужные PVar'ы
        DeletePVar(playerid, "Iteration");
    }
    return 1;
}
forward NoAnim(playerid);
public NoAnim(playerid) return ClearAnimations(playerid);
Вот и вся система. Аналогов, особенного такого уровня, не существует.

Автор: OKStyle
 
Сверху Снизу