Hallo allemaal.
In deze tut ga ik het hebben over hudelements.
Dit is de 1e van de delen. Dit deel is het novice gedeelte.
In dit deel wordt alles uitgelegd.
Laten we maar eens beginnen
Dit is het script voor een standaard hud:
self.streak = newClientHudElem(self);
self.streak.archived = false;
self.streak.x = 580;
self.streak.y = 400;
self.streak.sort = 9998;
self.streak.fontscale = 1;
self.streak.label = &"^1Spyplane";
self.streak.alpha = 1;
Laten we nu eens kijken hoe het allemaal werkt:
self.streak = newClientHudElem(self);
Laat het spel weten dat het een hudelement is, die gecast wordt op (in dit geval dan) self.
Als je dit voor alle spelers wil laten doen, kan je hetvolgende doen:
player = getentarray("player", "classname");
for(a=0;a
{
player = player[a];
player.streak = newClientHudElem(player);
player.streak.archived = false;
player.streak.x = 580;
player.streak.y = 400;
player.streak.sort = 9998;
player.streak.fontscale = 1;
player.streak.label = &"^1Spyplane";
player.streak.alpha = 1;
}
zo call je voor iedere speler apart de hud
MAAR
wat ook kan en waarschijnlijk wel beter is is hetvolgende:
level.streak = newHudElem();
level.streak.archived = false;
level.streak.x = 580;
level.streak.y = 400;
level.streak.sort = 9998;
level.streak.fontscale = 1;
level.streak.label = &"^1Spyplane";
level.streak.alpha = 1;
zo maakt het spel een hud aan voor ieder object dat een hud kan zien.
self.streak.archived = false;
Dit is voornamelijk voor killcams.
- Als archived op true staat, dan zal de hud de waarde aannemen die hij had op het moment waarop het spel gezien wordt.
- Als archived op false staat, dan zal de hud de waarde aannemen die hij normaliter zou hebben.
self.streak.x = 580;
Positie op de x-as
self.streak.y = 400;
Positie op de y-as
self.streak.sort = 9998;
Dit zorgt ervoor welke hud voor welke komt al komen ze in elkaar. De hud met de hogere .sort value komt boven. Dus 1 komt boven 0 en 9998 komt onder 9999.
self.streak.fontscale = 1;
Grootte van de text
self.streak.label = &"^1Spyplane";
De text van de hudelement. Deze kan ook geregeld worden door:
- self.streak setText(&"text");
- self.streak setValue(var);
setText is gewoon voor een string met text
setValue is voor een int var, dus een var met een getalwaarde.
Je kan ook twee van deze functies gebruiken, behalve met plaatjes. En setValue() en setText() kunnen niet samen. Dus moet je .label en setValue()/setText() gebruiken, en de .label komt dan altijd voor de setValue()/setText().
ook kan je plaatjes setten op een hud:
hhudup setShader("gfx/hud/hud@health_cross.tga", 20, 15);
"gfx/hud/hud@health_cross.tga" is het plaatje
20 is de grootte op de x as
15 is de grootte op de y as
self.streak.alpha = 1;
is de dichtheid van de text
1 = normaal
0 = niet zichtbaar
0.5 = doorzichtig
Mag alle waardes hebben van 0 tot 1
(staat er hier niet bij maar) self.streak.color = (1,1,1);
(red, green, blue), met waardes van 0-1
Er zijn (+-) 20 dingen die je kan gebruiken op huds, maar dit zijn de meest belangrijke voor nu.
Wat ook niet bepaald onbelangrijk is is het precachen van huds. Iedere string moet geprecached worden aan het begin van het laden van de gametype. Hier alle precaches van een gametype:
precacheString(&"MPSCRIPT_PRESS_ACTIVATE_TO_SKIP");
precacheString(&"MPSCRIPT_KILLCAM");
precacheString(&"SD_MATCHSTARTING");
precacheString(&"SD_MATCHRESUMING");
precacheString(&"SD_EXPLOSIVESPLANTED");
precacheString(&"SD_EXPLOSIVESDEFUSED");
precacheString(&"SD_ROUNDDRAW");
precacheString(&"SD_TIMEHASEXPIRED");
precacheString(&"SD_ALLIEDMISSIONACCOMPLISHED");
precacheString(&"SD_AXISMISSIONACCOMPLISHED");
precacheString(&"SD_ALLIESHAVEBEENELIMINATED");
precacheString(&"SD_AXISHAVEBEENELIMINATED");
precacheMenu(game["menu_team"]);
precacheMenu(game["menu_weapon_allies"]);
precacheMenu(game["menu_weapon_axis"]);
precacheMenu(game["menu_viewmap"]);
precacheMenu(game["menu_callvote"]);
precacheMenu(game["menu_quickcommands"]);
precacheMenu(game["menu_quickstatements"]);
precacheMenu(game["menu_quickresponses"]);
precacheShader("black");
precacheShader("white");
precacheShader("hudScoreboard_mp");
precacheShader("gfx/hud/hud@mpflag_spectator.tga");
precacheStatusIcon("gfx/hud/hud@status_dead.tga");
precacheStatusIcon("gfx/hud/hud@status_connecting.tga");
precacheHeadIcon(game["headicon_allies"]);
precacheHeadIcon(game["headicon_axis"]);
precacheShader("ui_mp/assets/hud@plantbomb.tga");
precacheShader("ui_mp/assets/hud@defusebomb.tga");
precacheShader("gfx/hud/hud@objectiveA.tga");
precacheShader("gfx/hud/hud@objectiveA_up.tga");
precacheShader("gfx/hud/hud@objectiveA_down.tga");
precacheShader("gfx/hud/hud@objectiveB.tga");
precacheShader("gfx/hud/hud@objectiveB_up.tga");
precacheShader("gfx/hud/hud@objectiveB_down.tga");
precacheShader("gfx/hud/hud@bombplanted.tga");
precacheShader("gfx/hud/hud@bombplanted_up.tga");
precacheShader("gfx/hud/hud@bombplanted_down.tga");
precacheShader("gfx/hud/hud@bombplanted_down.tga");
precacheModel("xmodel/mp_bomb1_defuse");
precacheModel("xmodel/mp_bomb1");
Zoals je kunt zien, zijn strings niet het enige wat geprecached moet worden.
Bij huds zijn er 2 precaches:
precacheString(&"{string}");
precacheShader("{shader}");
{string} is hier gewoon de hele text die je in een hud zet, dus uit het voorbeeld is het
precacheString(&"^1Spyplane");
{shader} is de plek + naam van het plaatje, dus zoals je kunt zien in het voorbeeld:
precacheShader("gfx/hud/hud@objectiveA.tga");
"gfx/hud" is de plek en "hud@objectiveA.tga" is de naam. Nu heb je misschien een probleem bij plaatjes zoeken, want sommige plaatjes zijn een .dds bestand. Dan moet je gewoon de naam van het plaatje pakken en van de .dds .tga maken, en dan kan je hem gewoon gebruiken.
Er zijn ook nog een paar functies die je kan gebruiken op huds
self.streak fadeOverTime(1);
wait 1;
self.streak.alpha = 0;
Met dit laat je de hud over 1 seconde langzaam verdwijnen.
Bij mij werkt dit soms niet (geen idee waarom) en ipv fadeOverTime kan je ook dit script gebruiken:
destroy=0;
while(hhudup.alpha > 0)
{
destroy += 0.05;
hhudup.alpha -= destroy;
wait 0.05;
}
Alleen wel oppassen, dit script werkt alleen maar voor 1 seconde.
Al wil je andere tijden gebruiken, moet je een beetje experimenteren met
destroy += 0.05; hhudup.alpha -= destroy;
Een andere veelvoorkomende functie is self.streak destroy();
Dit laat een hud destroyen.
Deze functie zal je veel gebruiken met whiles, aangezien cod maximaal iets van 1012 huds mag hebben, en al maak je er telkens 1 opnieuw zonder hem ook weer weg te halen, dan krijg je errors.
Ook zal dit vaak tezamen gaan met if(isDefined(self.streak)), want al bestaat hij niet je je vernietigd hem, kan je ook errors krijgen.
Er zijn nog wat functies, maar hier kom ik in deel 2 op terug, want dan gaan we verder 'klooien' met huds.
Dan gaan we nu alles een beetje uit te hebben gelegd eens kijken/proberen een script te maken met wat huds.
Ik doe meestal vanaf Callback_playerConnect universele huds spawnen (servernaam bijv) en anders doe ik het op een bepaalde tijd in een script (bijv een killstreak hud).
Ik heb in de callback_playerConnect de thread aangeroepen die wij hier bespreken, en ik heb hem met self aangeroepen (de speler)
hud()
{
self.hudname = newClientHudElem(self);
self.hudname.archived = false;
self.hudname.x = 580; // de plekken vergeten we even, want dat is opzich wel irrelevant
self.hudname.y = 400; // de plekken vergeten we even, want dat is opzich wel irrelevant
self.hudname.sort = 9998;
self.hudname.fontscale = 1;
self.hudname.label = self.name; // heel nutteloos, maarja...
self.hudname.alpha = 1;
if(!isDefined(level.credit)) // Als deze hud al bestaat, hoeft hij niet nog eens gemaakt te worden :P.
{
level.credit = newHudElem();
level.credit.archived = false;
level.credit.x = 15; // de plekken vergeten we even, want dat is opzich wel irrelevant
level.credit.y = 500; // de plekken vergeten we even, want dat is opzich wel irrelevant
level.credit.sort = 9998;
level.credit.fontscale = 1;
level.credit.label = &"^5B^7ucket^5h^7ead ^5R^7ockz!";
level.credit.alpha = 1;
}
// natuurlijk is de vorige hud een beetje stom om zo aan te maken,
// maar dit is even om het verschil te laten zien. Als je slim bent
// call je een thread enkel aan het begin van een gametype om
// level.huds/newHudElem() aan te maken.
}
Uiteraard zijn de strings geprecached.
Hier kun je dus een beetje het verschil zien tussen de twee huds, bijvoorbeeld dat de eerste gewoon gecalld kan worden zonder if's, want de speler connect maar 1x en er zal dus ook maar 1 hud gemaakt worden. Maar de tweede hud word zonder if iedere keer als er een speler connect gemaakt, wat niet nodig is. Wat misschien een mooier voorbeeld is is dit:
hud2()
{
player = getentarray("player", "classname"); //
for(i=0;i
level.players++; //
if(isDefined(level.playerhud)) //
level.playerhud destroy(); // DEEL 2
level.playerhud = newHudElem(); //
level.playerhud.archived = false; //
level.playerhud.x = 15; // // de plekken vergeten we even, want dat is opzich wel irrelevant
level.playerhud.y = 500; // DEEL 3 // de plekken vergeten we even, want dat is opzich wel irrelevant
level.playerhud.sort = 9998; //
level.playerhud.fontscale = .8; //
level.playerhud.label = &"Number of players: ";
level.playerhud setValue(level.players); //
level.playerhud.alpha = 1; //
}
Wat dit script doet is een int var maken van alle spelers (zie deel 1), de hud destroyen als hij bestaat om dubbele huds te verkomen (zie deel 2) en de hud aan te maken met als text "Number of players: " en met als waarde het aantal spelers.
Het beste voor dit script is om aangeroepen te worden in de callback_playerconnect en callback_playerdisconnect, want dan verandert het aantal spelers.
Dit was deel 1, hopelijk klaart dit wat dingen op, en
stay tuned voor deel 2, waarin we meer gecompliceerde scripts behandelen.