Sign in to follow this  
Followers 0

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

2 posts in this topic

Guest
Новичок

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



Одной из самых распространённых задач в программировании являетсявывод данных для пользователей в текстовом виде. При этом вместе с текстом приходится выводить значения каких-либо переменных.
Для подобных задач можно использовать функцию 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.

Edited by Artemio

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Recently Browsing   0 members

    No registered users viewing this page.