PDA

Просмотр полной версии : [Вопрос] Система коробки передач.



SteveStage
28.01.2020, 21:43
Натолкните меня на мысль, как сделать ускорение автомобиля? Основа уже есть, но при ее использовании авто беспорядочно кидает в разные стороны.

public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
switch(newkeys)
{
case KEY_ANALOG_UP:
{
if(!IsPlayerInAnyVehicle(playerid)) return false;
new
vehicleid = GetPlayerVehicleID(playerid);
switch(veh[vehicleid][v_gear])
{
case GEAR_1: // set gear 2
{
new
Float:z;
GetVehicleVelocity(vehicleid, z, z, z);
SetVehicleVelocity(vehicleid, 0.9, 0.9, z);
veh[vehicleid][v_gear] = GEAR_2;
}
case GEAR_2: // set gear 3
{
new
Float:z;
GetVehicleVelocity(vehicleid, z, z, z);
SetVehicleVelocity(vehicleid, 1.2, 1.2, z);
veh[vehicleid][v_gear] = GEAR_3;
}
case GEAR_3: // set gear 4
{
new
Float:z;
GetVehicleVelocity(vehicleid, z, z, z);
SetVehicleVelocity(vehicleid, 1.5, 1.5, z);
veh[vehicleid][v_gear] = GEAR_4;
}
case GEAR_4: // set gear 5
{
new
Float:z;
GetVehicleVelocity(vehicleid, z, z, z);
SetVehicleVelocity(vehicleid, 1.8, 1.8, z);
veh[vehicleid][v_gear] = GEAR_5;
}
case GEAR_5: // set gear r
{
new
Float:z;
GetVehicleVelocity(vehicleid, z, z, z);
SetVehicleVelocity(vehicleid, 0.0, 0.0, z);
veh[vehicleid][v_gear] = GEAR_R;
}
case GEAR_R: // set gear 1
{
new
Float:z;
GetVehicleVelocity(vehicleid, z, z, z);
SetVehicleVelocity(vehicleid, 0.7, 0.7, z);
veh[vehicleid][v_gear] = GEAR_1;
}
default: veh[vehicleid][v_gear] = GEAR_1;
}
new
str[24+1],
gear[1+1];
if(veh[vehicleid][v_gear] == GEAR_R) strmid(gear, "R", 0, sizeof(gear));
else valstr(gear, veh[vehicleid][v_gear]);
format(str, sizeof(str), "VEHICLE GEAR CHANGE TO %s", gear);
TextForPlayer(playerid, str, 3000, 2);
printf("%d - gear", veh[vehicleid][v_gear]);
}
case KEY_ANALOG_DOWN:
{
if(!IsPlayerInAnyVehicle(playerid)) return false;
new
vehicleid = GetPlayerVehicleID(playerid);
switch(veh[vehicleid][v_gear])
{
case GEAR_1: // set gear r
{
new
Float:z;
GetVehicleVelocity(vehicleid, z, z, z);
SetVehicleVelocity(vehicleid, 0.0, 0.0, z);
veh[vehicleid][v_gear] = GEAR_R;
}
case GEAR_2: // set gear 1
{
new
Float:z;
GetVehicleVelocity(vehicleid, z, z, z);
SetVehicleVelocity(vehicleid, 0.7, 0.7, z);
veh[vehicleid][v_gear] = GEAR_3;
}
case GEAR_3: // set gear 2
{
new
Float:z;
GetVehicleVelocity(vehicleid, z, z, z);
SetVehicleVelocity(vehicleid, 0.9, 0.9, z);
veh[vehicleid][v_gear] = GEAR_4;
}
case GEAR_4: // set gear 3
{
new
Float:z;
GetVehicleVelocity(vehicleid, z, z, z);
SetVehicleVelocity(vehicleid, 1.2, 1.2, z);
veh[vehicleid][v_gear] = GEAR_5;
}
case GEAR_5: // set gear 4
{
new
Float:z;
GetVehicleVelocity(vehicleid, z, z, z);
SetVehicleVelocity(vehicleid, 1.5, 1.5, z);
veh[vehicleid][v_gear] = GEAR_R;
}
case GEAR_R: // set gear 5
{
new
Float:z;
GetVehicleVelocity(vehicleid, z, z, z);
SetVehicleVelocity(vehicleid, 1.8, 1.8, z);
veh[vehicleid][v_gear] = GEAR_1;
}
default: veh[vehicleid][v_gear] = GEAR_1;
}
new
str[24+1],
gear[1+1];
if(veh[vehicleid][v_gear] == GEAR_R) strmid(gear, "R", 0, sizeof(gear));
else valstr(gear, veh[vehicleid][v_gear]);
format(str, sizeof(str), "VEHICLE GEAR CHANGE TO %s", gear);
TextForPlayer(playerid, str, 3000, 2);
printf("%d - gear", veh[vehicleid][v_gear]);
return true;
}
}
return true;
}

Как сделать нормальную макс. скорость авто на разных передачах?

DeimoS
30.01.2020, 19:37
Такое есть смысл делать только на стороне клиента, ибо если делать на стороне сервера, то с пингом больше 100 эта система уже будет ощущаться не очень комфортно для игрока.

Ну а если очень хочется, то SetVehicleVelocity + функция изменения гравитации для конкретного игрока из YSF или подобного плагина. Увеличением гравитации можно добиться более сильного прижатия к дороге и, соответственно, авто будет меньше носить.

L0ndl3m
30.01.2020, 21:10
Полностью согласен по поводу пинга. У тех людей у кого пинг большой, будут испытывать большие проблемы с вашей системой, даже если ваша система будет удовлетворять всем стандартам, и будут оптимизирована. Всегда стоит помнить о том, что SA-MP является архитектурой "Клиент->Сервер" и наоборот. То есть, если клиент не отдаст свои данные, то следовательно, сервер их не получит, до тех пор, пока пакеты не дойдут до сервера (исправьте меня обязательно, если я не прав!). И да, система "коробок передач" не заключается в том, чтобы "разгонять" транспорт. Насколько я знаю, при переключении передач, скорость остаётся неизменной, либо наоборот(?) уменьшается в несколько единиц.
Поэтому, мне кажется, необходимо оставлять скорость неизменной при переходе на новую ступень.

По поводу кода ничем не смогу помочь на данный момент.

DeimoS
30.01.2020, 23:50
Полностью согласен по поводу пинга. У тех людей у кого пинг большой, будут испытывать большие проблемы с вашей системой, даже если ваша система будет удовлетворять всем стандартам, и будут оптимизирована. Всегда стоит помнить о том, что SA-MP является архитектурой "Клиент->Сервер" и наоборот. То есть, если клиент не отдаст свои данные, то следовательно, сервер их не получит, до тех пор, пока пакеты не дойдут до сервера (исправьте меня обязательно, если я не прав!). И да, система "коробок передач" не заключается в том, чтобы "разгонять" транспорт. Насколько я знаю, при переключении передач, скорость остаётся неизменной, либо наоборот(?) уменьшается в несколько единиц.
Поэтому, мне кажется, необходимо оставлять скорость неизменной при переходе на новую ступень.

По поводу кода ничем не смогу помочь на данный момент.

Так он и пытается сделать так, чтоб скорость была неизменной. Правда делает он это кривовато. Стоило посмотреть как реализованы функции, по типу "SetVehicleSpeed"

SteveStage
31.01.2020, 00:38
Я конечно знаю о такой функции:

stock SetVehicleSpeed(vehicleid, Float:speed)
{
new Float:x1, Float:y1, Float:z1, Float:x2, Float:y2, Float:z2, Float:a;
GetVehicleVelocity(vehicleid, x1, y1, z1);
GetVehiclePos(vehicleid, x2, y2, z2);
GetVehicleZAngle(vehicleid, a); a = 360 - a;
x1 = (floatsin(a, degrees) * (speed/100) + floatcos(a, degrees) * 0 + x2) - x2;
y1 = (floatcos(a, degrees) * (speed/100) + floatsin(a, degrees) * 0 + y2) - y2;
SetVehicleVelocity(vehicleid, x1, y1, z1);
}

но вычисление скорости авто у меня такое:

stock GetVehicleSpeed(vehicleid)
{
new
Float:x, Float:y, Float:z;
GetVehicleVelocity(vehicleid, x, y, z);
return floatround(floatsqroot(x*x+y*y+z*z)*100);
}

а они могут отличаться в вычислении => скорость не будет выставляться корректно. Вот это и тормозит меня.

Может быть вот так?

@_UpdateSpeed(playerid, vehicleid, oldspeed);
@_UpdateSpeed(playerid, vehicleid, oldspeed)
{
new
getspeed = GetVehicleSpeed(vehicleid),
Float:carhp,
string[16],
engine,
lights,
alarm,
bonnet,
boot,
objective,
doors;
GetVehicleHealth(vehicleid, carhp);
GetVehicleParamsEx(vehicleid, engine, lights, alarm, doors, bonnet, boot, objective);
if(carhp <= 300.0)
{
if(engine == VEHICLE_PARAMS_ON) SetVehicleParamsEx(vehicleid, VEHICLE_PARAMS_OFF, lights, alarm, doors, bonnet, boot, objective);
SetVehicleHealth(vehicleid, 300.0);
if(is_veh_dmg_first_time{vehicleid} == true)
{
SCM(playerid, COLOR_RED, !"[SERVER] Ваше транспортное средство повреждено!");
is_veh_dmg_first_time{vehicleid} = false;
}
}
if(getspeed >= veh[vehicleid][v_max_speed] && getspeed >= 1) SetVehicleSpeed(vehicleid, veh[vehicleid][v_max_speed] - 1.0);
if(veh[vehicleid][v_fuel] > 0 && engine == VEHICLE_PARAMS_ON)
{
if(getspeed == 0) used_fuel_veh[vehicleid] += 1;
else if(getspeed >= 1)
{
if(getspeed >= oldspeed)
{
if(getspeed >= 1 && getspeed <= 20) used_fuel_veh[vehicleid] += 4;
else if(getspeed >= 21 && getspeed <= 50) used_fuel_veh[vehicleid] += 6;
else if(getspeed >= 51 && getspeed <= 70) used_fuel_veh[vehicleid] += 10;
else if(getspeed >= 71 && getspeed <= 120) used_fuel_veh[vehicleid] += 14;
else if(getspeed >= 121 && getspeed <= 300) used_fuel_veh[vehicleid] += 18;
}
else used_fuel_veh[vehicleid] += 1;
}
}
if(used_fuel_veh[vehicleid] >= 250 && veh[vehicleid][v_fuel] > 0)
{
veh[vehicleid][v_fuel] -= 1;
used_fuel_veh[vehicleid] = 0;
if(veh[vehicleid][v_fuel] == 0)
{
GetVehicleParamsEx(vehicleid, engine, lights, alarm, doors, bonnet, boot, objective);
if(engine == VEHICLE_PARAMS_ON) SetVehicleParamsEx(vehicleid, VEHICLE_PARAMS_OFF, lights, alarm, doors, bonnet, boot, objective);
SCM(playerid, COLOR_RED, !"[SERVER] В вашем транспортном средстве кончилось топливо!");
}
}
format(string, sizeof(string), "SPEED: %d KM/H", getspeed);
PlayerTextDrawSetString(playerid, td_speed[1], string);
format(string, sizeof(string), "FUEL: %d", veh[vehicleid][v_fuel]);
PlayerTextDrawSetString(playerid, td_speed[2], string);
format(string, sizeof(string), "LOCK: %s", (veh[vehicleid][v_lock] == true) ? ("LOCKED") : ("UNLOCKED"));
PlayerTextDrawSetString(playerid, td_speed[3], string);
for(new i = 1; i < sizeof(td_speed); i++) PlayerTextDrawShow(playerid, td_speed[i]);
speed_timer[vehicleid] = SetTimerEx("@_UpdateSpeed", 250, false, "ddd", playerid, vehicleid, getspeed);
return true;
}

{
switch(newkeys)
{
case KEY_ANALOG_UP:
{
if(!IsPlayerInAnyVehicle(playerid)) return false;
new
vehicleid = GetPlayerVehicleID(playerid);
switch(veh[vehicleid][v_gear])
{
case GEAR_1: // set gear 2
{
veh[vehicleid][v_max_speed] = 70.0;
veh[vehicleid][v_gear] = GEAR_2;
}
case GEAR_2: // set gear 3
{
veh[vehicleid][v_max_speed] = 90.0;
veh[vehicleid][v_gear] = GEAR_3;
}
case GEAR_3: // set gear 4
{
veh[vehicleid][v_max_speed] = 120.0;
veh[vehicleid][v_gear] = GEAR_4;
}
case GEAR_4: // set gear 5
{
veh[vehicleid][v_max_speed] = 150.0;
veh[vehicleid][v_gear] = GEAR_5;
}
case GEAR_5: // set gear r
{
veh[vehicleid][v_max_speed] = 0.0;
veh[vehicleid][v_gear] = GEAR_R;
}
case GEAR_R: // set gear 1
{
veh[vehicleid][v_max_speed] = 50.0;
veh[vehicleid][v_gear] = GEAR_1;
}
default: veh[vehicleid][v_gear] = GEAR_1;
}
new
str[24+1],
gear[1+1];
if(veh[vehicleid][v_gear] == GEAR_R) strmid(gear, "R", 0, sizeof(gear));
else valstr(gear, veh[vehicleid][v_gear]);
format(str, sizeof(str), "VEHICLE GEAR CHANGE TO %s", gear);
TextForPlayer(playerid, str, 3000, 2);
printf("%d - gear", veh[vehicleid][v_gear]);
}
case KEY_ANALOG_DOWN:
{
if(!IsPlayerInAnyVehicle(playerid)) return false;
new
vehicleid = GetPlayerVehicleID(playerid);
switch(veh[vehicleid][v_gear])
{
case GEAR_1: // set gear r
{
veh[vehicleid][v_max_speed] = 0.0;
veh[vehicleid][v_gear] = GEAR_R;
}
case GEAR_2: // set gear 1
{
veh[vehicleid][v_max_speed] = 50.0;
veh[vehicleid][v_gear] = GEAR_3;
}
case GEAR_3: // set gear 2
{
veh[vehicleid][v_max_speed] = 70.0;
veh[vehicleid][v_gear] = GEAR_4;
}
case GEAR_4: // set gear 3
{
veh[vehicleid][v_max_speed] = 90.0;
veh[vehicleid][v_gear] = GEAR_5;
}
case GEAR_5: // set gear 4
{
veh[vehicleid][v_max_speed] = 120.0;
veh[vehicleid][v_gear] = GEAR_R;
}
case GEAR_R: // set gear 5
{
veh[vehicleid][v_max_speed] = 150.0;
veh[vehicleid][v_gear] = GEAR_1;
}
default: veh[vehicleid][v_gear] = GEAR_1;
}
new
str[24+1],
gear[1+1];
if(veh[vehicleid][v_gear] == GEAR_R) strmid(gear, "R", 0, sizeof(gear));
else valstr(gear, veh[vehicleid][v_gear]);
format(str, sizeof(str), "VEHICLE GEAR CHANGE TO %s", gear);
TextForPlayer(playerid, str, 3000, 2);
printf("%d - gear", veh[vehicleid][v_gear]);
return true;
}
}
return true;
}

Суть в том, что передача меняет макс. скорость, а настоящая скорость не меняется, только уменьшается, если она достигает максимальной.

Проверил: машину все равно кидает в стороны. Как это реализовывать и можно ли - я хз, а главное - стоят ли усилия над коробкой передач того? Я думаю нет.

DeimoS
31.01.2020, 14:12
Я конечно знаю о такой функции:

stock SetVehicleSpeed(vehicleid, Float:speed)
{
new Float:x1, Float:y1, Float:z1, Float:x2, Float:y2, Float:z2, Float:a;
GetVehicleVelocity(vehicleid, x1, y1, z1);
GetVehiclePos(vehicleid, x2, y2, z2);
GetVehicleZAngle(vehicleid, a); a = 360 - a;
x1 = (floatsin(a, degrees) * (speed/100) + floatcos(a, degrees) * 0 + x2) - x2;
y1 = (floatcos(a, degrees) * (speed/100) + floatsin(a, degrees) * 0 + y2) - y2;
SetVehicleVelocity(vehicleid, x1, y1, z1);
}

но вычисление скорости авто у меня такое:

stock GetVehicleSpeed(vehicleid)
{
new
Float:x, Float:y, Float:z;
GetVehicleVelocity(vehicleid, x, y, z);
return floatround(floatsqroot(x*x+y*y+z*z)*100);
}

а они могут отличаться в вычислении => скорость не будет выставляться корректно. Вот это и тормозит меня.

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



Суть в том, что передача меняет макс. скорость, а настоящая скорость не меняется, только уменьшается, если она достигает максимальной.

Если это не то, что ты задумывал, то так происходит, ибо ты сам такое условие составил, не?


Проверил: машину все равно кидает в стороны.

Я уже выше писал, что тут только ковыряние гравитации может хоть немного ситуацию изменить. Но всё равно будет кривовато и игроки с большим пингом будут страдать.


Как это реализовывать и можно ли - я хз, а главное - стоят ли усилия над коробкой передач того? Я думаю нет.

С реализацией на стороне сервера - нет. С реализацией на стороне клиента - как опциональный вариант управления машиной подойдёт.