PDA

Просмотр полной версии : [Function] GetPlayerFacingDirection - узнаём в какую сторону света смотрит игрок (компас)



DeimoS
09.12.2016, 14:37
Описание:

Функция узнаёт в какую сторону света смотрит игрок.

Параметры:

playerid - ID игрока
Float:facing_angle - Текущее направление взгляда игрока (необязательный параметр)
Второй параметр позволяет заранее указать направление взгляда игрока. Он сделан на случай, если Вы в своём коде уже вызывали GetPlayerFacingAngle до того, как вызвали мою функцию.

То бишь у Вас есть, например, такой код:

new Float:facing_angle;
GetPlayerFacingAngle(playerid, facing_angle);
//Тут Ваш остальной код, в котором Вы используете значение facing_angle
//И теперь Вам нужно узнать сторону света, в которую смотрит игрок.
//Вы можете сразу прописать направление взгляда во втором параметре, тем самым "отключив" вызов функции
//GetPlayerFacingAngle внутри GetPlayerFacingDirection

GetPlayerFacingDirection(playerid, facing_angle);


Если же этого не сделать (не указать второй параметр), вызов GetPlayerFacingAngle случится внутри самой функции GetPlayerFacingDirection. То бишь, можно сделать так:


public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if(newkeys & KEY_YES)
SendClientMessage(playerid, -1, side_of_the_world_list[GetPlayerFacingDirection(playerid)]);
return 1;
}
И теперь, при нажатии на "Y", в чат будет писать сторону света, в которую смотрит игрок.

Возвращаемое значение:

0 (DIRECTION_NORTH) - Игрок смотрит на Север
1 (DIRECTION_NORTH_WEST) - Игрок смотрит на Северо-Запад
2 (DIRECTION_WEST) - Игрок смотрит на Запад
3 (DIRECTION_SOUTH_WEST) - Игрок смотрит на Юго-Запад
4 (DIRECTION_SOUTH) - Игрок смотрит на Юг
5 (DIRECTION_SOUTH_EAST) - Игрок смотрит на Юго-Восток
6 (DIRECTION_EAST) - Игрок смотрит на Восток
7 (DIRECTION_NORTH_EAST) - Игрок смотрит на Северо-Восток

Код:




enum
{
DIRECTION_NORTH = 0,
DIRECTION_NORTH_WEST = 1,
DIRECTION_WEST = 2,
DIRECTION_SOUTH_WEST = 3,
DIRECTION_SOUTH = 4,
DIRECTION_SOUTH_EAST = 5,
DIRECTION_EAST = 6,
DIRECTION_NORTH_EAST = 7
};



stock GetPlayerFacingDirection(playerid, Float:facing_angle = -1.0)
{
static const
Float: side_of_the_world = 20.0,// Минимум: 0.0, Максимум - 45.0
Float: coord_indent = 0.1;

new const
Float: north_coord_min = 360.0-side_of_the_world,
Float: north_coord_max = 0.0+side_of_the_world,

Float: west_coord_min = 90.0-side_of_the_world,
Float: west_coord_max = 90.0+side_of_the_world,

Float: south_coord_min = 180.0-side_of_the_world,
Float: south_coord_max = 180.0+side_of_the_world,

Float: east_coord_min = 270.0-side_of_the_world,
Float: east_coord_max = 270.0+side_of_the_world;


if(!floatcmp(facing_angle, -1.0))
GetPlayerFacingAngle(playerid, facing_angle);
else if(floatcmp(facing_angle, 0.0) == -1)
facing_angle = 0.0;
else if(floatcmp(facing_angle, 360.0) == 1)
facing_angle = 360.0;

if(north_coord_min <= facing_angle <= 360.0 || 0.0 <= facing_angle <= north_coord_max)
return DIRECTION_NORTH;
else if(north_coord_max+coord_indent <= facing_angle <= west_coord_min-coord_indent)
return DIRECTION_NORTH_WEST;

else if(west_coord_min <= facing_angle <= west_coord_max)
return DIRECTION_WEST;
else if(west_coord_max+coord_indent <= facing_angle <= south_coord_min-coord_indent)
return DIRECTION_SOUTH_WEST;

else if(south_coord_min <= facing_angle <= south_coord_max)
return DIRECTION_SOUTH;
else if(south_coord_max+coord_indent <= facing_angle <= east_coord_min-coord_indent)
return DIRECTION_SOUTH_EAST;

else if(east_coord_min <= facing_angle <= east_coord_max)
return DIRECTION_EAST;
else //if(east_coord_max+coord_indent <= facing_angle <= north_coord_min-coord_indent)
return DIRECTION_NORTH_EAST;
}



Настройки:

В функции предусмотрена возможность настроить "чувствительность" поиска той или иной стороны света.
Настраивается она через константу "side_of_the_world".
Чем выше значение данной переменной, тем больше градусов выделяется под "основные" стороны света ("Север"/"Юг"/"Запад"/"Восток") и меньше под "второстепенные" ("Северо-Запад"/"Северо-Восток"/"Юго-Восток"/"Юго-Запад").
http://ihost.pro-pawn.ru/image.php?di=PCLR

Минимальное значение для переменной - "0.0" (в этом случае игроку нужно смотреть чётко в координаты "0.0", "90.0", "180.0", "280.0" для того, чтоб функция определила "основные" стороны света)
Максимальное значение для переменной - 45.0 (в этом случае все "второстепенные" стороны стороны света перестанут определяться. Будут определяться лишь "основные")

Больше никаких настроек функция не требует.

Пример использования:


new const side_of_the_world_list[8][14] =
{
"Север",
"Северо-Запад",
"Запад",
"Юго-Запад",
"Юг",
"Юго-Восток",
"Восток",
"Северо-Восток"
};


public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if(newkeys & KEY_YES)
SendClientMessage(playerid, -1, side_of_the_world_list[GetPlayerFacingDirection(playerid)]);
return 1;
}

Автор:

DeimoS

$continue$
17.06.2017, 04:06
Не сказал бы, что максимально удобно использовать. Добавь enum с константами названием сторон света. Будет куда лучше, чем запоминать цифры от 0-7 (я у себя сделал, но крайне сомнительные название констант -_-)


enum
{
SIDE_WORLD_NORTH = 0,
SIDE_WORLD_NORTH_WEST = 1,
SIDE_WORLD_WEST = 2,
SIDE_WORLD_SOUTH_WEST = 3,
SIDE_WORLD_SOUTH = 4,
SIDE_WORLD_SOUTH_EAST = 5,
SIDE_WORLD_EAST = 6,
SIDE_WORLD_NORTH_EAST = 7
};

Daniel_Cortez
17.06.2017, 07:06
Небольшое замечание: обычно в названиях функции не используют "which" и прочие местоимения. Можно было бы назвать функцию GetPlayerFacingDirection, по аналогии с GetPlayerFacingAngle.

TheMallard
17.06.2017, 08:10
Не сказал бы, что максимально удобно использовать. Добавь enum с константами названием сторон света. Будет куда лучше, чем запоминать цифры от 0-7 (я у себя сделал, но крайне сомнительные название констант -_-)


enum
{
SIDE_WORLD_NORTH = 0,
SIDE_WORLD_NORTH_WEST = 1,
SIDE_WORLD_WEST = 2,
SIDE_WORLD_SOUTH_WEST = 3,
SIDE_WORLD_SOUTH = 4,
SIDE_WORLD_SOUTH_EAST = 5,
SIDE_WORLD_EAST = 6,
SIDE_WORLD_NORTH_EAST = 7
};



DIRECTION_NORTH = 0, ...

DeimoS
17.06.2017, 14:33
Небольшое замечание: обычно в названиях функции не используют "which" и прочие местоимения. Можно было бы назвать функцию GetPlayerFacingDirection, по аналогии с GetPlayerFacingAngle.

Ок, переименовал



Не сказал бы, что максимально удобно использовать. Добавь enum с константами названием сторон света. Будет куда лучше, чем запоминать цифры от 0-7 (я у себя сделал, но крайне сомнительные название констант -_-)


enum
{
SIDE_WORLD_NORTH = 0,
SIDE_WORLD_NORTH_WEST = 1,
SIDE_WORLD_WEST = 2,
SIDE_WORLD_SOUTH_WEST = 3,
SIDE_WORLD_SOUTH = 4,
SIDE_WORLD_SOUTH_EAST = 5,
SIDE_WORLD_EAST = 6,
SIDE_WORLD_NORTH_EAST = 7
};



DIRECTION_NORTH = 0, ...

Вообще подразумевалось, что каждый сам уже сделает нужную ему "надстройку" функции: будь то массив с названиями, как я показал в теме или же константы. Но ок, добавлено

Nash_Brigers
17.06.2017, 15:09
Честно, не представляю, где это может быть использовано.. Просветите?

$continue$
17.06.2017, 15:23
Сейчас пишу возврат в полигон. Есть зависимость от сторон света, где дистанция от выхода из полигона +/-. Используя функцию GetPointInFront2D (https://github.com/AbyssMorgan/SA-MP/blob/master/include/SAM/3DTryg.inc#L2129-L2132) нужно передать дистанцию, чтобы игрок оказался в полигоне. Вот такие вот костыли =)

Честно, не представляю, где это может быть использовано.. Просветите?

В возврат функции, наверное будет лучше добавить константы, вместо значении

Но ок, добавлено

whale
17.06.2017, 16:44
Сейчас пишу возврат в полигон. Есть зависимость от сторон света, где дистанция от выхода из полигона +/-. Используя функцию GetPointInFront2D (https://github.com/AbyssMorgan/SA-MP/blob/master/include/SAM/3DTryg.inc#L2129-L2132) нужно передать дистанцию, чтобы игрок оказался в полигоне. Вот такие вот костыли =)


В возврат функции, наверное будет лучше добавить константы, вместо значении

Это Вы имели ввиду, я так понимаю:


if(north_coord_min <= facing_angle <= 360.0 || 0.0 <= facing_angle <= north_coord_max)
return DIRECTION_NORTH;
else if(north_coord_max+coord_indent <= facing_angle <= west_coord_min-coord_indent)
return DIRECTION_NORTH_WEST;

else if(west_coord_min <= facing_angle <= west_coord_max)
return DIRECTION_WEST;
else if(west_coord_max+coord_indent <= facing_angle <= south_coord_min-coord_indent)
return DIRECTION_SOUTH_WEST;

else if(south_coord_min <= facing_angle <= south_coord_max)
return DIRECTION_SOUTH;
else if(south_coord_max+coord_indent <= facing_angle <= east_coord_min-coord_indent)
return DIRECTION_SOUTH_EAST;

else if(east_coord_min <= facing_angle <= east_coord_max)
return DIRECTION_EAST;
else //if(east_coord_max+coord_indent <= facing_angle <= north_coord_min-coord_indent)
return DIRECTION_NORTH_EAST;

$continue$
17.06.2017, 16:59
Именно.

Это Вы имели ввиду, я так понимаю:


if(north_coord_min <= facing_angle <= 360.0 || 0.0 <= facing_angle <= north_coord_max)
return DIRECTION_NORTH;
else if(north_coord_max+coord_indent <= facing_angle <= west_coord_min-coord_indent)
return DIRECTION_NORTH_WEST;

else if(west_coord_min <= facing_angle <= west_coord_max)
return DIRECTION_WEST;
else if(west_coord_max+coord_indent <= facing_angle <= south_coord_min-coord_indent)
return DIRECTION_SOUTH_WEST;

else if(south_coord_min <= facing_angle <= south_coord_max)
return DIRECTION_SOUTH;
else if(south_coord_max+coord_indent <= facing_angle <= east_coord_min-coord_indent)
return DIRECTION_SOUTH_EAST;

else if(east_coord_min <= facing_angle <= east_coord_max)
return DIRECTION_EAST;
else //if(east_coord_max+coord_indent <= facing_angle <= north_coord_min-coord_indent)
return DIRECTION_NORTH_EAST;

DeimoS
17.06.2017, 17:19
Честно, не представляю, где это может быть использовано.. Просветите?

Я писал её по чьей-то просьбе (не помню уже кто просил), так что, видимо, предназначение ей можно придумать, помимо того, что предложил $continue$.

Обновил тему.

Nash_Brigers
17.06.2017, 18:16
Я писал её по чьей-то просьбе (не помню уже кто просил), так что, видимо, предназначение ей можно придумать, помимо того, что предложил $continue$.

Обновил тему.Компас разве-что.. То, что описал Даниил можно и проще запилить, на сколько я в курсе.

Fallen A.
17.06.2017, 18:30
Советую добавить определение "точки относительно точки" и "игрока, относительно точки" вдобавок к этому.

DeimoS
17.06.2017, 18:58
Компас разве-что.. То, что описал Даниил можно и проще запилить, на сколько я в курсе.

Ну так это и есть основное предназначение функции, о чём даже в названии указано. При помощи GetPlayerPos ты тоже не узнаешь ничего, кроме координат игрока


Советую добавить определение "точки относительно точки" и "игрока, относительно точки" вдобавок к этому.

Зачем это в данной функции?

Fallen A.
17.06.2017, 19:03
Зачем это в данной функции?

Это явно не было бы лишним.

DeimoS
17.06.2017, 21:54
Это явно не было бы лишним.

В теме, посвящённой функции, у которой есть конкретное предназначение? Видимо я чего-то не понимаю в этой жизни

Fallen A.
17.06.2017, 22:32
В теме, посвящённой функции, у которой есть конкретное предназначение? Видимо я чего-то не понимаю в этой жизни

Ну почему же, то, что предложил я, довольно-таки близко по смыслу к вышеупомянутой функции.

DeimoS
17.06.2017, 22:40
Ну почему же, то, что предложил я, довольно-таки близко по смыслу к вышеупомянутой функции.

В любом случае в теме, которая посвящена конкретной функции, следует находиться лишь этой самой функции. Любые другие функции должны находиться в своих темах, а если нужно их объединить - следует создавать инклуд с этими функциями и публиковать уже его.
Создавать кашу в одной теме - такая себе идея. Вот всё, о чём я хотел сказать.

Касаемо твоего предложения: если есть желание - реализуй. У меня пока ни времени, ни желания особо нет.

Fallen A.
18.06.2017, 01:09
В любом случае в теме, которая посвящена конкретной функции, следует находиться лишь этой самой функции. Любые другие функции должны находиться в своих темах, а если нужно их объединить - следует создавать инклуд с этими функциями и публиковать уже его.
Создавать кашу в одной теме - такая себе идея. Вот всё, о чём я хотел сказать.

Касаемо твоего предложения: если есть желание - реализуй. У меня пока ни времени, ни желания особо нет.

Мда-м, ну ладно. Как появится необходимость, так и сделаю.

vovandolg
19.06.2017, 01:23
Честно, не представляю, где это может быть использовано.. Просветите?

РПГ + ТДМ жанр, там иногда такое бывает по компасу ориентируются или по как это с понтами по "часам"...

DeimoS
19.06.2017, 01:34
Та можно много чего придумать при наличии фантазии. Например, квестики по типу "сделайте то-то", как в Team Fortress 2 есть режим "Wario Ware", в котором есть нечто подобное. И вот там уже можно сделать, например, "Посмотрите на сервер" :pardon:
В общем, главное фантазию иметь.

vovandolg
19.06.2017, 04:25
Просто все привыкли к названиям что даёт точную координацию, а если так прикинуть по компасу и приблизительным ориентирам то и функция понадобится, и не будет всяких лс, сф, лв, чилик и прочего, более неизвестное что то