Speedo Help
#1

Hey guys. I am working on a speedo and I cant get it to work. It shows a whole bunch of numbers overlapping. Could anyone help?

pawn Код:
public UpdateSpeedoMeter()
{
        for(new playerid; playerid < GetMaxPlayers(); playerid++ )
        {
            if(IsPlayerInAnyVehicle(playerid))
            {
                new Float:CurPos[4]Float:OldPos[4];
                GetVehiclePos(GetPlayerVehicleID(playerid), CurPos[1], CurPos[2], CurPos[3]);
                new Float:A = OldPos[1] - CurPos[1];
                if(A < 0.0) A = -A;
                new Float:B = OldPos[2] - CurPos[2];
                if(B < 0.0) B = -B;
                new Float:C = OldPos[3] - CurPos[3];
                if(C < 0.0) C = -C;
                new Float:vSpeed = A + B + C;
                vSpeed *= 2;
               
                format(string, sizeof(string), "MPH: %i", vSpeed);
                Speedo[playerid] = TextDrawCreate(497 ,397 , string);
                TextDrawShowForPlayer(playerid, Speedo[playerid]);
            }
        }
}
Reply
#2

The mistake is here
pawn Код:
format(string, sizeof(string), "MPH: %i", vSpeed);
use %f to format a float

Another little remark
pawn Код:
if(C < 0.0) C = -C; // 0.0 can also be just 0
Don't forget commas
pawn Код:
new Float:CurPos[4], Float:OldPos[4];
And after all I don't get how adding up the distance changes would lead to your velocity, I'd rather do it like this
pawn Код:
new Float:VehVelocity[4];

GetPlayerVelocity(playerid, VehVelocity[0], VehVelocity[1], VehVelocity[2]);
VehVelocity[3] = floatsqroot(VehVelocity[0] * VehVelocity[0] + VehVelocity[1] * VehVelocity[1] + VehVelocity[2] * VehVelocity[2])
Reply
#3

Yea I just re wrote the way to get velocity to well. Pretty much what you put. Haha. Thanks for the help.
Reply
#4

Be careful about making those little mistakes I remarked. Reread your code a few times before posting because you don't necesserily need us to tell you about them

Anyways, glad to have helped you.
Reply
#5

EDIT: Same error



heres the code. It uses a timer under OnGameModeInit
pawn Код:
public UpdateSpeedoMeter()
{
        for(new playerid; playerid < GetMaxPlayers(); playerid++ )
        {
            if(IsPlayerInAnyVehicle(playerid))
            {
                new Float:vVelocity[3], string[200];
                GetVehicleVelocity(GetPlayerVehicleID(playerid), vVelocity[0], vVelocity[1], vVelocity[2]);
                new Float: vSpeed = floatsqroot(floatpower(vVelocity[0], 2) + floatpower(vVelocity[1], 2) + floatpower(vVelocity[2], 2)) * 99;
                format(string, sizeof(string), "MPH: %f", vSpeed);
                Speedo[playerid] = TextDrawCreate(497 ,397 , string);
                TextDrawShowForPlayer(playerid, Speedo[playerid]);
            }
        }
}
Reply
#6

pawn Код:
Speedo[playerid] = TextDrawCreate(497 ,397 , string);
TextDrawShowForPlayer(playerid, Speedo[playerid]);
Your function creates the textdraws but doesn't destroy them (lines: 19-20).

You could add:
pawn Код:
TextDrawHideForPlayer(playerid, Speedo[playerid]);
Speedo[playerid] = TextDrawCreate(497 ,397 , string);
TextDrawShowForPlayer(playerid, Speedo[playerid]);
However I don't recommend it.
Every unused textdraw should be destroyed, not hidden, but it's not so easy to do - remember that if you try to desroy a non-existing textdraw, you'll have a problem with other textdraws scripted on your server.

What about OnPlayerStateChange? If a player changes his state for a driver, you can create your speedo textdraw once and then update it regularly in your UpdateSpeedoMeter() function. And destroy the textdraw if the player exits the vehicle:

pawn Код:
public OnPlayerStateChange(playerid, newstate, oldstate)
{
        if(newstate == PLAYER_STATE_DRIVER)
        {
            Speedo[playerid] = TextDrawCreate(497, 397, "_"); //Creating empty textdraw for a player
            TextDrawShowForPlayer(playerid, Speedo[playerid]);
        }
        else TextDrawDestroy(Speedo[playerid]);
        return 1;
}

[...]

public UpdateSpeedoMeter()
{
        for(new playerid; playerid < GetMaxPlayers(); playerid++ )
        {
            if(IsPlayerInAnyVehicle(playerid))
            {
                new Float:vVelocity[3], string[200];
                GetVehicleVelocity(GetPlayerVehicleID(playerid), vVelocity[0], vVelocity[1], vVelocity[2]);
                new Float: vSpeed = floatsqroot(floatpower(vVelocity[0], 2) + floatpower(vVelocity[1], 2) + floatpower(vVelocity[2], 2)) * 99;
                format(string, sizeof(string), "MPH: %f", vSpeed);
                TextDrawSetString(Speedo[playerid], string);
            }
        }
}
Reply
#7

Quote:
Originally Posted by Sznupek
Посмотреть сообщение
pawn Код:
Speedo[playerid] = TextDrawCreate(497 ,397 , string);
TextDrawShowForPlayer(playerid, Speedo[playerid]);
Your function creates the textdraws but doesn't destroy them (lines: 19-20).

You could add:
pawn Код:
TextDrawHideForPlayer(playerid, Speedo[playerid]);
Speedo[playerid] = TextDrawCreate(497 ,397 , string);
TextDrawShowForPlayer(playerid, Speedo[playerid]);
However I don't recommend it.
Every unused textdraw should be destroyed, not hidden, but it's not so easy to do - remember that if you try to desroy a non-existing textdraw, you'll have a problem with other textdraws scripted on your server.

What about OnPlayerStateChange? If a player changes his state for a driver, you can create your speedo textdraw once and then update it regularly in your UpdateSpeedoMeter() function. And destroy the textdraw if the player exits the vehicle:

pawn Код:
public OnPlayerStateChange(playerid, newstate, oldstate)
{
        if(newstate == PLAYER_STATE_DRIVER)
        {
            Speedo[playerid] = TextDrawCreate(497, 397, "_"); //Creating empty textdraw for a player
            TextDrawShowForPlayer(playerid, Speedo[playerid]);
        }
        else TextDrawDestroy(Speedo[playerid]);
        return 1;
}

[...]

public UpdateSpeedoMeter()
{
        for(new playerid; playerid < GetMaxPlayers(); playerid++ )
        {
            if(IsPlayerInAnyVehicle(playerid))
            {
                new Float:vVelocity[3], string[200];
                GetVehicleVelocity(GetPlayerVehicleID(playerid), vVelocity[0], vVelocity[1], vVelocity[2]);
                new Float: vSpeed = floatsqroot(floatpower(vVelocity[0], 2) + floatpower(vVelocity[1], 2) + floatpower(vVelocity[2], 2)) * 99;
                format(string, sizeof(string), "MPH: %f", vSpeed);
                TextDrawSetString(Speedo[playerid], string);
            }
        }
}
But don't have to destroy a textdraw before updating it right?
Reply
#8

its not a good idea to create a textdraw anywhere else than the OnGameModeInit(). the max TD limit (serversided) is 2048. so if you create the 2049-st textdraw, it will fuck up.
despite the extra CPU time needed plus the bandwidth for setting the clients textdraws position, font, shadow, color etc. is not needed when a textdraw exists "forever". try to
Код:
OnGameModeInit(){
new Speedo[MAX_PLAYERS];
pay attention at the middle line. no need to create a new textdraw each time. just set its string...
Код:
format(string, sizeof(string), "MPH: %i", vSpeed);
TextDrawSetString(Speedo[playerid],string);//that instead of destroying, creating again. simply modify it :)
TextDrawShowForPlayer(playerid, Speedo[playerid]);
Reply
#9

if(C < 0.0) C = -C; // 0.0 can also be just 0
That was not true by the way, I tested it
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)