Energie Bälle

Vor Hunderten von Jahren lebte ein böser Zauberer in einer Höhle. Früher schleuderte er den ganzen Tag lang mit Energiebällen, doch irgendwann gingen sie ihm aus und er starb. Seine Kunst war für immer verloren... halt, noch nicht ganz! Ich habe die Höhle gefunden und dort war das Skript an die Wand geschrieben. Ok, es war in alter WDL Syntax geschrieben, aber ich habe es etwas aufpoliert und jetzt sieht es in Ordnung aus. :)

action wizard
{
   clip_size = 0;
   while (1)
   {
      while (my.skill10 < 95)
      {
         ent_cycle ("attack", my.skill10); 
         my.skill10 += 3 * time;
         wait (1);
      }
      eball_pos.x = my.x;
      eball_pos.y = my.y;
      eball_pos.z = my.z + 25; 
      ent_create (energyball_mdl, eball_pos, energy_ball);
      snd_play (energy_snd, 70, 0);
      waitt (16);
      while (my.skill10 > 2)
      {
         ent_cycle ("attack", my.skill10); 
         my.skill10 -= 2 * time;
         wait (1);
      }
      waitt (32);
    }
}

Die erste Zeile der Action sagt der Engine, dass sie alle Polygone für alle Models zeichnen soll. Der Zauberer wird seine Hände bewegen ("Angriff"); der Energieball wird 25 Quants über dem Zentrum des Zauberermodels erstellt. Dieser wird wieder seine Hände (in umgekehrter Richtung) bewegen und nach 2 Sekunden wiederholt sich alles.

function energy_ball()
{
   wait (1);
   my.enable_entity = on;
   my.enable_block = on;
   my.event = remove_eball;
   my.pan = you.pan;
   my.tilt = you.tilt;
   my.lightred = 250;
   my.lightgreen = 150;
   my.lightrange = 200;
   eball_speed.x = 20;
   eball_speed.y = 0;
   eball_speed.z = 0;
   eball_speed *= time;
   while (my != null)
   {
      my.roll += 20 * time;
      move_mode = ignore_you + ignore_passents;
      ent_move (eball_speed, nullvector);
      wait (1);
   }
}

function remove_eball()
{
   wait (1);
   if (you == player)
   {
      player._health -= 60; // decrease player's health
   }
   ent_remove (me);
}

Der Ball reagiert auf Entities und Blocks. Wenn er mit einer Entity kollidiert (dem Spieler, einem Fahrstuhl, etc.) oder mit einer Wand, dann wird das remove_eball Event aufgerufen. Der Ball erhält denselben Pan und Tilt wie die erzeugende Entity (der Zauberer) und generiert ein orange farbenes Licht in 200 Quants Radius. Solange der Ball existiert, bewegt er sich mit der Geschwindigkeit gegeben durch eball_speed.x und rotiert, indem er seinen roll Winkel ändert.

Wenn er mit etwas zusammenstößt, wird geprüft, ob es der Spieler ist. Wenn ja, werden 60 Punkte von der Gesundheit des Spielers abgezogen. Am Ende der Even Funktion wird der Ball dann entfernt.
 

Disco

Dieser Code kombiniert Musik mit farbigen Lichtern. Ich habe ein eigenständiges Projekt entwickelt, aber Sie können den Code mit Leichtigkeit in Ihre eigenen Projekte einfügen.

Als erstes die Main Funktion:

function main()
{
   d3d_lightres = 1; 
   fps_max = 50; 
   level_load (disco_wmb);
   wait (2); // wait for the level to be loaded
   set_camera();
   waitt (80);
   while (1)
   {
      if (sound_handle == 0)
      {
         snd_loop (music_snd, 80, 0);
         sound_handle = result;
      }
      wait (1);
   }
}

Wir setzen d3d_lightres auf 1; dies erhöht die Qualität der dynamischen Lichter. Außerdem setzen wir die Framerate auf 50 fps fest, laden das Level, setzen die Kamera und spielen die Musik (wav Datei) in einer Schleife. Ich habe als Beispiel ein kurzes Musikstück ausgewählt, aber Sie können es mit einer anderen Datei ersetzen.

function set_camera()
{
 camera.tilt = -90;
 camera.y = -100;
 camera.z = 800;
 wait (1);
}

Die Funktion set_camera sucht sich eine geeignete Position und einen Winkel für die Kamera. Spielen Sie ein wenig mit den obigen Werten, um andere Blickwinkel zu erzielen.

Aber was ist das Besondere an diesem Disco Licht Code? Ich könnte doch eine unsichtbare Entity verwenden, die auf einem Pfad läuft und Licht erzeugt, oder?
Sicher könnte ich das tun, aber der Code plaziert das Licht auf dem Boden in Abhängigkeit davon, wo der Strahler an der Wand ist, wie im Bild unten:

Jede Lichtfarbe hat 2 Entities und 2 Actions, wir haben disco_red (diese Action ist dem roten Licht auf dem Boden zugewiesen) und red_spot (für den roten Strahler), etc.

Schauen wir uns die Action an, die das rote Licht auf dem Boden erzeugt:

entity* redspot_pnt;

action disco_red
{
   my.invisible = on;
   my.passable = on;
   my.lightrange = 0;
   my.lightred = 250;
   waitt (16 + random(32));
   snd_play (poweron_snd, 30, 0);
   my.lightrange = 200;
   while (1)
   {
      my.x = redspot_pnt.z * tan (redspot_pnt.pan);
      my.y = redspot_pnt.z * tan (redspot_pnt.roll);
      wait (1);
   }
}

Die Entity ist unsichtbar, passierbar und wird rotes Licht erzeugen (lightred = 250). Nach 1..3 Sekunden spielen wir den "Power On" Sound und geben dem Licht eine Reichweite von 200 Quants. Das Licht wird sich auf dem Boden bewegen, indem es seine x und y Koordinaten in Abhängigkeit von der Position und dem Winkel von redspot_pnt ändert.

action red_spot
{
   redspot_pnt = me;
   my.light = on;
   my.lightrange = 0;
   my.lightred = 250;
   waitt (80);
   while (1)
   {
      my.pan = 30 - random(60);
      my.roll = -10 - random(50);
      waitt (2);
   }
}

Der Strahler leuchtet rot, ich verwende dasselbe Model für alle Strahler (rot, grün und blau) und benutze verschiedene Werte für lightred, lightblue und lightgreen, damit sie verschieden aussehen.

Der Strahler wartet ca. 5 Sekunden (ich benutze den gleichen Wert in der Main, erinnern Sie sich?) und beginnt dann seinen pan und roll in einer wilden Schleife zu ändern. Diese Werte hängen von der Level Geometrie ab und Sie sollten ein wenig damit experimentieren. Sie können auch andere Kombinationen von Werten ändern (pan und tilt, tilt und roll, etc.), solange sie dieselben Werte in der disco_red Action benutzen. Ehe ich es vergesse, hier die Mathematik zum Code:
 

Für grün und blau geht es ebenso.