Ich war mal wieder im thread Tutorialwünsche und
habe da gesehen das ein Tutorial über HUDs mehrfach
gewünscht wird also habe ich mich entschlossen
ein Tutorial darüber zu schreiben.
Vorwissen das nötig ist:
-Grundlegendes über Variablen/Funktion
-Kenntnis einfacher Standart-Funktion(CustomMessage,SetPosition.....)
-Umgang mit einfachen Action
So das hier ist ein einfaches Beispiel für ein HUD es zeigt stehts
die Lebensenergie des aktiven Clonks als Zahlen-Wert:
Im folgenden zeige ich euch jetzt wie dieses HUD Stück für Stück entsteht.
Zuerst wird ein Neues Objekt mit dieser Grafik hier erstellt(oder eurer eigenen):
Es hat die maße 80x40 pixel und ist das eigentlich HUD.
DefCore:- Spoiler:
id=H19K
Version=4,9,8
Name=Anzeige
Category=C4D_StaticBack|C4D_Parallax|C4D_Foreground|C4D_MouseIgnore|C4D_IgnoreFoW
MaxUserSelect=0
Width=80
Height=40
Offset=-40,-20
Picture=0,0,80,40
Eigentlich eine sehr einfacher und übersichtlicher DefCore das
einzig entscheigende sind die Kathegorien:
C4D_StaticBack sorgt dafür dass das Objekt schwebt außerdem muss immer eine der ersten 5
Kathegorien gesetzt sein.
C4D_Foreground sorgt dafür das Objekt immer zu sehen ist und nicht hinter Häusern am Bildschirmrand verschwindet.
C4D_MouseIgnore Das HUD ist halt nur zum gucken und nicht zum anfassen da!
C4D_IgnoreFow Macht dass das HUD auch zu lesen ist wenn es bei Mauspielern z.b. im FoW liegen würde
C4D_Parallax Sorgt dafür das Objekt nicht einfach in der Gegend rumschwebt sondern immer (scheinbar) innerhalb des Sichtbereiches ist. Wo im Sichtbereich, dass
kann man mit SetPosition und den ersten beiden Localen Variablen steuern.Siehe hierzu
C4D_Parallax.
Der rest des DefCores legt eigentlich nur ID und Grafikkoordinaten fest.
Als nächstes brauchen wir regelmäßige Funktionsaufrufe dies kann man mit einem TimerCall machen was allerdings sehr Rechenlastig ist also arbeite ich mit einer
Actmap:
- Spoiler:
[Action]
Name=Time
StartCall=Timer
FacetBase=1
Delay=1
NextAction=Time
Die Action Time ruft einmal pro Tick/Frame die Funktion Timer auf die wir brauchen
um die Anzeige des HUDs auf dem neustem Stand zu halten.
Jetzt muss diese Objekt nur noch einen Script bekommen damit es auch so funktioniert wie wir wollen,
ich werde den jetzt erstmal hier schreiben und anschließend Stück für Stück erklären:
- Code:
-
/*--- HUD ---*/
#strict 2
func Initialize(){
SetVisibility(VIS_Owner);
SetAction("Time");
SetPosition(160,30);
}
func Timer(){
var clonk;
clonk=GetCursor(GetOwner(this));
if(clonk){
CustomMessage(Format("%d",GetEnergy(clonk)),
this,
GetOwner(this),
20,35,
Farbe(clonk));
}
}
func Farbe(object clonk){
//Grün
if(GetEnergy(clonk)>GetPhysical("Energy",0,clonk)/1000-20)return(RGB(0,180,0));
//Gelb
if(GetEnergy(clonk)>20)return(RGB(255,255,0));
//Rot
return(RGB(180,0,0));
}
- Code:
-
func Initialize(){
SetVisibility(VIS_Owner);
SetAction("Time");
SetPosition(160,30);
}
Die erste größere Funktion die beim erschaffen des Objects ausgefüht wird macht 3 Dinge:
1)Das HUD wird nur für den Besitzer sichtbar gemacht
2)Die Action des HUDs wird auf "Time" gesetzt denn die sorgt ja für Regelmäßige Funktionsaufrufe
3)Das HUD wird mittels SetAction auf die Position 160/30 gesetzt(siehe Spoiler für erklärung)
- Spoiler:
Das Object hat die Category C4D_Parallax und seine beiden Loaclen Local(0) und Local(1) haben jeweils den Wert 0,
das bedeuted das die Position die mit SetPosition gesetzt wird immer Relativ zur oberen linken Ecke des Sichtfensters ist
das HUD sich also 160 pixel Rechts von und 30 unter der linken oberen Ecke befindet.
Nach dieser kürzeren Funktion kommen wir nun zur Regelmäßig durch die Action "Time" aufgerufenen Funktion Timer()
- Code:
-
func Timer(){
var clonk;
clonk=GetCursor(GetOwner(this));
if(clonk){
CustomMessage(Format("%d",GetEnergy(clonk)),
this,
GetOwner(this),
20,35,
Farbe(clonk));
}
}
Hier wird zuerst eine locale Variable namens clonk angelegt in der der Aktive Clonk des Besitzers mittels
GetCursor ermittelt und gespeichert wird.Für den Fall das tatsächlich kein Clonk angewählt ist z.b. in einem Intro ist dann eine if-Abfrage ob überhaupt ein Clonk aktiv ist, ist es keiner hat clonk den wert 0/false. Anschließend werden mit
CustomMessage die Leben des Clonks ausgegeben.
Da die CustomMessage-Funktion hier viele Parameter verwendet erkläre ich diese alle nochmal:
CustomMessage(Format("%d",GetEnergy(clonk)),
//Die Funktion Format gibt einen String zurück der die Leben des Clonks darstellt this,
//macht das die Nachricht über diesem Object erscheint GetOwner(clonk),
//Macht das nur der besitzer des Clonks die Nachricht sehen kann 20,35,
//verschiebt die Nachricht um 20Pixel nach Rechts und 35 Nach unten so das sie auf dem HUD ist Farbe());
//Rufft die Funktion Farbe auf die einen Integerwert zurückgibt der einer Farbe entspricht.Auf diese weise hat die Schrift je nach Lebensstand eine Andere Farbe(Rot,Gelb,Grün)Und nun die schon genannte Funktion Farbe()
- Code:
-
func Farbe(){
//Grün
if(GetEnergy(clonk)>GetPhysical("Energy",0,clonk)/1000-20)return(RGB(0,180,0));
//Gelb
if(GetEnergy(clonk)>20)return(RGB(255,255,0));
//Rot
return(RGB(180,0,0));
}
Zuerst wird abgefragt ob der Clonk im Bereich max.Leben bis max.Leben-20 ist.
Hierzu wird die Physical "Energy" des Clonks abgefragt welche dem 1000-Fachen der
eigentlichen Leben entspricht und durch 1000 geteillt, so erhalten wir bei jeder Clonkart
den genauen Lebenswert.gibt die erste if-Klammer true zurück wird Grün als RGB-Wert
zurückgegeben an die Funktion CustomMessage die wir weiter oben besprochen haben
ansonsten wird abgefragt ob der Clonk wenigstens mehr als 20 Leben hat(ist
dies der Fall wird Gleb als RGB-Code zurückgegeben) und ist dies auch nicht der Fall
(Oh der arme Clonk
)wird Rot als RGB-Code zurückgegeben.
So damit ist das HUD fertig allerdings wird noch ein Appendto an den Clonk
benötigt damit der sich auch bei seiner erschaffaung ein HUD macht(falls der Spieler noch keins hat).
Dieses Appendto bekommt folgenden Code:
- Code:
-
//Das Clonk-Append
#strict 2
#appendto CLNK
//HUD erzeugen falls noch keins da ist
func Initialize(){
if(!FindObject2(Find_ID(H19K),Find_Owner(GetOwner())))
CreateObject(H19K,0,0,GetOwner());
return(_inherited());
}
protected func Death(int iKilledBy){
//Kein Clonk mehr dann HUD entfernen
if(!FindObject2(Find_OCF(OCF_CrewMember),Find_OCF(OCF_Alive),Find_Owner(GetOwner())))
RemoveObject(FindObject2(Find_ID(H19K),Find_Owner(GetOwner())));
return(_inherited(iKilledBy));
}
Und nun mal wieder schrittweise:
In der Initialize-Funktion wird zuerst abgefragt ob der Besitzer schon ein HUD hat, hierzu benutze ich
FindObject2 und suche nach einem Object mit der id des HUDs und dem Besitzer des Clonks falls es keins gibt wird einfach eins erschaffen mit CreateObject und anschließend wird mitt _inherited() die überladende Funktion aufgerufen.
- Code:
-
protected func Death(int iKilledBy){
//Kein Clonk mehr dann HUD entfernen
if(!FindObject2(Find_OCF(OCF_CrewMember),Find_OCF(OCF_Alive),Find_Owner(GetOwner())))
RemoveObject(FindObject2(Find_ID(H19K),Find_Owner(GetOwner())));
return(_inherited(iKilledBy));
}
Falls der Clonk stirbt wird wieder mit
FindObject2 nach einem Lebenden Crew Mitglied des Besitzers gesucht falls es keins mehr gibt wird das HUD des Besitzers gelöscht.
Feedback,Fragen und Fehlermeldungen auf jeden Fall erwünscht.
Dieses Tutorial wurde erneuert vielen dank hier an Umezava der mich drauf hingewiesen hat das ein HUD pro Spieler besser ist als eins pro Clonk und somit geholfen hat dieses Tutorial zu verbessern.Und natürlich vielen dank an alle die es durchgearbeited haben viel Spass weiterhin beim scripten hoffe ich konnte hiermit helfen.
Mit Freundlichen Grüßen Toastbrot