PDA

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



SteveStage
30.12.2019, 14:43
Вот моя система спидометра:

new speed_timer[MAX_VEHICLES];

public OnPlayerStateChange(playerid, newstate, oldstate)
{
if(newstate == PLAYER_STATE_DRIVER)
{
td_speed[0] = TextDrawCreate(641.531494, 378.333312, "usebox");
TextDrawLetterSize(td_speed[0], 0.000000, 7.525930);
TextDrawTextSize(td_speed[0], 500.723266, 0.000000);
TextDrawUseBox(td_speed[0], true);
TextDrawBoxColor(td_speed[0], 102);
speed_timer[vehicleid] = SetTimerEx("@_UpdateSpeed", 500, false, "dd", playerid, vehicleid);
}
}

@_UpdateSpeed(playerid, vehicleid);
@_UpdateSpeed(playerid, vehicleid)
{
if(GetPlayerState(playerid) != PLAYER_STATE_DRIVER)
{
KillTimer(speed_timer[vehicleid]);
for(new i; i < 4; i++) TextDrawHideForPlayer(playerid, td_speed[i]);
return false;
}
for(new i; i < 4; i++) TextDrawHideForPlayer(playerid, td_speed[i]);
new
string1[15],
string2[10],
string3[15];
format(string1, sizeof(string1), "SPEED: %d KM/H", GetVehicleSpeed(playerid, vehicleid));
format(string2, sizeof(string2), "FUEL: %d", veh[vehicleid][v_fuel]);
format(string3, sizeof(string3), "LOCK: %s", (lock_veh{vehicleid} == true) ? ("LOCKED") : ("UNLOCKED"));
TD_ChangeSpeed(string1, string2, string3);
for(new i; i < 4; i++) TextDrawShowForPlayer(playerid, td_speed[i]);
speed_timer[vehicleid] = SetTimerEx("@_UpdateSpeed", 500, false, "dd", playerid, vehicleid);
return true;
}

stock TD_ChangeSpeed(const speed[], const fuel[], const lock[])
{
new
color = COLOR_ORANGE;
td_speed[1] = TextDrawCreate(511.200000, 384.666596, speed);
TextDrawLetterSize(td_speed[1], 0.449999, 1.600000);
TextDrawAlignment(td_speed[1], 1);
TextDrawColor(td_speed[1], color);
TextDrawSetShadow(td_speed[1], 0);
TextDrawSetOutline(td_speed[1], 1);
TextDrawBackgroundColor(td_speed[1], 255);
TextDrawFont(td_speed[1], 3);
TextDrawSetProportional(td_speed[1], 1);

td_speed[2] = TextDrawCreate(511.200000, 402.916687, fuel);
TextDrawLetterSize(td_speed[2], 0.449999, 1.600000);
TextDrawAlignment(td_speed[2], 1);
TextDrawColor(td_speed[2], color);
TextDrawSetShadow(td_speed[2], 0);
TextDrawSetOutline(td_speed[2], 1);
TextDrawBackgroundColor(td_speed[2], 255);
TextDrawFont(td_speed[2], 3);
TextDrawSetProportional(td_speed[2], 1);

td_speed[3] = TextDrawCreate(511.200000, 421.166778, lock); // 18,250091
TextDrawLetterSize(td_speed[3], 0.449999, 1.600000);
TextDrawAlignment(td_speed[3], 1);
TextDrawColor(td_speed[3], color);
TextDrawSetShadow(td_speed[3], 0);
TextDrawSetOutline(td_speed[3], 1);
TextDrawBackgroundColor(td_speed[3], 255);
TextDrawFont(td_speed[3], 3);
TextDrawSetProportional(td_speed[3], 1);
}

Как вы можете видеть, в UpdateSpeed создаются 3 локальных массива, в них форматируются нужные значения, и после нового запуска они удаляются и потом снова создаются

А вот если я создам эти 3 массива, но глобальных, и буду форматировать их (первая мера - айди игрока), то уменьшится ли нагрузка от создания и удаления 3 локальных массивов, и как лучше это реализовать?

P.S. Опечатался в названии, не спмдометр, а спидометр =)

DeimoS
30.12.2019, 15:16
3 массива можно спокойно заменить на 1 и записывать строки поочерёдно.
К тому же у тебя сейчас происходит спам текстдравами, ибо старые текстдравы ты не удаляешь, а скрываешь и поверх создаёшь новую пачку.
И непонятно зачем там KillTimer, если таймер у тебя создаётся без повторения и при срабатывании условия он и так прекратит своё существование.



Сильного влияния инициализация массива не будет оказывать. Но если очень хочется ускорить работу кода, то можно просто сделать так:
goto __skip;
new
string1[15],
string2[10],
string3[15];
__skip:
В этом случае массивы всё так же будут созданы, но не будут инициализированы нулями (то есть, ячейки будут хранить те данные, которые были записаны ранее в стеке). В твоём случае инициализация нулями всё равно не нужна, так что подобный вариант будет работать корректно.
Хотя, как я изначально написал, корректнее всего создавать 1 массив, а не 3.



А вот если я создам эти 3 массива, но глобальных, и буду форматировать их (первая мера - айди игрока), то уменьшится ли нагрузка от создания и удаления 3 локальных массивов, и как лучше это реализовать?

Никакой меры с ID игрока тут не нужно. У тебя код в одном потоке обрабатывается. Зачем тебе создавать для каждого игрока свой массив?

SteveStage
30.12.2019, 15:25
3 массива можно спокойно заменить на 1 и записывать строки поочерёдно.
К тому же у тебя сейчас происходит спам текстдравами, ибо старые текстдравы ты не удаляешь, а скрываешь и поверх создаёшь новую пачку.
И непонятно зачем там KillTimer, если таймер у тебя создаётся без повторения и при срабатывании условия он и так прекратит своё существование.

Ты говорил про подобную реализацию?

@_UpdateSpeed(playerid, vehicleid);
@_UpdateSpeed(playerid, vehicleid)
{
for(new i; i < 4; i++) TextDrawDestroy(td_speed[i]);
if(GetPlayerState(playerid) != PLAYER_STATE_DRIVER) return false;
td_speed[0] = TextDrawCreate(641.531494, 378.333312, "usebox");
TextDrawLetterSize(td_speed[0], 0.000000, 7.525930);
TextDrawTextSize(td_speed[0], 500.723266, 0.000000);
TextDrawUseBox(td_speed[0], true);
TextDrawBoxColor(td_speed[0], 102);
if(GetPlayerState(playerid) != PLAYER_STATE_DRIVER) return false;
new
string[3];
format(string[0], 15, "SPEED: %d KM/H", GetVehicleSpeed(playerid, vehicleid));
format(string[1], 10, "FUEL: %d", veh[vehicleid][v_fuel]);
format(string[2], 11, "LOCK: %s", (lock_veh{vehicleid} == true) ? ("LOCKED") : ("UNLOCKED"));
TD_ChangeSpeed(string[0], string[1], string[2]);
for(new i; i < 4; i++) TextDrawShowForPlayer(playerid, td_speed[i]);
speed_timer[vehicleid] = SetTimerEx("@_UpdateSpeed", 500, false, "dd", playerid, vehicleid);
return true;
}

UPD: Проверил, и получил такие сообщения от крашдетекта:

[14:33:26] [debug] Run time error 6: "Invalid instruction"
[14:33:26] [debug] Unknown opcode 0x2700 at address 0x00000043
[14:33:26] [debug] AMX backtrace:
[14:33:26] [debug] #0 00000000 in public @_UpdateSpeed ()

Все равно не понимаю, как можно создать 1 массив, если TD_ChangeSpeed требует 3...

DeimoS
30.12.2019, 16:19
Эмм, нет. Я говорю про вариант, при котором ты код из TD_ChangeSpeed переносишь в таймер и делаешь так:
new string[15];
format(string, sizeof(string), "SPEED: %d KM/H", GetVehicleSpeed(playerid, vehicleid));
td_speed[1] = TextDrawCreate(511.200000, 384.666596, string);
/*...*/

format(string, sizeof(string), "FUEL: %d", veh[vehicleid][v_fuel]);
td_speed[2] = TextDrawCreate(511.200000, 402.916687, fuel);
/*...*/

//И т.п.

И зачем тебе две одинаковых проверки?

SteveStage
30.12.2019, 16:36
Получилось вот так (вместе с системой топлива):

@_UpdateSpeed(playerid, vehicleid);
@_UpdateSpeed(playerid, vehicleid)
{
if(GetPlayerState(playerid) != PLAYER_STATE_DRIVER)
{
for(new i; i < 4; i++) TextDrawDestroy(td_speed[i]);
return false;
}
new
getspeed = GetVehicleSpeed(vehicleid);
if(getspeed >= 1 && veh[vehicleid][v_fuel] > 0)
{
switch(getspeed)
{
case 1..20: used_fuel_veh[vehicleid] += 1;
case 21..40: used_fuel_veh[vehicleid] += 2;
case 41..80: used_fuel_veh[vehicleid] += 3;
case 81..100: used_fuel_veh[vehicleid] += 4;
case 101..130: used_fuel_veh[vehicleid] += 5;
}
}
if(used_fuel_veh[vehicleid] == 180 && 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);
SetVehicleParamsEx(vehicleid, VEHICLE_PARAMS_OFF, lights, alarm, doors, bonnet, boot, objective);
SCM(playerid, COLOR_RED, !"[SERVER] В вашем транспортном средстве кончилось топливо!");
SCM(playerid, COLOR_RED, !"[SERVER] Вы можете вызвать эвакуатор, который отбуксирует вас до ближайшей АЗС");
}
if(IsPlayerConnected(veh[vehicleid][v_ownerid]))
{
new
str[128+1];
format(str, sizeof(str), "UPDATE `vehicles` SET `fuel` = '%d' WHERE `tableid` = '%d'", veh[vehicleid][v_fuel], veh[vehicleid][v_tableid]);
mysql_function_query(connect_mysql, str, false, "", "");
}
}
new
string[16];
format(string, sizeof(string), "SPEED: %d KM/H", getspeed);
TextDrawSetString(td_speed[1], string);
format(string, sizeof(string), "FUEL: %d", veh[vehicleid][v_fuel]);
TextDrawSetString(td_speed[2], string);
format(string, sizeof(string), "LOCK: %s", (lock_veh{vehicleid} == true) ? ("LOCKED") : ("UNLOCKED"));
TextDrawSetString(td_speed[3], string);
speed_timer[vehicleid] = SetTimerEx("@_UpdateSpeed", 500, false, "dd", playerid, vehicleid);
return true;
}

public OnPlayerStateChange(playerid, newstate, oldstate)
{
if(newstate == PLAYER_STATE_DRIVER)
{
TD_CreateSpeed();
for(new i; i < 4; i++) TextDrawShowForPlayer(playerid, td_speed[i]);
speed_timer[vehicleid] = SetTimerEx("@_UpdateSpeed", 500, false, "dd", playerid, vehicleid);
}
}

stock TD_CreateSpeed()
{
td_speed[0] = TextDrawCreate(641.531494, 378.333312, "usebox");
TextDrawLetterSize(td_speed[0], 0.000000, 7.525930);
TextDrawTextSize(td_speed[0], 500.723266, 0.000000);
TextDrawUseBox(td_speed[0], true);
TextDrawBoxColor(td_speed[0], 102);

td_speed[1] = TextDrawCreate(511.200000, 384.666596, "SPEED: 0 KM/H");
TextDrawLetterSize(td_speed[1], 0.449999, 1.600000);
TextDrawAlignment(td_speed[1], 1);
TextDrawColor(td_speed[1], COLOR_ORANGE);
TextDrawSetShadow(td_speed[1], 0);
TextDrawSetOutline(td_speed[1], 1);
TextDrawBackgroundColor(td_speed[1], 255);
TextDrawFont(td_speed[1], 3);
TextDrawSetProportional(td_speed[1], 1);

td_speed[2] = TextDrawCreate(511.200000, 402.916687, "FUEL: 50");
TextDrawLetterSize(td_speed[2], 0.449999, 1.600000);
TextDrawAlignment(td_speed[2], 1);
TextDrawColor(td_speed[2], COLOR_ORANGE);
TextDrawSetShadow(td_speed[2], 0);
TextDrawSetOutline(td_speed[2], 1);
TextDrawBackgroundColor(td_speed[2], 255);
TextDrawFont(td_speed[2], 3);
TextDrawSetProportional(td_speed[2], 1);

td_speed[3] = TextDrawCreate(511.200000, 421.166778, "LOCK: UNLOCKED"); // 18,250091
TextDrawLetterSize(td_speed[3], 0.449999, 1.600000);
TextDrawAlignment(td_speed[3], 1);
TextDrawColor(td_speed[3], COLOR_ORANGE);
TextDrawSetShadow(td_speed[3], 0);
TextDrawSetOutline(td_speed[3], 1);
TextDrawBackgroundColor(td_speed[3], 255);
TextDrawFont(td_speed[3], 3);
TextDrawSetProportional(td_speed[3], 1);
}

В общем можно просто создать текстдравы спидометра один раз и изменять их через SetString, и нагрузки это не вызовет, да и цвет текста не меняется, а если гг не в машине - удалять текстдравы. И использовать 1 массив для каждого текстдрава поочередно.
Если кто-либо хочет сделать замечание - пожалуйста. Тему не закрывайте.