PDA

Просмотр полной версии : [Вопрос] SpeedVehicle



SQL_
25.02.2018, 22:33
Добрый вечер, еще появился вопрос наткнулся на тему про SpeedVehicle, и Ziggi дал в этой теме формулу скорости:

stock Float:SpeedVehicle(vehicleid)
{
new Float:x, Float:y, Float:z;
GetVehicleVelocity(vehicleid, x, y, z);
return VectorSize(x, y, z) * 150.0;
}

Можете обьяснить почему Float: speedVehicle? И данная формула правильная для определения KM/H транспорта?

SQL_
25.02.2018, 23:12
Можете пожалуйста дать правильную формулу для определения скорости автомобиля?
Вышеописанная формула не работает!

StevenH
26.02.2018, 19:15
В смысле почему Float:SpeedVehicle? Вектор возвращает число с плавающей точкой, поэтому и Float, разве нет?

На счет определения, не уверен, но умножать надо на 180, а не на 150, хотя могу и ошибаться

DeimoS
26.02.2018, 20:27
Нет универсальной формулы, как минимум, потому, что скорость напрямую зависит от FPS (/fpslimit в помощь, если есть желание проверить мои слова) + чтоб всё нормально работало, формула получения скорости должна быть похожей на формулу установки

SQL_
26.02.2018, 22:37
Еще можно задам вопрос, а что лучше обновлять спидометр в секундном таймере или же вызывать его в OnPlayerUpdate?

DeimoS
26.02.2018, 23:39
Еще можно задам вопрос, а что лучше обновлять спидометр в секундном таймере или же вызывать его в OnPlayerUpdate?

Секундный таймер естественно. Можно даже индивидуальный для каждого игрока, который будет запускаться при посадке в авто (на место водителя, естественно) и убиваться при выходе из авто/с сервера, дабы не нагружать сервер единоразово для всех игроков, а разделять нагрузку по потоку

pawnoholic
27.02.2018, 00:41
Секундный таймер естественно. Можно даже индивидуальный для каждого игрока, который будет запускаться при посадке в авто (на место водителя, естественно) и убиваться при выходе из авто/с сервера, дабы не нагружать сервер единоразово для всех игроков, а разделять нагрузку по потоку

Почему в таймере лучше?

В OnPlayerUpdate обновление скорости плавно происходит, а по таймеру скорость будет обновляться рывками.

DeimoS
27.02.2018, 00:44
Почему в таймере лучше?

В OnPlayerUpdate обновление скорости плавно происходит, а по таймеру скорость будет обновляться рывками.

Потому что ты будешь заставлять сервер выполнять кучу ненужных действий ради необязательной плавности (в том числе и постоянно проверяя, находится ли игрок в авто, даже когда он просто бегает пешком)? Да ещё и флудя пакетами игроку.
Если уж так хочется добиться плавности (хотя делать подобное со стороны сервера - пустая трата ресурсов) - просто делай время между итерациями таймера меньше и всё.

Индивидуальные таймеры тем и хороши, что ты, во-первых, можешь настроить частоту обновления, а, во-вторых, обновление будет происходить реально только тогда, когда игрок находится в авто и не будет никаких лишних проверок, ибо пока игрок вне авто, таймер просто не работает.

И да, автор, предупреждаю сразу: делать старт и окончание таймера следует в OnPlayerStateChange, ибо OnPlayerEnterVehicle и OnPlayerExitVehicle работают немного иначе (вызываются не в момент, когда игрок уже сел или вышел, а когда игрок только начал бежать к двери. И даже если она закрыта/заполнена, они будут вызываться. + не вызываются когда игрок падает с мотоцикла/велосипеда или если на нём применить SetPlayerPos, когда он сидит в транспорте). Так же не забывай таймер при выходе с сервера убивать, ибо OnPlayerStateChange (как и те два коллбэка) не вызывается при выходе с сервера.

SQL_
27.02.2018, 08:17
public OnPlayerStateChange(playerid, newstate, oldstate)
{
if(newstate == PLAYER_STATE_ENTER_VEHICLE_DRIVER)
{
/*Вызываю таймер*/
Speedometer_timer[playerid] = SetTimerEx("Update_speedometer",200,1,"d",playerid);
}
else if(oldstate == PLAYER_STATE_EXIT_VEHICLE)
{
/*убиваем таймер*/
KillTimer(Speedometer_timer[playerid]);
}
return 1;
}

forward Update_speedometer(playerid);
public Update_speedometer(playerid)
{
/*тут уже обновлять действия спидометра*/
}

Так?

- - - Добавлено - - -

Вопрос еще актуален по по поводу SpeedVehilce, в интернете нашел уйма вариантов.

stock SpeedVehicle(playerid)
{
new Float:ST[4];
if(IsPlayerInAnyVehicle(playerid))
GetVehicleVelocity(GetPlayerVehicleID(playerid),ST[0],ST[1],ST[
2]);
else GetPlayerVelocity(playerid,ST[0],ST[1],ST[2]);
ST[3] = floatsqroot(floatpower(floatabs(ST[0]), 2.0) + floatpower(floatabs(ST[1]), 2.0) + floatpower(floatabs(ST[2]), 2.0)) * 100.3;
return floatround(ST[3]);
}

Можете обьяснить пожалуйста как идёт тут подсчёт, умножение,складывания:

ST[3] = floatsqroot(floatpower(floatabs(ST[0]), 2.0) + floatpower(floatabs(ST[1]), 2.0) + floatpower(floatabs(ST[2]), 2.0)) * 100.3;
return floatround(ST[3]);
И откуда берётся число 100.3(везде поразному 180.0)

DeimoS
27.02.2018, 11:19
public OnPlayerStateChange(playerid, newstate, oldstate)
{
if(newstate == PLAYER_STATE_DRIVER)
{
if(Speedometer_timer[playerid] == -1)
{
/*Вызываю таймер*/
Speedometer_timer[playerid] = SetTimerEx("Update_speedometer",200,1,"d",playerid);
}
}
else if(oldstate == PLAYER_STATE_DRIVER)
{
if(Speedometer_timer[playerid] != -1)
{ /*убиваем таймер*/
KillTimer(Speedometer_timer[playerid]);
Speedometer_timer[playerid] -1;
}
}
return 1;
}
И при входе на сервер

Speedometer_timer[playerid] = -1;
А при выходе

if(Speedometer_timer[playerid] != -1)
{ /*убиваем таймер*/
KillTimer(Speedometer_timer[playerid]);
Speedometer_timer[playerid] -1;
}

- - - Добавлено - - -


И откуда берётся число 100.3(везде поразному 180.0)

Из головы. Оно нужно, чтоб финальная скорость выглядела реалистичнее (чтоб велосипед не ездил под 60 км/ч). Соответственно, разные числа дают разные финальные значения. Чтоб это понять, достаточно было опробовать формулу без этих чисел и посмотреть на результат.

Вот тут (http://forum.sa-mp.com/showthread.php?t=364124&page=3) можешь почитать на тему того, какой логики придерживаются при составлении формулы

Elrmrnt-Kritik
27.02.2018, 22:09
И при входе на сервер

Speedometer_timer[playerid] = -1;


А использование INVALID_PLAYER_ID в данном случае нежелательно или на усмотрение каждого все же?

VVWVV
27.02.2018, 22:49
А использование INVALID_PLAYER_ID в данном случае нежелательно или на усмотрение каждого все же?

Насколько я понял, вы хотите заменить число -1 на константу INVALID_PLAYER_ID. Если действительно так, то это совершенно бессмысленно, вы навредите самому себе же, поскольку массив Speedometer_timer хранит идентификаторы таймеров, а не игроков.

SQL_
01.03.2018, 16:12
if (speedometer_timer[playerid] != -1)
{
KillTimer(speedometer_timer[playerid]);
speedometer_timer[playerid] -1; //варнинг на эту строку (warning 215: expression has no effect - выражение не имеет эффекта)
}
PlayerTextDrawHide// тут скрываю ТД


if (speedometer_timer[playerid] == -1)
{
speedometer_timer[playerid] = SetTimerEx("Update_speedometer", 200, true, "i", playerid);
}
PlayerTextDrawShow// показываю ТД

forward Update_speedometer(playerid);
public Update_speedometer(playerid)
{
new fmt_str[11];
format(fmt_str, sizeof(fmt_str), "%d KM/H", SpeedVehicle(vehicle));
PlayerTextDrawSetString(playerid, TDKM[playerid], fmt_str);

PlayerTextDrawSetString(playerid, TDEngine[playerid], (zavodis[vehicle] == false ? ("~g~E") : ("E")));
PlayerTextDrawSetString(playerid, TDDoor[playerid], (gCarLock[vehicle] == false ? ("~g~U") : ("L")));
return 1;
}

в public OnPlayerConnect(playerid)


speedometer_timer[playerid] -1; //варнинг на эту строку (warning 215: expression has no effect - выражение не имеет эффекта)

в public OnPlayerDisconnect(playerid, reason)


if (speedometer_timer[playerid] != -1)
{
KillTimer(speedometer_timer[playerid]);
speedometer_timer[playerid] -1; //варнинг на эту строку (warning 215: expression has no effect - выражение не имеет эффекта)
}

- - - Добавлено - - -

еще спидометр обновляется когда происходит какое то действие, вкл. выкл. двигатель, закрыл открыл машину. Скорость покажет и застынет на этой скорости пока не произойдёт действие

Daniel_Cortez
01.03.2018, 17:37
...
Во всех трёх случаях пропущен знак "=".

DeimoS
02.03.2018, 01:09
PlayerTextDrawSetString(playerid, TDEngine[playerid], (zavodis[vehicle] == false ? ("~g~E") : ("E")));
PlayerTextDrawSetString(playerid, TDDoor[playerid], (gCarLock[vehicle] == false ? ("~g~U") : ("L")));
Зачем текстдравы в таймере обновлять, если все действия, которыми они управляются, подконтрольны серверу? Текстдрав двигателя обновляй в коде, ответственном за заводку двигателя, а текстдрав дверей в команде открытия/закрытия дверей