Wasserfall

Ich denke, dass ein guter Wasserfall mit dem folgenden Rezept erstellt werden kann: mischen Sie eine transparente WMB Entity mit einem Code, der die Textur verändert und fügen Sie einige Partikel hinzu. Und das werde ich jetzt tun.

action waterfall
{
my.transparent = on;
while (1)
{
my.v -= 30 * time;

Die Action waterfall wird der Wasserfall Entity zugewiesen. Diese ist transparent und die Textur bewegt sich, weil wir den v parameter ändern; so sieht alles in Wed aus:

Ich kann die Frage schon hören: was ist so besonders an dieser Entity?

Nun ja, wir müssen die Breite des Wasserfalls kennen (130 Quants in dem Beispiel) und wir müssen ihren Ursprung so setzen, wie Sie es in der Back View erkennen können. Auf diese Weise werden die Partikel direkt in der Region erstellt, die den Wasserfall und den Pool trennt und man braucht keinen komplizierten Code oder weitere Entities als Partikelgeneratoren.

vec_set (temp, my.pos);
temp.y += 60 - random(120);
effect (water_splash, 1, temp, normal);
wait (1);
}
}

Wir verwenden temp, um die Position der Wasserfall entity zu speichern und addieren eine Zufallszahl zwischen -60 und 60 Quants in y Richtung. Dieses wird water_splash Partikelgeneratoren plazieren, die zufällig in y-Richtung verteilt sind. Die Partikel werden mit der gewöhnlichen "effect" Anweisung erstellt, mit 1 Partikel pro Frame. Ich habe die Anzahl der so erzeugten Partikel nicht limitiert, ein PC mit 100 fps wird 100 Partikel pro Sekunde anzeigen. Auf diese Weise können schwächere Rechner so viel anzeigen, wie sie können. Wenn Sie möchten, können Sie mehrere Partikel auf einmal erzeugen und sleep(x) anstelle von wait(1) benutzen.

Schauen wir uns die Funktion an, die Partikel erzeugt:

function water_splash()
{
temp.x = random(4) - 2;
temp.y = random(2) - 1;
temp.z = random(1) + 1;
vec_add (my.vel_x, temp);
my.alpha = 10 + random(10);
my.bmap = water_pcx;
my.size = 20 + random(10);
my.flare = on;
my.move = on;
my.bright = on;
my.lifespan = 200;
my.function = splash_fade;
}

Die Partikel haben zufällige Geschwindigkeiten in x (-2 bis 2) und y-Richtung (-1 bis 1) und eine positive z Geschwindigkeit (1 bis 2), weil sie aufsteigen sollen. Wie Sie sehen beginnen die Partikel ihr Leben mit einem zufälligen alpha-Wert und einer Lebensspanne von 200 Ticks. Die Funktion, die die Partikel schließlich bewegt, ist die Folgende:

function splash_fade()
{
my.size += 5 * time;
my.alpha -= 1 * time;
if (my.alpha < 0)
{
my.lifespan = 0;
}
}

Das Partikel vergrößert sich und wird zugleich transparenter, während es zu sehen ist. Wenn es unsichtbar wird (alpha < 0), entfernen wir es, um keine Ressourcen zu vergeuden. Sie sollten in der Lage sein, gut aussehende Wasserfälle anhand dieses Beispiels zu konstruieren.

Sie könnten zufällig verschiedene Splash Bitmaps wählen, die Werte für alpha und die Größe ändern, Flags setzen usw. Viel Glück!

Zerbrechliche Fenster

Lesen Sie diesen Artikel und finden Sie heraus, wie man ein Fenster erstellt, dass zerbricht, wenn man darauf schießt oder wenn der Spieler hindurchspringt. Der Spieler sollte auch einen Teil seiner Lebensenergie verlieren, wenn er das tut, richtig?

action breakable_glass
{
my.transparent = on;
my.enable_impact = on;
my.enable_entity = on;
my.enable_shoot = on;
my.event = glass_pieces;
}

Diese Action wird Ihren Fenstern zugewiesen und macht sie transparent, sowie sensitiv gegenüber impact, shoot und anderen Entities. Wenn eines dieser Events zutrifft, wird die Funktion glass_pieces ablaufen:

function glass_pieces()
{
if (you == player) {player._health -= 20;} // decrease player's health if it breaks the window by passing through it
my.passable = on;
snd_play (breakglass_snd, 50, 0);
my.skill10 = 0;
my.invisible = on;
while (my.skill10 < 15)
{
create (gibglass_mdl, my.pos, gib_glass);
my.skill10 += 1;
wait (1);
}
ent_remove (me);
}

Wenn der Spieler durch das Fenster "läuft", wird seine Lebensenergie um 20 Punkte gesenkt. Das Fenster wird passierbar gemacht, damit die Glassplitter hindurchkönnen, ein Geräusch wird abgespielt und das Fenster wird unsichtbar gemacht. Vielleicht fragen Sie sich, warum ich das Fenster selbst noch nicht entfernt habe - die Antwort ist, dass ich gern skill10 der Fensterentitiy als einen Counter nutzen möchte und 15 Glasfragmente in einer Schleife erzeugen will. Sobald alle Splitter erzeugt sind, wird das große Fenster entfernt.

Hier ist die gib_glass() Funktion:

function gib_glass()
{
my.transparent = on;
my.skill1 = random(200) - 100;
my.skill2 = (random(100) + 25) * sign (my.y - player.y);
my.skill3 = -random(25) - 10;
my.skill1 *= time; // all the values (skill1..skill3) are multiplied with time
my.pan = random(360);
my.tilt = random(360);
my.roll = random(360);
while(my.skill40 < 10)
{
move_mode = ignore_passable;
ent_move (nullvector, my.skill1);
my.skill3 -= 20 * time;
my.skill40 += time;
wait(1);
}
my.passable = on;
while (my.alpha > 0)
{
my.alpha -= 0.3 * time;
wait (1);
}
ent_remove (me);
}

Die Splitter sind transparent; wir benutzen skill1 bis skill3 als lokale Variablen. Jedes Glasfragment bewegt sich in eine zufällige Richtung (ent_move), wie Sie sehen reicht die Bewegung in x Richtung von -100 bis 100 (skill1) und die Bewegung in z Richtung reicht von -35 bis -25 (skill3), weil die splitter ja herunterfallen sollen. Aber was ist mit der Bewegung in y-Richtung und warum sollte diese von der Position des Spielers abhängen?

Mal schauen ob ein Bild wirklich mehr sagt als 1000 Worte:

Wenn der Spieler auf das Fenster schießt, viele Splitter sollten auf die andere Seite des Fensters fallen. Skill2 (y Geschwindigkeit) ändert sein Vorzeichen, je nach der Position des Spielers und das Fensters.

Die Splitter erhalten zufällige Werte für pan, tilt und roll. Skill3 (z-Geschwindigkeit) sinkt mehr und mehr und die Fragmente kommen dem Boden Frame für Frame immer näher. Wenn die Bewegung stoppt, machen wir die Fragmente passierbar und senken ihren alpha-Wert bis sie verschwinden.