Гость

Урок №2 Форматирование и показ сообщений

В теме 2 сообщения

Форматирование и показ сообщений



Одной из самых распространённых задач в программировании являетсявывод данных для пользователей в текстовом виде. При этом вместе с текстом приходится выводить значения каких-либо переменных.
Для подобных задач можно использовать функцию printf, однако в SA:MP от неё не будет никакого толку: printf выводит текст только в консоль сервера, пользователи (т.е. игроки) этот текст не увидят.

Для вставки в текст значений переменных (форматирования) в SA:MP есть функция format:

format(<строковая переменная>, <размер>, <форматная строка>, <список>)
 

 

  • <строковая переменная> - переменная, в которую будет записан отформатированный текст
  • <размер> - размер строковой переменный (нужен функции, чтобы предотвратить случайный выход за пределы строковой переменной), желательно указывать в виде sizeof(<строковая переменная>)
  • <форматная строка> - строка для вставки значений переменных
  • <список> - значения, которые нужно вставить в форматный текст


Принцип работы функции format схож с принципом работы printf, однако format не выводит отформатированный текст в консоль, а сохраняет его в строковой переменной.

С форматированием разобрались, но как показывать отформатированный текст игрокам?
Для показа сообщений игрокам разработчики SA:MP сделали функции SendClientMessage и SendClientMessageToAll.

 

// отправка сообщения указанному игроку

SendClientMessage(<id игрока>, <цвет>, <строка>)

// отправка сообщения всем игрокам

SendClientMessageToAll(<цвет>, <строка>)
  • <id игрока> - номер игрока, которому требуется показать сообщение
  • <цвет> - число (обычно в шестнадцатеричном представлении), в котором закодирован цвет текста сообщения
  • <строка> - текст сообщения, который будет показан игроку

Чаще всего цвет записывают в форме

0xAARRGGBB
  • A (alpha) - степень прозрачности (от 0 до FF, чем меньше - тем прозрачнее)
  • R (red) - оттенок красного (от 0 до FF)
  • G (green) - оттенок зелёного
  • B (blue) - оттенок синего

Для удобного выбора цвета можно использовать инструмент "Подбор цвета" в программе SimplePawn.


Теперь перейдём к практике.
Сделаем простую команду /stats, в которой выведем игроку его ID, имя и кол-во игровых очков:

CMD:stats(playerid, params[])
{
    // строковая переменная для хранения имени игрока, длиной в
    // MAX_PLAYER_NAME (константа из a_samp.inc, обозначающая макс.
    // длину имени игрока) + 1 ячейка под завершающий нуль-символ
    new playername[MAX_PLAYER_NAME+1];

    // получаем кол-во игровых очков с помощью функции GetPlayerScore
    new score = GetPlayerScore(playerid);

    // строка для форматирования сообщения
    new string[128];

    // получить имя игрока
    GetPlayerName(playerid, playername, sizeof(playername));

    // форматирование текста сообщения
    format( string, sizeof(string), "ID: %d, имя: %s, очки: %d",
            playerid, playername, score);

    // вывод сообщения игроку
    SendClientMessage(playerid, 0xFFFFFFFF, string);

    // завершение работы команды
    return 1;
}

 

Разберём некоторые детали:

  • Количество игровых очков мы узнаём с помощью функции GetPlayerScore, которая имеет следующий синтаксис:
  • GetPlayerScore(<id игрока>)

     

  • Имя игрока получаем с помощью функции GetPlayerName:
  • GetPlayerName(<id игрока>, <строковая переменная>, <размер>)

     

  • Число 0xFFFFFFFF означает белый цвет (alpha=255 (FF), R=255, G=255, B=255).

Теперь посмотрим на вышеприведённый код ещё раз, многие вещи можно упростить:

  1. Вместо playername можно получать имя игрока в строковую переменную string, после чего строка может участвовать в форматировании (format) самой себя.
  2. Использовать переменную score необязательно, вместо этого можно подставить вызов функции GetPlayerScore напрямую в format.

Теперь упростим код:

CMD:stats(playerid, params[])
{
    static const fmt_str[] = "ID: %d, имя: %s, очки: %d";
    new string[sizeof(fmt_str)-2+4-2+MAX_PLAYER_NAME-2+11];
    GetPlayerName(playerid, string, sizeof string );
    format( string, sizeof string , fmt_str, playerid, string, GetPlayerScore(playerid));
    SendClientMessage(playerid, 0xFFFFFFFF, string);
    return 1;
}

Но даже после этого остаётся один серьёзный недочёт: размер переменной string оставляет желать лучшего. Однако, вручную подсчитывать необходимый размер строковой переменной - не самая простая задача. К тому же, если нужно будет изменить форматный текст, придётся пересчитывать размер строки заново.
Впрочем, выход есть. Сделаем так, чтобы компилятор сам подсчитал необходимый размер строки:

CMD:stats(playerid, params[])
{
    static const fmt_str[] = "ID: %d, имя: %s, очки: %d";
    new string[sizeof(fmt_str)-2+4-2+MAX_PLAYER_NAME-2+11];
    GetPlayerName(playerid, string, sizeof string );
    format( string, sizeof string , fmt_str, playerid, string, GetPlayerScore(playerid));
    SendClientMessage(playerid, 0xFFFFFFFF, string);
    return 1;
}

Принцип работы:

Создаётся строковая константа fmt_str (сокр. от "format string" - форматная строка), чтобы компилятор мог подсчитать её размер с помощью оператора sizeof.
Затем от размера строки отнимается 2 (длина "%d", "%s" и т.п. отрывков) и прибавляется максимальная длина форматируемого значения: для чисел это 11 (минимальное отрицательное значение: -2147483647 - 11 символов), для имён игроков - MAX_PLAYER_NAME, для ID игроков - на данный момент 3 (в коде поставлено 4, чтобы не пришлось его переделывать, если в будущих версиях SA:MP будет более 1000 игроков, who knows...).
В результате получаем необходимую длину переменной string.

Отредактировано пользователем Artemio

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

@Artemio, про спецификаторы было бы неплохо сказать. Сделать это можно даже в WIKI: тык.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!


Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.


Войти

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу