PDA

Просмотр полной версии : [Вопрос] Расстояние между двумя игроками.



Wise
14.11.2015, 16:42
Здравствуйте. Эта функция ещё актуальная? Или есть что-нибудь попроще, чтобы узнать расстояние между 2мя игроками?

stock Float:GetDistanceBetweenPlayers(p1,p2)
{
new Float:x1,Float:y1,Float:z1,Float:x2,Float:y2,Float:z2;
if(!IsPlayerConnected(p1) || !IsPlayerConnected(p2)) return -1.00;
GetPlayerPos(p1,x1,y1,z1);
GetPlayerPos(p2,x2,y2,z2);
return floatsqroot(floatpower(floatabs(floatsub(x2,x1)),2)+floatpower(floatabs(floatsub(y2,y1)),2)+floatpower(floatabs(floatsub(z2,z1)),2));
}

Daniel_Cortez
14.11.2015, 17:17
1. Использование IsPlayerConnected не обязательно, т.к. во всех функциях, выполняющих действия с игроками, есть встроенные проверки подключения.
Взять, например, GetPlayerPos: эта функция возвращает координаты игрока косвенно, через передаваемые ей аргументы. Сама же она возвращает ещё и статус подключения игрока: 1, если подключен, иначе - 0.


new x1, y1, z1, x2, y2, z2;
if((0 == GetPlayerPos(p1,x1,y1,z1) || (0 == GetPlayerPos(p2,x2,y2,z2)))
return -1.00;

2. http://pro-pawn.ru/showthread.php?6407-VectorSize

Wise
14.11.2015, 17:33
Воспользовался вторым пунктом. Немного переделал пример, получил вот такую функцию:

stock Float:GetDistanceBetweenPlayers(u1, u2)
{
new Float:coor_one[3], Float:coor_two[3];
GetPlayerPos(u1, coor_one[0], coor_one[1], coor_one[2]);
GetPlayerPos(u2, coor_two[0], coor_two[1], coor_two[2]);
return VectorSize(coor_one[0]-coor_two[0], coor_one[1]-coor_two[1], coor_one[2]-coor_two[2]);
}
В принципе работает также, как и первый пункт. Спасибо большое.

UPD: Если кто-то возьмёт себе, из-за стока будет ошибка. Добавьте forward.

forward Float:GetDistanceBetweenPlayers(u1, u2);
public Float:GetDistanceBetweenPlayers(u1, u2)
{
new Float:coor_one[3], Float:coor_two[3];
GetPlayerPos(u1, coor_one[0], coor_one[1], coor_one[2]);
GetPlayerPos(u2, coor_two[0], coor_two[1], coor_two[2]);
return VectorSize(coor_one[0]-coor_two[0], coor_one[1]-coor_two[1], coor_one[2]-coor_two[2]);
}

Daniel_Cortez
14.11.2015, 18:04
new Float:coor_one[3], Float:coor_two[3];
http://pro-pawn.ru/showthread.php?12821

И да, где проверка на подключение? Если хотя бы один из игроков не подключен, функция будет возвращать некорректные результаты.
Неужели вам настолько лень сделать так, как советуют, и поставить одну строчку с if?

Btw, накопал тут ещё одну функцию: GetPlayerDistanceFromPoint.

Wise
14.11.2015, 18:21
Перед тем, как написать тему, я использовал поиск. Функцию GetPlayerDistanceFromPoint я находил, она мне не подходит. На счёт вашего замечания, я просто поспешил. Исправил.

forward Float:GetDistanceBetweenPlayers(u1, u2);
public Float:GetDistanceBetweenPlayers(u1, u2)
{
new Float:x1, Float:y1, Float:z1,
Float:x2, Float:y2, Float:z2;
if((0 == GetPlayerPos(u1, x1, y1, z1) || (0 == GetPlayerPos(u2, x2, y2, z2)))) return -1.00;
GetPlayerPos(u1, x1, y1, z1);
GetPlayerPos(u2, x2, y2, z2);
return VectorSize(x1-x2, y1-y2, z1-z2);
}

Daniel_Cortez
14.11.2015, 18:52
if((0 == GetPlayerPos(u1, x1, y1, z1) || (0 == GetPlayerPos(u2, x2, y2, z2)))) return -1.00;
GetPlayerPos(u1, x1, y1, z1);
GetPlayerPos(u2, x2, y2, z2);

Зачем узнавать координаты 2 раза подряд? Вы их уже узнаёте в if.



Перед тем, как написать тему, я использовал поиск. Функцию GetPlayerDistanceFromPoint я находил, она мне не подходит.
Значит плохо искали.
Единственный минус в GetPlayerDistanceFromPoint: она возвращает значение напрямую, а не через аргумент, поэтому придётся отдельно проверять подключение одного из игроков с помощью IsPlayerConnected.


if(0 == IsPlayerConnected(p1))
return -1.00;
new Float:x, Float:y, Float:z;
if(0 == GetPlayerPos(p2, x, y, z))
return 1.00;
return GetPlayerDistanceFromPoint(targetid, x, y, z);

В итоге чуть больше строк кода, но львиная доля времени отнимется на вызов нативных функций SA:MP (не на выполнение функций, а именно на сам их вызов, т.е. на процесс перехода с интерпретируемого кода на нативный и обратно).
Здесь этих вызовов так же 3, как и в варианте с VectorSize. Зато этот вариант менее требователен к стеку: 3 локальных переменных против 6.