Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 1 из 2 1 2 ПоследняяПоследняя
Показано с 1 по 10 из 20

Тема: UICompass

  1. #1
    Аватар для m1n1vv
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.09.2015
    Сообщений
    541
    Репутация:
    78 ±

    UICompass

    UICompass v0.7


    Данный инклуд предназначен для реализации компаса с стиле PUBG. Он выводит нынешнее направление включая три предыдущих и последующих.

    Все направления в шкале кратны максимальному шагу, MAX_UICOMPASS_STEP. Направление выводится с интервалом. Например при [41 - 47] выведет 45. Поддерживается только нечетное количество TD!

    Реализация TD на вашей стороне.


    • RoundCompassDirection - округляет направление до кратного round.

      PHP код:
      RoundCompassDirection(Float:angleround); 
      • Float:angle - нынешнее направление игрока
      • round - делает число кратным указанному значению

    • CreateCompassString - создает строку с направлением игрока.

      PHP код:
      CreateCompassString(angleround); 
      • angle - направление игрока полученное из RoundCompassDirection
      • round - делает число кратным указанному значению

    • CompassHeadingNorth - определяет, в каком из TD будет выведено "N".

      PHP код:
      CompassHeadingNorth(angle); 
      • angle - направление игрока полученное из RoundCompassDirection


    Директивы По умолчанию Описание
    MAX_UICOMPASS_TD 7 Количество TD, которое будет использоваться в Вашем компасе
    MIN_UICOMPASS_STEP 5 Минимальный шаг компаса
    MAX_UICOMPASS_STEP 15 Максимальный шаг компаса


    Применение:

    Создаем коллбэк для таймера.



    PHP код:
    forward UICompassTimer(playerid);
    public 
    UICompassTimer(playerid)
    {
        static const
            
    step_1 MAX_UICOMPASS_STEP 1,
            
    step_2 MAX_UICOMPASS_STEP 2,
            
    step_3 MAX_UICOMPASS_STEP 3;
            
        static
            
    north,
            
    result,
            
    direction,
            
    Float:angle;

        
    //Узнаем направление игрока
        
    GetPlayerFacingAngle(playeridangle);

        
    //Получаем максимальный шаг компаса
        
    result RoundCompassDirection(angle);

        
    //Получаем минимальный шаг компаса
        
    direction RoundCompassDirection(angleMIN_UICOMPASS_STEP);

        
    //Узнаем, в каком TD будет выведено "N"
        
    north CompassHeadingNorth(result);

        
    //Три предыдущих направления
        
    PlayerTextDrawSetString(playeridtd_uicompass[playerid][0], CreateCompassString(result step_3));
        
    PlayerTextDrawSetString(playeridtd_uicompass[playerid][1], CreateCompassString(result step_2));
        
    PlayerTextDrawSetString(playeridtd_uicompass[playerid][2], CreateCompassString(result step_1));

        
    //Нынешнее направление
        
    PlayerTextDrawSetString(playeridtd_uicompass[playerid][3], CreateCompassString(result));

        
    //Три последующих направления
        
    PlayerTextDrawSetString(playeridtd_uicompass[playerid][4], CreateCompassString(result step_1));
        
    PlayerTextDrawSetString(playeridtd_uicompass[playerid][5], CreateCompassString(result step_2));
        
    PlayerTextDrawSetString(playeridtd_uicompass[playerid][6], CreateCompassString(result step_3));

        
    //Выводим направление кратное минимальному шагу
        
    PlayerTextDrawSetString(playeridtd__compass_dir[playerid], CreateCompassString(directionMIN_UICOMPASS_STEP));

        
    //Устанавливаем всем TD изначальный цвет (Готов выслушать предложения по упрощению)
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][0], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][0]);
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][1], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][1]);
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][2], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][2]);
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][3], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][3]);
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][4], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][4]);
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][5], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][5]);
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][6], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][6]);
        
        
    //Устанавливаем нужному TD желтый цвет, где будет выведено "N"
        
    if (<= north MAX_UICOMPASS_TD)
        {
            
    PlayerTextDrawColor(playeridtd_uicompass[playerid][north], 0xFFFF00FF);
            
    PlayerTextDrawShow(playeridtd_uicompass[playerid][north]);
        }

        return 
    1;

    Автор: m1n1vv
    Скачать/Репозиторий: https://github.com/m1n1vv/UICompass
    Версия: v0.7
    Последний раз редактировалось m1n1vv; 27.12.2017 в 23:52.

  2. 2 пользователя(ей) сказали cпасибо:
    Nurick (18.12.2017) wAx (13.12.2017)
  3. #2
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Взглянул на код, вот проблемы, которые сразу бросились в глаза:
    • Неудачно названные функции. К примеру, в английском языке первым в предложении ставится дополнительное существительное, а после него основное, поэтому корректным названием будет не "GetDirectionCompass", а "GetCompassDirection".
      Настоятельно рекомендую заглянуть сюда, здесь больше примеров в пунктах 14 и 15.

    • Функция названа CompassSetString, но на вход принимает не строку, а число. Это идёт вразрез с логикой, по которой именуются стандартные функции TextDrawSetString и PlayerTextDrawSetString (а на неё ориентируются авторы многих других хорошо выполненных инклудов, так что это не просто пара функций).

    • Магические числа.
      PHP код:
      uic__N 24 uic__N uic__min_N
      Пришлось портатить несколько минут, чтобы понять, что "24" здесь означает "360 / 15". Можно было бы вынести это в отдельную константу ("MAX_UICOMPASS_DIRECTIONS", например).

    • Путаница со сравнением целочисленных и логических значений с 0/false.
      PHP код:
      if (!angle
      Обычно таким образом проверяют логические переменные (или выражения) на равенство false. Из-за этого возникает впечатление, что angle - переменная логического типа, и приходится перемещаться в самый верх инклуда, к объявлению этой переменной, чтобы убедиться в обратном.
      Та же самая проблема, но с проверкой на ненулевое значение:
      PHP код:
      if (uic__diff
      Не ленитесь дописать "== 0" или "!= 0" - это отнимет полсекунды вашего времени, но зато будет понятно, что производится сравнение именно с 0, а не с true/false.

    • Этот отрывок
      PHP код:
          if (angle 360)
              
      angle -= 360;
          else if (
      angle 0)
              
      angle += 360
      можно заменить на
      PHP код:
          angle %= 360
    • Что помешало объявить это как константу?
      PHP код:
          static
              
      getN;

      getN = (UICOMPASS_MAX_TD 1) / 2
    • Табы вперемешку с пробелами. На GitHub это особенно заметно, т.к. там один таб равносилен не 4, а 8 пробелам.
      Бросайте pawno, возьмите нормальный текстовый редактор, который не подсовывает пробелы вместо табов - на форуме есть мануалы по адаптации (1, 2).

    • В коде нет лицензии. Отсутствие лицензии означает отсутствие разрешения на использование кода, т.е. использование сего инклуда по сути незаконно (по крайней мере, такой принцип действует в юрисдикциях США и стран Европы, на счёт кривого российского законодательства не уверен).
      Устранить эту проблему довольно просто: добавьте в начало файла копирайт и текст лицензии (к примеру, я обычно выкладываю свой код под лицензией zlib - она довольно простая и накладывает минимум обязательств на пользователя, но вы вправе выбрать любую другую лицензию).


    Задумка в целом хорошая, но реализация немного хромает. Хотя, справедливости ради стоит отметить объявление локальных переменных с атрибутом static - для одиночных переменных это выгоднее, чем создание переменных в стеке с ключевым словом new, и позволяет немного снизить требования к используемой памяти, но немногие знают об этом приёме.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  4. Пользователь сказал cпасибо:
    m1n1vv (13.12.2017)
  5. #3
    Аватар для m1n1vv
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.09.2015
    Сообщений
    541
    Репутация:
    78 ±
    А если CreateCompassString и RoundCompassDirection?

    Я уже который год использую сублайм.
    Последний раз редактировалось m1n1vv; 14.12.2017 в 01:59.

  6. #4
    Аватар для Fallen A.
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.09.2015
    Адрес
    Минск, БССР
    Сообщений
    236
    Репутация:
    19 ±
    Цитата Сообщение от m1n1vv Посмотреть сообщение
    PHP код:
        //Устанавливаем всем TD изначальный цвет (Готов выслушать предложения по упрощению)
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][0], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][0]);
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][1], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][1]);
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][2], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][2]);
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][3], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][3]);
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][4], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][4]);
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][5], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][5]);
        
    PlayerTextDrawColor(playeridtd_uicompass[playerid][6], 0xFFFFFFFF);
        
    PlayerTextDrawShow(playeridtd_uicompass[playerid][6]); 
    Не?

    PHP код:
        for(new i7i++)
        {
            
    PlayerTextDrawColor(playeridtd_uicompass[playerid][i], 0xFFFFFFFF);
            
    PlayerTextDrawShow(playeridtd_uicompass[playerid][i]);
        } 

  7. #5
    Аватар для m1n1vv
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.09.2015
    Сообщений
    541
    Репутация:
    78 ±
    Цитата Сообщение от Fallen A. Посмотреть сообщение
    Не?

    PHP код:
        for(new i7i++)
        {
            
    PlayerTextDrawColor(playeridtd_uicompass[playerid][i], 0xFFFFFFFF);
            
    PlayerTextDrawShow(playeridtd_uicompass[playerid][i]);
        } 
    Потеря скорости

  8. #6
    Аватар для Fallen A.
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.09.2015
    Адрес
    Минск, БССР
    Сообщений
    236
    Репутация:
    19 ±
    Цитата Сообщение от m1n1vv Посмотреть сообщение
    Потеря скорости
    В таком случае использовать форич.

  9. #7
    Аватар для m1n1vv
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.09.2015
    Сообщений
    541
    Репутация:
    78 ±
    Цитата Сообщение от Fallen A. Посмотреть сообщение
    В таком случае использовать форич.
    Любой цикл приведет к потере скорости. Я хотел бы услышать предложение о функции, которая заменит цвет у предыдущего и последующего TD. +-1 здесь не поможет.

    Что-то вроде такого:

    PHP код:
    stock ReturnColorCompass(&previous, &next)
    {
        static const
            
    max_limit MAX_UICOMPASS_TD 1;

        
    previous uic__N 1;
        
    next uic__N 1;

        
    previous = (previous max_limit) ? (0) : ((previous 0) ? (max_limit) : (previous));
        
    next = (next max_limit) ? (0) : ((next 0) ? (max_limit) : (next));

        return 
    1;

    Не проверял. Сделал на быструю руку.


    UICompass V0.4

    • Изменены названия двух функций:

      • GetDirectionCompass > RoundCompassDirection;
      • CompassSetString > CreateCompassString.

    • Внесены небольшие изменения в работу инклуда.



    UICompass V0.5

    • Добавлена возможность изменения минимального шага. По умолчанию было 15.
      За это отвечает директива: UICOMPASS_STEP.
    Последний раз редактировалось m1n1vv; 16.12.2017 в 21:45.

  10. #8
    Аватар для m1n1vv
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.09.2015
    Сообщений
    541
    Репутация:
    78 ±
    DEL
    Последний раз редактировалось m1n1vv; 15.12.2017 в 12:08.

  11. #9
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от m1n1vv Посмотреть сообщение
    А если CreateCompassString
    Советую вдуматься в смысл слова "Create" и для примера посмотреть, в каких функциях SA-MP это слово используется.


    Цитата Сообщение от m1n1vv Посмотреть сообщение
    и RoundCompassDirection?
    Либо "ToCompassDirection", ведь функция по сути осуществляет конверсию угла.


    Цитата Сообщение от Fallen A. Посмотреть сообщение
    Не?

    PHP код:
        for(new i7i++)
        {
            
    PlayerTextDrawColor(playeridtd_uicompass[playerid][i], 0xFFFFFFFF);
            
    PlayerTextDrawShow(playeridtd_uicompass[playerid][i]);
        } 
    Цитата Сообщение от m1n1vv Посмотреть сообщение
    Потеря скорости
    Куда больше времени уйдёт, к примеру, на вызов нативной функции (т.е. на сохранение состояния виртуальной машины, переход на нативный код и восстановление ВМ, не считая времени выполнения самой функции).
    Но ведь лучше же засорять свой код, чтобы (может быть) сэкономить пару пикосекунд в коде, который выполняется 2-3 раза в секунду, правда?
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  12. #10
    Аватар для m1n1vv
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.09.2015
    Сообщений
    541
    Репутация:
    78 ±
    Значит лучше взять в цикл?

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

    А как тут будет лучше?

    PHP код:
    stock CompassHeadingNorth(angle)
    {
        
    uic__N angle UICOMPASS_STEP;

        if (
    uic__N >= uic__max_N)
            
    uic__N uic__max_directions uic__N uic__min_N;
        else
        {
            
    uic__N -= uic__min_N;
            
    uic__N = ~uic__N 1
        }

        return 
    uic__N;

    PHP код:
    stock CompassHeadingNorth(angle)
    {
        
    angle /= UICOMPASS_STEP;

        return (
    angle >= uic__max_N) ? (uic__max_directions angle uic__min_N) : (~(angle uic__min_N) + 1);

    Последний раз редактировалось m1n1vv; 15.12.2017 в 13:33.

 

 
Страница 1 из 2 1 2 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •