Просмотр полной версии : [Вопрос] Метки на радаре
PawnoNoob
10.07.2016, 23:09
Всем привет. Я уверен в том, что этот вопрос задавался несколько десятков (а может и сотен) раз, да и ответ на этот вопрос давался столько же, но, к сожалению, конкретно этого вопроса я не нашёл на просторах этого форума (да и в поисковой системе тоже что-то не удалось найти). Так вот, всё опишу ниже.
Что я делал до того, как задать этот вопрос:
ShowPlayerMarkers(PLAYER_MARKERS_MODE_STREAMED);
После всего этого метка начала действительно пропадать, но уже ближе к концу самой пирамиды (чистый new.pwn), а это довольно-таки многовато для меня. Как уменьшить это расстояние?
И я так и не понял, за что отвечает функция LimitPlayerMarkerRadius? В Wiki написано, что устанавливает радиус этой метки, а на стороннем портале пишут следующее: "Функция определяет, на каком расстоянии будет виден маркер.".
И я так и не понял, за что отвечает функция LimitPlayerMarkerRadius? В Wiki написано, что устанавливает радиус этой метки, а на стороннем портале пишут следующее: "Функция определяет, на каком расстоянии будет виден маркер.".
Самым лучшим способом будет просто взять и проверить, не?
Не уверен, что кто-то из форумчан часто работал с этой функцией и даст тебе точный ответ
PawnoNoob
10.07.2016, 23:23
Самым лучшим способом будет просто взять и проверить, не?
Не уверен, что кто-то из форумчан часто работал с этой функцией и даст тебе точный ответ
Вот именно, что проверял, да и не раз, результата вообще никакого не заметил, ставил и 10.0, и 20.0. Эффекта по-моему вообще никакого нет.
LimitPlayerMarkerRadius - устанавливает радиус (расстояние игрока от другого игрока, при котором появится метка на карте) показа метки
В Wiki написано, что устанавливает радиус этой метки
и
"Функция определяет, на каком расстоянии будет виден маркер."
имеется ввиду одно и то же
PawnoNoob
10.07.2016, 23:34
LimitPlayerMarkerRadius - устанавливает радиус (расстояние игрока от другого игрока, при котором появится метка на карте) показа метки
и
имеется ввиду одно и то же
Хм, эти две функции нужно использовать вместе? Типа:
ShowPlayerMarkers(PLAYER_MARKERS_MODE_STREAMED);
LimitPlayerMarkerRadius(например, 50.0);
Или как-то по-другому?
Вот именно, что проверял, да и не раз, результата вообще никакого не заметил, ставил и 10.0, и 20.0. Эффекта по-моему вообще никакого нет.
Сам я с этой функцией работал, примерно, году в 13-ом последний раз и, как мне помнится, тоже не добился желаемого успеха.
Если ничего не получится, можешь попробовать сделать свой костыль в виде прикрепления к каждому игроку динамической зоны и использовании вот такой функции:
stock TogglePlayerOnMapForPlayer(playerid, showplayerid, bool:visible) SetPlayerMarkerForPlayer(playerid, showplayerid, (GetPlayerColor(showplayerid) | 0xFF) - (visible ? 0x00 : 0xFF));
//Функцию набросал прямо тут и не уверен, что угадал с правильностью playerid и showplayerid
То бишь, игрок один игрок зашёл в зону другого и для того, кто зашёл:
TogglePlayerOnMapForPlayer(playerid, giveplayerid, true);// playerid - кто зашёл в зону, giveplayerid - к кому зашли в зону
// Покажет иконку showplayerid для playerid
И когда вышел
TogglePlayerOnMapForPlayer(playerid, giveplayerid, false);
Так сможешь чуть ли не прямо в игре регулировать расстояние прорисовки иконок.
Позже, мб, инк напишу с этой системой, если никто не опередит и если SetPlayerMarkerForPlayer вообще работает
Стоит немного поискать и можно найти подобные сообщения где-то ещё (http://forum.sa-mp.com/showthread.php?t=563915)
Я изучил работу этих маркеров и выяснил, что значение PLAYER_MARKERS_MODE_STREAM отвечает за отображение маркеров игроков в стриме (как очевидно из названия), а маркеры в зоне стрима отрисовываются на стороне клиента.
Значение PLAYER_MARKERS_MODE_GLOBAL запускает функцию постоянного обновления маркеров раз в 2.5 секунды. Именно в эту функцию идёт значение, переданное с помощью LimitPlayerMarkerRadius (значение, кстати, идёт в квадрате, видимо изначально Kye хотел обойтись без sqrt в вычислении расстояния, но потом забыл убрать возведение в квадрат).
То есть за отрисовку маркеров игроков в стриме отвечает клиент, а в глобале - сервер, именно поэтому при покидании зоны стрима иконка на карте появляется не сразу.
Из-за того, что клиент автоматически удаляет глобальный маркер при входе в стрим, исправить работу стандартных маркеров не представляется возможным. Хотя что стоит добавить вызов функции обновления маркеров при входе/выходе игрока в/из стрима, что исправит задержку между появлениями маркеров, и что стоит добавить передачу расстояния из LimitPlayerMarkerRadius в клиент и поставить одну небольшую проверку на расстояние? Эх...
Кстати, функция SetPlayerMarkerForPlayer - всего лишь SetPlayerColorForPlayer, то есть эта функция изменяет цвет одного игрока для другого.
Отвечаю на вопрос автора:
И я так и не понял, за что отвечает функция LimitPlayerMarkerRadius?
Функция LimitPlayerMarkerRadius отвечает за расстояние (точнее за квадрат расстояния) на котором будет отрисовываться маркеры игроков, которые находятся вне стрима. Эту функцию имеет смысл использовать только в режиме PLAYER_MARKERS_MODE_GLOBAL.
Кстати, функция SetPlayerMarkerForPlayer - всего лишь SetPlayerColorForPlayer, то есть эта функция изменяет цвет одного игрока для другого.
Так я и хотел работать с иконками путём изменения цвета одного игрока для другого. Точнее, изменения насыщенности, которая отвечает за прозрачность иконки на радаре.
Так я и хотел работать с иконками путём изменения цвета одного игрока для другого. Точнее, изменения насыщенности, которая отвечает за прозрачность иконки на радаре.
Дак я ничего и не говорю, это единственный вариант.
PawnoNoob
11.07.2016, 20:49
Теперь знаю больше, спасибо огромное за помощь :thank_you:
Я тут вчера набросал реализацию своей идеи (начал делать заготовку для инклюда) и вот что вышло (может кому пригодится)
#if !defined DEFAULT_PLAYER_MARKER_RADIUS
#define DEFAULT_PLAYER_MARKER_RADIUS 300.0
#endif
enum e_PLAYER_MARKER_INFO
{
mark_id,
Float:mark_radius,
transparent
}
new pl_mark[MAX_PLAYERS][e_PLAYER_MARKER_INFO];
stock TogglePlayerOnMapForPlayer(playerid, showplayerid, bool:visible)
{
new map_color = GetPlayerColor(showplayerid);
if((map_color & 0xFF) != 0x00) pl_mark[playerid][transparent] = map_color & 0xFF;
SetPlayerMarkerForPlayer(playerid, showplayerid, (map_color | 0xFF) - (visible ? 0x00 : pl_mark[playerid][transparent]));
return 1;
}
stock UpdateRadiusForPlayerMarker(playerid, Float:radius)
{
if(pl_mark[playerid][mark_id] == -1) return 0;
pl_mark[playerid][mark_radius] = radius;
DestroyDynamicArea(pl_mark[playerid][mark_id]);
printf("\n%d", pl_mark[playerid][mark_id] = CreateDynamicSphere(0.0, 0.0, 0.0, pl_mark[playerid][mark_radius], -1, -1, -1));
printf("%d\n", AttachDynamicAreaToPlayer(pl_mark[playerid][mark_id], playerid));
return 1;
}
cmd:radius(playerid, params[])
{
if(isnull(params) || !(params[0] >= '0' && params[0] <= '9')) return SendClientMessage(playerid, -1, "Введите радиус");
new Float: radius = float(strval(params));
new string[30];
foreach(new i: Player)
{
format(string, sizeof(string), "%d", UpdateRadiusForPlayerMarker(playerid, radius));
SendClientMessage(playerid, -1, string);
}
return 1;
}
public OnGameModeInit()
{
ShowPlayerMarkers(PLAYER_MARKERS_MODE_GLOBAL);
LimitPlayerMarkerRadius(10000.0);
for(new i; i < sizeof(pl_mark); i++)
{
pl_mark[i][mark_id] = -1;
pl_mark[i][transparent] = 0xFF;
pl_mark[i][mark_radius] = DEFAULT_PLAYER_MARKER_RADIUS;
}
return 1;
}
public OnPlayerSpawn(playerid)
{
if(pl_mark[playerid][mark_id] == -1)
{
pl_mark[playerid][mark_id] = CreateDynamicSphere(0.0, 0.0, 0.0, pl_mark[playerid][mark_radius], -1, -1, -1);
AttachDynamicAreaToPlayer(pl_mark[playerid][mark_id], playerid);
}
SetPlayerPos(playerid, 1830.3783, 1340.1572, 14.3746);
return 1;
}
public OnPlayerDisconnect(playerid, reason)
{
if(pl_mark[playerid][mark_id] != -1)
{
DestroyDynamicArea(pl_mark[playerid][mark_id]);
pl_mark[playerid][mark_id] = -1;
}
pl_mark[playerid][transparent] = 0xFF;
return 1;
}
public OnPlayerEnterDynamicArea(playerid, areaid)
{
new string[30];
foreach(new i: Player)
{
if(i == playerid) continue;
if(areaid != pl_mark[i][mark_id]) continue;
TogglePlayerOnMapForPlayer(i, playerid, true);
format(string, sizeof(string), "%d показан для %d", playerid, i);
SendClientMessageToAll(-1, string);
}
return 1;
}
public OnPlayerLeaveDynamicArea(playerid, areaid)
{
new string[30];
foreach(new i: Player)
{
if(i == playerid) continue;
if(areaid != pl_mark[i][mark_id]) continue;
TogglePlayerOnMapForPlayer(i, playerid, false);
format(string, sizeof(string), "%d скрыт для %d", playerid, i);
SendClientMessageToAll(-1, string);
}
return 1;
}
Код чисто написан для теста (некоторая "ненужная" информация выдаётся в чат и прочее) и я сразу пытался адаптировать его под расширенные возможности (обновлять радиус отображения маркеров для всех/определённого игрока прямо в игре и т.п.). В общем, чисто на посмотреть.
P.S. Тестировал всё на одном компьютере с использованием песочницы и заметил, что то ли функция AttachDynamicAreaToPlayer отказывается крепить зону к игроку, который АФК, то ли OnPlayerEnterDynamicArea/OnPlayerLeaveDynamicArea как-то отказывается срабатывать нормально, но смысл в том, что если попробовать обновить радиус зон (пока реализовано обновление для всех сразу) и кто-то будет стоять АФК, система начнёт глючить (у АФК-шника радиус зоны останется старым).
Вполне возможно, что это косяк моего кода. Вчера просто не было времени проверить. Просто если кто-то решит копаться в моём говнокоде, имейте это ввиду.
И да, я, похоже, стандартные маркеры настроил немного неверно. В общем, работать ещё есть над чем :3
UPD: Бага с AFK никакого нет. Всему виной мои кривые руки и невнимательность. Скоро запилю инклюд
LimitPlayerMarkerRadius лучше убрать, чтобы внутренний стриммер не рассчитывал дистанцию.
Powered by vBulletin® Version 4.2.0 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot