Clonk-Center Titelbild

Texte / Erstellung eines HUD (CNDG)




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 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:
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 Kategorien:

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 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:
[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:
/*--- 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));                
}


Die erste größere Funktion Initialize die beim erschaffen des Objects ausgefüht wird macht 3 Dinge:

  • Das HUD wird nur für den Besitzer sichtbar gemacht
  • Die Action des HUDs wird auf "Time" gesetzt denn die sorgt ja für Regelmäßige Funktionsaufrufe
  • Das HUD wird mittels SetAction auf die Position 160/30 gesetzt. Erklärung: 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(). 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(). 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 Erschaffung ein HUD macht (falls der Spieler noch keins hat).

Dieses Appendto bekommt folgenden 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));
}



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.

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.

Mit Freundlichen Grüßen Toastbrot (Übertragen vom CNDG von Tyron)