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 überschrieben werden, die regelmäßig ausgeführt wird.

Die Position (Particle.pos) wird automatisch durch den aktuellen Wert der Geschwindigkeit (Particle.vel) korregiert. Auch Particle.time_to_live 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.

Beispiel:

class MyParticle extends Particle
    # Callback-Funktion
    override void on_iterate(float dt)
        # langsam transparenter werden lassen
        self.color.a -= dt / 4.0

        # löschen, wenn es nicht mehr sichtbar ist
        #   (eigentlich nicht nötig, da es automatisch gelöscht wird...)
        if self.color.a < 0
            time_to_live = -1

void CreateSomeParticles()
    vector pos = vector(100, 100, 100)
    int tex = LoadTexture("aaa.tga")

    # einmalig 10 Partikel in einer Reihe erstellen
    for i in 0:10

        # erstellen
        Particle *p = new MyParticle(pos, tex,
                                     5,     # lebt 5 sec
                                     10 )   # 10 le Radius
        # Start-Werte festlegen
        p.color = Green                    # grün färben
        p.source = rect(0, 1, 0, 0.5)      # nur einen Ausschnitt der Textur nehmen
        p.vel = vector(0, 100, 0)          # mit 100 le/s nach oben fliegen lassen

        pos.x += 10

Weiterführend: Ein einfaches Partikel hängt in der Welt und hat immer die selbe Ausrichtung zur Kamera. Will man diese kontrollieren, muss die Klasse ParticleRot verwendet werden. Dadurch wird die Eigenschaft ParticleRot.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.

Beispiel:

void main()
    vector pos = vector(100, 100, 100)
    vector dir = vector(1, 0, 0)

    # Erschaffen
    Beam *b = new Beam(pos,
                       dir * 200,              # Länge = 200, Richtung = dir
                       LoadTexture("aaa.jpg"), # eine Textur eben
                       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.

Beispiel:

class MyParticle extends Particle
    override void on_iterate(float dt)
        # ausblenden
        self.color.a -= dt * 0.25

class MyEffect extends Effect
    override void on_iterate(float dt)
        # ein Partikel an der Effekt-Position erstellen
        Particle *p = new MyParticle(fx.Pos, -1,
                                     4, 10)

        # in zufällige Richtung fliegen lassen
        p.vel = vector(rand(200) - 100,
                       rand(200) - 100,
                       rand(200) - 100)

    override void on_init()
        # Callback-Funktion nur jede Sekunde aufrufen
        func_delta_t = 1.0

void CreateFunkyEffect()
    # Effekt erschaffen
    Effect *fx = new MyEffect(vector(100, 100, 100), # Position
                              -1 )                   # bis in alle Ewigkeit

    fx.vel = vector(100, 0, 0)                      # Geschwindigkeit setzen

im Editor einem Modell zuweisen ed

...

komplizierter ed

Effekte sind nicht nur auf Partikel beschränkt. So können zum Beispiel Lichtquellen oder Geräuschquellen erschaffen werden.

Das Script und seine globalen Variablen existieren nur einmal im Speicher. D.h. Mehrere Instanzen desselben Effekts teilen sich die globalen Variablen. Deshalb eignen sich diese nicht zum Speichern von Daten, die einem einzelnen Effekt gehören sollen!

Um einem Effekt weitere Daten anhängen zu können, muss deshalb eine neue Klasse abgeleitet werden, die die zusätzlichen Daten enthält.

Beispiel:

class MyEffect extends Effect
    Light *light
    Sound *sound

    override void on_iterate(float dt)
        # die Position der Lichtquelle synchronisieren
        light.set_radial(pos, 10000)

        # Geräusch synchronisieren
        sound.set(pos, vel, 10000, 1.0, 1.0)

    override void on_enable()
        light.enabled = enabled # nur leuchten, wenn der Effekt aktiv ist

    override void on_delete()
        # Licht und Geräusch löschen, falls der Effekt gelöscht wird
        delete light
        delete sound

    override void on_init()
        # Lichtquelle erschaffen und im Effekt speichern
        light = new Light
        light.set_colors(Black, White, Black)
        light.set_radial(pos, 10000)
        light.enabled = true

        # Geräusch erschaffen...
        sound = LoadSound("some_sound.wav")
        sound.set(pos, v_0, 10000, 1.0, 1.0)