Partikel-Effekte programmieren ed
einzelne Partikel ed
allgemein ed
Ein Partikel ist ein (2D-) Bild, das in der 3D-Welt herumhängt und immer zur Kamera ausgerichtet ist.
Um das Verhalten eines Partikels festzulegen, kann eine Callback-Funktion beim Erschaffen mitgegeben werden, die regelmäßig ausgeführt wird.
Die Position (xxx.Pos) wird automatisch durch den aktuellen Wert der Geschwindigkeit (xxx.Vel) korregiert. Auch xxx.TimeToLive zählt automatisch nach unten und sobald es negativ wird, wird das Partikel gelöscht.
Partikel ed
Der Variablen-Typ für ein einziges Partikel ist particle.
Erschaffen werden kann es mit CreateParticle, gelöscht mit XDelete
Beispiel:
// Callback-Funktion
void ParticleFunc(particle p)
{
// langsam transparenter werden lassen
p.Color.a -= p.elapsed / 4.0f;
// loeschen, wenn es nicht mehr sichtbar ist
// (waere nicht noetig, da es automatisch geloescht wird...)
if (p.Color.a < 0)
p.TimeToLive = -1;
}
void CreateSomeParticles()
{
vector pos = vector(100, 100, 100);
int tex = LoadTexture("aaa.tga");
// einmalig 10 Partikel in einer Reihe erstellen
int i = 0;
while (i < 10){
// erstellen
particle p = CreateParticle( pos, tex,
&ParticleFunc,
5, // lebt 5 sec
10); // 10 le Radius
// Start-Werte festlegen
p.Color = Green; // gruen faerben
p.Source = rect(0, 1, 0, 0.5f); // nur einen Ausschnitt der Textur nehmen
p.Vel = vector(0, 100, 0); // mit 100 le/s nach oben fliegen lassen
pos.x += 10;
i ++;
}
}Weiterführend: Ein einfaches Partikel hängt in der Welt und hat immer die selbe Ausrichtung zur Kamera. Will man diese kontrollieren, muss es mit der Funktion CreateParticleRot erzeugt werden. Dadurch wird die Eigenschaft xxx.Ang verwendbar.
Strahlen ed
Strahlen sind auch (2D-) Bilder, die in der 3D-Welt hängen, allerdings werden sie zwischen zwei Punkten im Raum gespannt. Sie eignen sich zum Beispiel für Laser-Strahlen.
Der Variablen-Typ für einen Strahl ist beam.
Erschaffen werden kann es mit CreateBeam, gelöscht mit XDelete
Beispiel:
void main()
{
vector pos = vector(100, 100, 100);
vector dir = vector(1, 0, 0);
// Erschaffen
beam b = CreateBeam( pos,
dir * 200, // Laenge = 200, Richtung = dir
LoadTexture("aaa.jpg"), // eine Textur eben
NULL, // keine Callback-Funktion
5, // lebt 5 sec
10 ); // Dicke = 10
b.Vel = dir * 1000; // Geschwindigkeit = 1000/s in Richtung dir
}Effekte ed
allgemein ed
Effekte sind unsichtbare Objekte, die dazu genutzt werden können, regelmäßig Partikel zu emittieren.
Der Variablentyp ist effect.
Sie werden mit CreateEffect erschaffen und mit XDelete gelöscht.
Beispiel:
void ParticleFunc(particle p)
{
// ausblenden
p.Color.a -= p.elapsed * 0.25f;
}
void EffectFunc(effect fx)
{
// ein Partikel an der Effekt-Position erstellen
particle p = CreateParticle( fx.Pos, -1,
&ParticleFunc,
4, 10 );
// in zufaellige Richtung fliegen lassen
p.Vel = vector( randf(200) - 100,
randf(200) - 100,
randf(200) - 100 );
}
void CreateFunkyEffect()
{
// Effekt erschaffen
effect fx = CreateEffect( vector(100, 100, 100), // Position
&EffectFunc, // Callback-Funktion
-1 ); // bis in alle Ewigkeit
fx.Vel = vector(100, 0, 0); // Geschwindigkeit setzen
fx.FuncDeltaT = 1.0f; // Callback-Funktion nur jede Sekunde aufrufen
}im Editor einem Modell zuweisen ed
noch in der Entwicklung!!!
Um einem Modell zugewiesen werden zu können, benötigt ein Effekt eine spezielle Funktion, die ihn erzeugt. Diese muss als Parameter die Position entgegennehmen und den Effekt selbst zurückgeben.
Position und Geschwindigkeit des Effektes werden von der Engine automatisch mit dem Modell abgeglichen.
Zusätzlich wird xxx.Enabled = false gesetzt, sobald das Modell nicht mehr an einem Objekt in der 3D-Welt angehängt ist.
Beispiel:
void ParticleFunc(particle p)
{
...
}
void EffectFunc(effect fx)
{
CreateParticle(fx.Pos, -1, &ParticleFunc, 5, 10);
...
}
// diese Funktion im Editor fuer das Modell eintragen,
// sie wird dann von der Engine beim Laden des Modells einmalig ausgefuehrt
effect CreateSomeFancyEffect(vector pos)
{
// erschaffen
effect fx = CreateEffect(pos, &EffectFunc, 100);
// wichtig: Effekt in die Obhut der Engine uebergeben!
return(fx);
}komplizierter ed
Effekte sind nicht nur auf Partikel beschränkt. So können zum Beispiel Lichtquellen oder Geräuschquellen erschaffen werden.
Zusätzlich erschaffene Objekte sollten aber nicht in globalen Variablen gespeichert werden, denn sobald ein Effekt mehrfach erzeugt wird, würde dieser seine Objekte auch wieder in den selben Variablen speichern (und somit überschreiben)!
Für Effekt-eigene Daten gibt es deshalb den Array xxx.ScriptVar[] (Typ: float), der auch über xxx.ScriptVarI[] (Typ: int) sowie xxx.ScriptVarP[] (Typ: void*) angesprochen werden kann. Hierin können also auch Lichter, Geräusche und Partikel (nur, wenn sie nicht unabhängig vom Effekt sein können) etc gespeichert werden.
Beispiel:
// zur Vereinfachung ein Makro benutzen
#define _light ScriptVarI[0]
#define _sound ScriptVarI[1]
void EffectFunc(effect fx)
{
// die Position der Lichtquelle synchronisieren
FXLightSetRadial(fx._light, fx.Pos, 10000, Black, White, Black);
FXLightEnable(fx._light, fx.Enabled); // nur leuchten, wenn der Effekt aktiv ist
// Geraeusch synchronisieren
SoundSetData(fx._sound, fx.Pos, fx.Vel, 10000, 1.0f, 1.0f);
// Licht und Geräusch loeschen, falls der Effekt geloescht wird
if (!fx.Used){
FXLightDelete(fx._light);
SoundDelete(fx._sound);
}
}
void Create(vector pos)
{
effect fx = CreateEffect(pos, &EffectFunc, 20);
// Lichtquelle erschaffen und im Effekt speichern
fx._light = FXLightCreate();
FXLightSetRadial(fx._light, pos, 10000, Black, White, Black);
FXLightEnable(fx._light, true);
// Geraeusch erschaffen...
fx._sound = SoundCreate("some_sound.wav");
SoundSetData(fx._sound, pos, v0, 10000, 1.0f, 1.0f);
return(fx);
}