Auf Wunsch ein Tutorial über Textdraws:
Zitat
As the name implies, a textdraw is text that is drawn on a player's screen. Unlike client messages or gametext however, textdraws can be shown on a player's screen for an indefinite period of time. Textdraws can be simple text on the screen such as a website address, or complex scripted dynamic textdraws such as progress bars.
-wiki.sa-mp.com
Frei übersetzt sind Textdraws also "Zeichnungen", die wir individuell auf dem Bildschirm erstellen können. Diese Zeichnungen können lediglich aus Text bestehen, aber auch komplexere Systeme innehaben.
Es gibt 2 Arten von Textdraws.
1. Globale Textdraws
2. Playertextdraws
Globale Textdraws verhalten sich wie Globale Variablen. Sie zeigen für jeden Spieler den selben Inhalt, weswegen sie beispielsweise für Tachos ungeeignet sind, da ja jeder mit einer anderen Geschwindigkeit fährt. Würde man also für ein Tacho globale Textdraws erstellen, so würde sich der Inhalt immer wieder überschreiben.
Diese Art von Textdraws verwendet man überlicherweise, wenn man Informationen anzeigen lassen möchte, die jeden Spieler betreffen und für jeden Spieler gleich sind. Uhrzeit, Forumlink, TS-IP beispielsweise.
1.1 Das Erstellen Globaler TextDraws
Die wenigsten erstellen Textdraws per Hand; Die meisten verwenden einen "Textdraw-Editor".
Ich bevorzuge iPLEOMAX's TextDraw Editor (Installation ist in dem verlinktem Thread)
Nachdem die TextDraws erstellt wurden, kann man sie exportieren.
Mein Beispiel ( Bild & Code )
Wenn wir uns nun den Code anschauen, sehen wir ganz oben die Deklaration der einzelnen Textdraws.
new Text:Textdraw0;
new Text:Textdraw1;
new Text:Textdraw2;
new Text:Textdraw3;
new Text:Textdraw4;
new Text:Textdraw5;
Diese könnt ihr nun umbenennen, damit ihr es später einfacher habt.
( Zu beachten ist, dass ihr wirklich alles ersetzen müsst. -> STRG + H )
Darunter findet ihr die jeweiligen Codes für die einzelnen TextDraws.
Textdraw1 = TextDrawCreate(511.000000, 248.080001, "Informationen");
TextDrawLetterSize(Textdraw1, 0.460000, 1.600000);
TextDrawTextSize(Textdraw1, 635.000000, -36.399997);
TextDrawAlignment(Textdraw1, 1);
TextDrawColor(Textdraw1, -1);
TextDrawSetShadow(Textdraw1, 0);
TextDrawSetOutline(Textdraw1, 1);
TextDrawBackgroundColor(Textdraw1, 51);
TextDrawFont(Textdraw1, 3);
TextDrawSetProportional(Textdraw1, 1);
ist beispielsweise der Code für die Überschrift der Box.
Textdraw1 = TextDrawCreate(511.000000, 248.080001, "Informationen");
/*Zugewiesener Name = TextDrawCreate(x,y,text[]) */
TextDrawLetterSize(Textdraw1, 0.460000, 1.600000);
/* Höhe und Breite der Buchstaben */
TextDrawTextSize(Textdraw1, 635.000000, -36.399997);
/* Höhe und Breite des Textes */
TextDrawAlignment(Textdraw1, 1);
/* Alignment des Textes. ( Linksbündig == 1, zentriert == 2, rechtsbündig == 3 )*/
TextDrawColor(Textdraw1, -1);
/* Farbe des TextDraws. ( -1 ist vorderfiniert = weiß ). Man kann auch Gametext-phrasen verwenden
z.b: ~g~ .. */
TextDrawSetShadow(Textdraw1, 0);
/* Ob ein Schatten verwendet wird. 0 = nein, 1 = Ja */
TextDrawSetOutline(Textdraw1, 1);
/* Sollen die Buchstaben mit einer Linie nachgezogen werden? ( Zahl = Breite der Outline )*/
TextDrawBackgroundColor(Textdraw1, 51);
/* Hintergrundfarbe des Textdraws */
TextDrawFont(Textdraw1, 3);
/* Font des Textes. 1-3 Fonts, 4 = Sprites, 5- Previewmodel, 6-16 = nichts, >16 = crash */
TextDrawSetProportional(Textdraw1, 1);
/* Aktiviert die richtige Proportionalität. ( Richtiger Abstand zwischen den einzelnen Buchstaben */
Es gibt noch weitere Funktionen, diese werde ich im Laufe des Tutorials erklären.
Nun müssen wir die TextDraws in das Script implementieren. Dafür kopieren wir die Deklarationen in das MainScript ( dorthin, wo ihr sonst Variablen erstellt ).
Globale TextDraws werden üblicherweise beim Serverstart geladen. Deswegen kopieren wir die restlichen Codeabschnitte und fügen sie in "OnGameModeInit" ein.
Hier könnte man auch ein Callback erstellen, wenn man nicht möchte, dass "OnGameModeInit" unübersichtlich wird.
Die TextDraws sind nun erfolgreich erstellt, allerdings sind wir noch nicht fertig. Wir müssen sie noch für die Spieler sichtbar machen. Dafür brauchen wir die Funktion
"TextDrawShowForPlayer" bzw. "TextDrawShowForAll".
Logischerweise sollen die TextDraws angezeigt werden, wenn der Spieler auf den Server connectet. Deswegen verwenden wir die Funktion in "OnPlayerConnect".
Dort schreiben wir folgendes hin:
TextDrawShowForPlayer(playerid,Text:Name);
"Name" muss natürlich mit euren TextDraw Namen ersetzt werden. Hier gilt wieder: Wem das zu unübersichtlich wird, kann gerne ein Callback erstellen.
Was macht man, wenn die TextDraws durch einen Command angezeigt weden sollen?
Dafür gibt es "TextDrawShowForAll".
Das ist vom Prinzip das selbe wie oben; lediglich der "playerid" Parameter fällt weg.
Und wie löscht/versteckt man Globale TextDraws?
Hierfür gibt es die Funktionen "TextDrawHideForPlayer" bzw. "TextDrawHideForAll".
Diese Funktionen benötigen exakt die selben Parameter wie "TextDrawShowForPlayer" bzw. "TextDrawShowForAll". Sie haben nur eine andere Wirkung:
Sie "verstecken" ein TextDraw; machen es also nicht mehr sichtbar.
Um ein TextDraw zu löschen braucht man die Funktion "TextDrawDestroy".
TextDrawDestroy(text:Name);
Es folgen: PlayerTextDraws, Anklickbare TextDraws, Komplexere Systeme & Sprites.
( Ich poste das allerdings jetzt schon, da meinem Laptop langsam der Saft ausgeht und ich gerade kein Ladekabel parat habe. )
[font='Verdana, Helvetica, sans-serif']
[font='Verdana, Helvetica, sans-serif']1.2 Anklickbare Globale TextDraws
In meinem Beispiel habe ich ein TextDraw erstellt, welches den Inhalt "Do not open!" hat.
Ich möchte nun dieses Textdraw anklickbar machen. Dafür braucht man lediglich folgende Codezeile:
TextDrawSetSelectable(Textdraw5, true);
Das war leider nur der erste Teil, jetzt wird es etwas schwieriger. Wir müssen die Area bestimmen, welche anklickbar sein soll.
Dafür verwendet man "TextDrawTextSize".
Mit dieser Funktion ändert man die Größer der Box ( wenn sie aktiviert wurde ) und/oder die Fläche, die zum Anklicken anklickbar sein soll.
Diese Area herauszufinden sollte normalerweise kein Problem sein.
TextDrawTextSize(Textdraw5, 630.000000, 20.600021);
Wäre für mein Beispiel ein möglicher Code. Die letzte Zahl gibt die Höhe an. Logischerweise kann man demzufolge einen Text, der "20" angegeben hat, besser anklicken, als einen Text der "0.1" angegeben hat.
Sollte man den richtigen Bereich gefunden haben, kann man mit dem nächsten Schritt weitermachen.
Dieser beinhaltet lediglich die Funktion, einen Cursor anzeigen zu lassen, damit man den Text auswählen kann. ( Die Funktion gehört üblicherweise in einen Command )
SelectTextDraw(playerid,0x00FF00FF);
Der letzte Parameter gibt die Farbe an, die beim drüberfahren angezeigt werden soll. ( Hover )
Nun brauchen wir ein Callback, welches aufgerufen wird, sobald man ein TextDraw anklickt.
public OnPlayerClickTextDraw(playerid,Text:clickedid)
{
return 1;
}
Sollte dein Script dieses Callback noch nicht beinhalten, kannst du es einfach hinzufügen.
Hier wird es wieder einfach.
public OnPlayerClickTextDraw(playerid,Text:clickedid)
{
if(clickedid == INVALID_TEXT_DRAW)return SendClientMessage(playerid,-1," Auswahl abgebrochen!");
else if(clickedid == Textdraw5)
{
Kick(playerid);
}
return 1;
}
Sollte klar sein.
Wir schon erwähnt verhalten sich Globale TextDraws wie Globale Variablen. PlayerTextDraws hingegen sind spielerspezifisch. Das heißt, sie werden nur für einen Spieler erstellt und zeigen für diesen einen individuellen Inhalt an. ( Tacho beispielsweise )
2.1 Das Erstellen von PlayerTextDraws
Vom Prinzip her bleibt genau so wie bei den Globalen TextDraws.
Dafür habe ich wieder ein Beispiel erstellt.
Wenn man sich den Code anschaut, sieht man, dass dort 2 Teile sind. Globale Textdraws und PlayerTextDraws.
Letzteres wird wie folgt deklariert:
new PlayerText:Name[MAX_PLAYERS];
( Wer sich darunter nichts vorstellen kann, sollte sich mal mit Arrays auseinandersetzen )
Nun müssen wir den Code wieder in das Script implementieren. Dafür kopieren wir wieder die Deklarationen und fügen sie in den Kopf-Bereich des Main-Scripts ein.
Danach kopieren wir die Textdraw-Codes und fügen die PlayerTextDraws in OnPlayerConnect ein und die Globalen TextDraws in OnGameModeInit.
Auch hier gilt wieder: Wem das zu unübersichtlich wird, kann ein Callback erstellen.
Textdraw0[playerid] = CreatePlayerTextDraw(playerid, 177.000000, 1.679998, "Raven");
/* Die Variable des Arrays wird zugewiesen */
PlayerTextDrawLetterSize(playerid, Textdraw0[playerid], 0.449999, 1.600000);
/* Siehe Globale TextDraws */
PlayerTextDrawAlignment(playerid, Textdraw0[playerid], 1);
/* Siehe Globale TextDraws */
PlayerTextDrawColor(playerid, Textdraw0[playerid], -1);
/* Siehe Globale TextDraws */
PlayerTextDrawSetShadow(playerid, Textdraw0[playerid], 0);
/* Siehe Globale TextDraws */
PlayerTextDrawSetOutline(playerid, Textdraw0[playerid], 1);
/* Siehe Globale TextDraws */
PlayerTextDrawBackgroundColor(playerid, Textdraw0[playerid], 51);
/* Siehe Globale TextDraws */
PlayerTextDrawFont(playerid, Textdraw0[playerid], 2);
/* Siehe Globale TextDraws */
PlayerTextDrawSetProportional(playerid, Textdraw0[playerid], 1);
/* Siehe Globale TextDraws */
Wie man sieht, sind die Funktionen gleich. Sie haben nur einen anderen Namen und benötigen andere Paramter.
Die PlayerTextDraws müssen auch erste sichtbar gemacht werden. Das geschieht mit PlayerTextDrawShow(playerid,PlayerText:Name[playerid]);
( Natürlich wieder in "OnPlayerConnect" bzw. dorthin, wo die TextDraws sichtbar gemacht werden sollen )
Kommen wir nun dazu, den Inhalt der TextDraws zu ändern.
Diese wären momentan:
-Name
-HP
-Schutzwestenzustand in Worten
-Schutzwestenzustand in Prozent
Dafür brauchen wir "PlayerTextDrawSetString". Diese Funktion ändert den Inhalt eines PlayerTextDraws.
Um den Namen zu ändern, brauchen wir also folgenden Code:
new name[MAX_PLAYER_NAME];
GetPlayerName(playerid,name,sizeof(name));
PlayerTextDrawSetString(playerid,PlayerText:Textdraw0[playerid],name);
Zu beachten ist, dass "Textdraw0" zuerst erstellt werden muss!
Das selbe könnt ihr mit "HP" und "Armor" machen.
2.2 Anklickbare PlayerTextDraws
Der Aufbau ist exakt der selbe wie mit Globalen TextDraws. Einfach die Schritte von oben wiederholen.
Lediglich das Callback ist anders:
public OnPlayerClickPlayerTextDraw(playerid, PlayerText:playertextid)
{
if(playertextid == Textdraw[playerid])
{
/*
..
*/
}
return 1;
}
Zu guter letzt gibt es noch sog. "Sprites". Diese sind kleine Bilder, welche man als TextDraw anzeigen lassen kann.
Der Aufbau ist der selbe wie bei den anderen TextDraws, lediglich 2 Unterschiede sind vorhanden:
Wenn man Sprites verwenden will, muss man die Font auf "4" setzen.
TextDrawFont(..,4 );
Der Text gibt den Sprite an:
[pwn]TextDrawCreate(...,...,"library:texture");
Ein Beispiel hierfür wäre:
TextDrawCreate(100,100,"LD_BEAT:upr"); // Grauer Pfeil
Siehe
-Der Text eines TextDraws darf nicht leer sein. Solltest du einen "leeren Text" brauchen, kannst du "~n~" als Inhalt angeben.
-Keystates ( z. b "~k~~VEHICLE_ENTER_EXIT~" ) funktionieren nicht mehr, sobald sie hinter dem 255. Buchstaben angezeigt werden.
-Sollte der letzte Buchstabe ein Leerzeichen sein, ist der ganze Text nicht sichtbar
-Falls der Text über den Bildschirmrand hinausgeht, wird die Farbe des Textes nicht mehr sichtbar sein.
-Es können maximal 2048 Globale-und 256 PlayerTextDraws gleichzeitig existieren.
-Textsize variiert je nach align des Textdraws
-Um den Wert des anklickbaren Textdraws zu ermitteln kann man auch eine Box erstellen & diese um den Text legen.
-PlayerTextDraws werden beim Verlassen des Spielers automatisch zerstört.
-Man kann "GameTextColors" in TextDraws verwenden.
-Sollte das Alignment eines bereits existierenden TextDraws verändert werden, so muss er erneut angezeigt werden, damit die Änderung in Kraft tritt.
-Man kann die Zahl, die als Y- Parameter angegeben wurde, mit 0.135 multiplizieren, damit man eine geeignete Zahl für "TextDrawTextSize" erhält.
-Sollte einem bereits existierendem TextDraw eine Box hinzugefügt werden, so muss er erneut angezeigt werden, damit die Änderung in Kraft tritt.
-(Player-)TextDrawSetSelectable muss vor dem Erstellen des TextDraws definiert werden!
Das war's eigentlich auch schon mit dem Tutorial. Sollte ich etwas vergessen haben oder einen Fehler gemacht haben, könnt ihr mich darauf hinweisen.
-Raven
Edits:
Teil 1+2 zusammengefügt ( Danke seegras
)
3:: Beitrag von [DT]Sniper hinzugefügt + 3. hinzugefügt; 4:: Sprites hinzugefügt