PDA

View Full Version : Textdraw összeakadás


Silent.Hunter
30/04/2010, 08:02 AM
Hello,
nemrég írtam egy fügvényt amit SecondLifeTXTTimer-nek kereszteltem el. Ennek a fügvénynek a használatával a képernyő alján létrehoz egy csíkot benne egy szöveggel.

Például: SecondLifeTXTTimer(playerid,"A kocsi beindításához használd: /start", 5000);
| - Maga a fügvény
| - célszemély
| - szöveg
| - megjelenítési idő milsec-ban, Ez jelen esetben 5000 - 5 másodperc.

Tehát ez a fügvény tökéletesen működik amig csak 1 játékosról van szó. Tegnap kipróbáltam a szervert több játékossal is és volt akinek egymás helyére rakódtak és volt akinek működött normálisan.... Volt hogy felváltva... A válaszokat előre is köszönöm.

Mellékeltem a forráskódot is... hátha az segít:
public SecondLifeTXTTimer(playerid,szoveg[],timer)//by silenthunter
{
if(IsPlayerConnected(playerid))
{
KillTimer(sltxttim);
SecondLifeTXTDelete(playerid);
sltxt = TextDrawCreate(txtx, txty, szoveg);
TextDrawUseBox(sltxt , 1);
TextDrawFont(sltxt , 1);
TextDrawBoxColor(sltxt ,txtbox);
TextDrawShowForPlayer(playerid, sltxt);
sltxttim = SetTimer("SecondLifeTXTDelete", timer, 0);
}
return 1;
}

public SecondLifeTXTDelete(playerid)//by silenthunter
{
if(IsPlayerConnected(playerid))
{
TextDrawHideForPlayer(playerid, sltxt);
}
return 1;
}

MPKaboose
30/04/2010, 08:17 AM
new sltxt[ MAX_PLAYERS ],
sltxttim[ MAX_PLAYERS ];
public OnGameModeInit( )
{
sltxt = TextDrawCreate( txtx, txty, " " ); // ezt hagy üressen
TextDrawUseBox( sltxt, 1 );
TextDrawFont( sltxt, 1 );
TextDrawBoxColor( sltxt, txtbox );
TextDrawShowForPlayer( playerid, sltxt );
return true;
}
public SecondLifeTXTTimer( playerid, szoveg[ ], timer ) // by silenthunter
{
if( IsPlayerConnected( playerid ) )
{
TextDrawSetString( sltxt[ playerid ], szoveg );
TextDrawShowForPlayer( playerid, sltxt[ playerid ] );
sltxttim = SetTimerEx( "SecondLifeTXTDelete", timer, false, "i", playerid );
}
return true;
}
public SecondLifeTXTDelete( playerid ) // by silenthunter
{
if( IsPlayerConnected( playerid ) )
{
TextDrawHideForPlayer( playerid, sltxt );
}
return true;
}

Te azt hibáztad el ,hogy minden játékosnak ugyan azt a timert és textdraw-ot használtad ezert keveredett ösze remélem ,hogy ez majd segít

Silent.Hunter
30/04/2010, 08:59 AM
Megcsináltam... bár nem lett jó. Mindenkinek ugyan azt írja... pl egy játékos beül egy járműbe mindenkinek kiírja hogy "Használd: /start a motor beindításához"
És a textdraw eltorzul... vmiért más az alakja...

MPKaboose
30/04/2010, 09:04 AM
nos én mostan suliba megyek utána majd segítek meg oldani ;)

Silent.Hunter
30/04/2010, 09:34 AM
Megoldottam a problémát. Köszönöm a segítséget ;)

MPKaboose
30/04/2010, 12:29 PM
Megoldottam a problémát. Köszönöm a segítséget ;)
Az jó hír mi volt a baj?

Silent.Hunter
30/04/2010, 01:26 PM
Te azt hibáztad el ,hogy minden játékosnak ugyan azt a timert és textdraw-ot használtad ezert keveredett ösze
Ezen az alapon írtam újra a rendszert...
Pédlául sltxt helyett sltxt[playerid] -t hazsnáltam. Ezáltal csak annak a játékosnak hozza létre a szöveget.

Végül kipróbáltam a te megoldásod:

new sltxt[ MAX_PLAYERS ],
sltxttim[ MAX_PLAYERS ];
public OnGameModeInit( )
{
sltxt = TextDrawCreate( txtx, txty, " " ); // ezt hagy üressen
TextDrawUseBox( sltxt, 1 );
TextDrawFont( sltxt, 1 );
TextDrawBoxColor( sltxt, txtbox );
TextDrawShowForPlayer( playerid, sltxt );
return true;
}
public SecondLifeTXTTimer( playerid, szoveg[ ], timer ) // by silenthunter
{
if( IsPlayerConnected( playerid ) )
{
TextDrawSetString( sltxt[ playerid ], szoveg );
TextDrawShowForPlayer( playerid, sltxt[ playerid ] );
sltxttim = SetTimerEx( "SecondLifeTXTDelete", timer, false, "i", playerid );
}
return true;
}
public SecondLifeTXTDelete( playerid ) // by silenthunter
{
if( IsPlayerConnected( playerid ) )
{
TextDrawHideForPlayer( playerid, sltxt );
}
return true;
}
Ezzel több problémám is volt.
Pédául a TextDrawSetString( sltxt[ playerid ], szoveg ); fügvény felesleges. Hisz nincs semilyen tároló amiből beolvashatná a karaktereket.
Utána az onGamodeModeInit-nél egy ilyen fügvény: TextDrawShowForPlayer( playerid, sltxt );... "Undefined symbol "playerid"... és most a logikát követve...
Az OnGamemodeInit fügvényt töbször is meghívja másodpercenként... ezért másodpercenként töbször is megjelenítené a textdrawn-t. Ez lag-hoz és egyébb kellemetlenségekhez vezethet.
Na és a TexdrawHideForPlayer fügvény kell a SecondLifeTXTTimer elejére. Ez eltünteti a korábban létrehozott TXT-t ha hamarabb jönne új üzenet mint ahogy az előző eltünne. Mivel ez egy dinamikus rendszer.

De a te kódot alapján kovácsoltam össze a jó kódot. tehát tartozom egy köszönettel ;)

A helyes kód:
public SecondLifeTXTTimer( playerid, szoveg[ ], timer ) // by silenthunter
{
if( IsPlayerConnected( playerid ) )
{
TextDrawHideForPlayer( playerid, sltxt[playerid] );
// TextDrawSetString( sltxt[ playerid ], szoveg );
sltxt[playerid] = TextDrawCreate( txtx, txty, szoveg );
TextDrawUseBox( sltxt[playerid], 1 );
TextDrawFont( sltxt[playerid], 1 );
TextDrawBoxColor( sltxt[playerid], txtbox );
TextDrawShowForPlayer( playerid, sltxt[ playerid ] );
sltxttim[playerid] = SetTimerEx( "SecondLifeTXTDelete", timer, false, "i", playerid );
}
return true;
}
public SecondLifeTXTDelete( playerid ) // by silenthunter
{
if( IsPlayerConnected( playerid ) )
{
TextDrawHideForPlayer( playerid, sltxt[playerid] );
}
return true;
}

MPKaboose
30/04/2010, 03:52 PM
Az OnGamemodeInit fügvényt töbször is meghívja másodpercenként... ezért másodpercenként töbször is megjelenítené a textdrawn-t. Ez lag-hoz és egyébb kellemetlenségekhez vezethet.

az nem igaz és a gamemodeinit alatt egy loop segítségével el készítheted egyszer minden játékosnak a textdrawot minthogy "végtelenül" újra készítsd a SecondLifeTXTTimer-t ahányszor azt hívod annyiszor újat készít

Silent.Hunter
30/04/2010, 07:07 PM
Nem igaz? Hmm... azt hiszem akkor öszekevertem az OnPlayerUpdate-val nem?

MPKaboose
30/04/2010, 07:49 PM
Nem igaz? Hmm... azt hiszem akkor öszekevertem az OnPlayerUpdate-val nem?
erre bezeg igent mondok :P

smeti
30/04/2010, 07:53 PM
Az OnGamemodeInit fügvényt töbször is meghívja másodpercenként... ezért másodpercenként töbször is megjelenítené a textdrawn-t. Ez lag-hoz és egyébb kellemetlenségekhez vezethet.

az nem igaz és a gamemodeinit alatt egy loop segítségével el készítheted egyszer minden játékosnak a textdrawot minthogy "végtelenül" újra készítsd a SecondLifeTXTTimer-t ahányszor azt hívod annyiszor újat készít


Így van az OnGameModeInit függvény csak egyszer hívódik meg, mikor a szerver elindul és nem ismétlődik folyamatosan. Ezt egyszerűen letudod ellenőrizni:

public OnGameModeInit()
{
new
H,
M,
S;
gettime(H, M, S);
printf("Teszt szerver üzenet! Szerver Start, time: %02d:%02d:%02d", H, M, S);
return 1;
}

Megnézed mennyiszer jeleníti meg ezt az üzenetet mikor elindítod a szervert, persze megnézheted a server_log.txt fájlban is.

És a textdraw:
Ha dinamikusan változó textdraw-ot akarsz létrehozni akkor egy for vagy while ciklus segítségével létre kell hoznod minden játékosnak egy textdraw_ot, az OnGameModeInit függvény alatt. Utána az általad kreált public funkcióban, elég csak elrejteni majd megváltoztatni a textdraw szövegét és újra megjeleníteni. Felesleges leterhelni a szervert folyamatos textdraw létrehozással.


#include <a_samp>

new
Text:sltxt[MAX_PLAYERS];

#define txtbox 0xC0C0C0AA
new
Float:txtx = 570.00,
Float:txty = 310.00;

public OnGameModeInit()
{
CreateTextDraw();
return true;
}

stock CreateTextDraw()
{
for(new i = 0, max_p = GetMaxPlayers(); i < max_p; i++) // Létrehozunk annyi textdrawot amennyi a max slotok száma.
// Azért kell elvileg annyi textdraw amennyi játékos van mivel mindegyiknek más tartalommal kell megjeleníteni.
{
sltxt[i] = TextDrawCreate(txtx, txty, " ");
TextDrawUseBox(sltxt[i], 1);
TextDrawFont(sltxt[i], 1);
TextDrawBoxColor(sltxt[i], txtbox);
}
return true;
}

forward SecondLifeTXTTimer(playerid, szoveg[], timer);
public SecondLifeTXTTimer(playerid, szoveg[], timer)
{
if(IsPlayerConnected(playerid))
{
TextDrawHideForPlayer(playerid, sltxt[playerid]); // Elrejtjük a textdrawot a playerid előtt
TextDrawSetString(sltxt[playerid], szoveg); // Megváltoztatjuk a textdraw szövegét.
TextDrawShowForPlayer(playerid, sltxt[playerid]); // Majd megjelenítjük újra a textdrawot a megváltoztatott tartalommal.
SetTimerEx("SecondLifeTXTHide", timer, false, "i", playerid); // Elindítunk egy nem ismétlődő timert ami arra hivatott hogy egy bizonyos idő után meghívjon egy olyan
// funkciót, ami elrejti a játékos előtt a textdrawot.
}
return true;
}

forward SecondLifeTXTHide(playerid);
public SecondLifeTXTHide(playerid) // Ide is azért kell public funkció mivel timer segítségével van meghívva.
{
if(IsPlayerConnected(playerid)) // Ezt feleslegesnek tartom de itt hagytam hátha a textdraw elrejtésének ideje túl hosszú és közben kilép a játékos.
{
TextDrawHideForPlayer(playerid, sltxt[playerid]); // Textdraw elrejtése
}
return true;
}

// Fura kiírások elkerülése végett a dinamikus textdrawot nem árt elrejteni játékos csatlakozáskor

public OnPlayerConnect(playerid)
{
TextDrawHideForPlayer(playerid, sltxt[playerid]);
return true;
}


Mondjuk nem így kellene működni, de ez a módszer vált be nálam kilométeróra textdraw esetén. :D

Silent.Hunter
01/05/2010, 10:43 AM
Kösz Phento. Végül a te megoldásod alkalmazom ;)