Author Topic: Explosions-Trümmelei  (Read 2037 times)

Offline Quentin

  • Prof. Inline
  • *****
  • Posts: 915
    • View Profile
Explosions-Trümmelei
« on: 2007-Jun-26 »
Versuche mich gerade an Explosionen mit umherfliegenden Trümmerteilen. Das folgende habe ich dabei zusammengeschustert. Klick auf linke Maustaste erzeugt an der aktuellen Mausposition eine Explosion. Die Anzahl der umherfliegenden Trümmer wird links oben angezeigt. Bei mehr als 5.000 Trümmerteilen ging mein Rechner allerdings schwer in die Knie. Wer bietet mehr? ;)

Mit den hier eingesetzten Werten komme ich jedoch auch bei gedrückt gehaltener Maustaste auf max. 1.100 Trümmerteile

Code: GLBasic [Select]
// --------------------------------- //
// Project: Explosion
// Start: Tuesday, June 26, 2007
// IDE Version: 4.225


// Typebeschreibung für die Explosionen
TYPE tExplosion
  picture           // ID für die Grafik
  x                 // horizontale Position auf dem Bildschirm
  y                 // vertikale Position auf dem Bildschirm
  direction         // Bewegungsrichtung (Winkel)
  rotation          // Rotationsgeschwindigkeit
  speed             // Geschwindigkeit der Partikel
  size              // aktuelle Größe der Partikel
  delay             // Pause bis zur nächsten Berechnung geht sonst zu schnell
ENDTYPE
GLOBAL Explosion[] AS tExplosion
GLOBAL newExplosion AS tExplosion

// lokale Variablen für Mausabfrage und Grafikerstellung
LOCAL mx, my, b1, b2, i, sx, sy


// erst mal ein paar Grafiken für die Partikel in
// unterschiedlicher Größe erstellen
// sieht mit richtigen Grafiken natürlich besser aus
FOR i = 0 TO 9
  FILLRECT 0, 0, 10+i, 10+i, RGB(255, RND(255), RND(128))
  GRABSPRITE i, 0, 0, 10+i, 10+i
NEXT

// Hauptschleife
SYSTEMPOINTER TRUE   // Mauscursor sichtbar machen
WHILE TRUE
  // mit Klick auf die linke Maustaste wird an der aktuellen
  // Mausposition eine Explosion erzeugt
  MOUSESTATE mx, my, b1, b2
  IF b1
    Make_Explosion(mx, my, RND(100) + 50, RND(100) + 50)
  ENDIF
  // und hier werden die Explosionen dargestellt
  Update_Explosions()
  SHOWSCREEN
WEND


// ------------------------------------------------------------- //
// -=#  MAKE_EXPLOSION  #=-
// ------------------------------------------------------------- //
FUNCTION Make_Explosion: x, y, width, height

  LOCAL wx, wy, pic

  // zufällig eine Partikelgrafik auswählen und deren Größe festhalten
  pic = RND(9)
  GETSPRITESIZE pic, wx, wy

  // die Anzahl der Partikel pro Explosion errechnet sich aus der
  // Größe des Explosionsbereiches, der mit den Parameters Breite (width)
  // und Höhe (height) angegeben wird. Hintergrund ist, daß eine
  // Explosion ja normalerweise dann erfolgt, wenn ein Objekt zerstört
  // wurde. Als width und height sollten dann die Breite und Höhe
  // der Objektgrafik mitgegeben werden. Je größer ein Objekt ist
  // desto mehr Partikel werden für die Explosion erzeugt
  count = width / wx + height / wx

  // nun werden die einzelnen Partikel der Explosion erzeugt
  FOR i = 1 TO count
    newExplosion.picture = pic          // zufällig ausgewählte Grafik
    newExplosion.x = x                  // Position übergeben
    newExplosion.y = y
    newExplosion.size = 1               // zu Begin ist die Größe noch normal
    newExplosion.rotation = RND(2)      // Rotationsgeschwindigkeit
    newExplosion.direction = RND(360)   // zufällige Bewegungsrichtung
    newExplosion.speed = RND(5) + 5     // und Geschwindigkeit (soll aber nicht zuuuu
                                        // langsam sein, sonst steht der Partikel dumm
                                        // in der Gegend rum
    DIMPUSH Explosion[], newExplosion   // und einfügen
  NEXT

ENDFUNCTION // MAKE_EXPLOSION


// ------------------------------------------------------------- //
// -=#  UPDATE_EXPLOSIONS  #=-
// ------------------------------------------------------------- //
FUNCTION Update_Explosions:

  // zur Info geben wir die Anzahl der Partikel aus
  PRINT BOUNDS(Explosion[], 0), 0, 0

  FOREACH ex IN Explosion[]
    // Partikel darstellen
    ROTOZOOMSPRITE ex.picture, ex.x, ex.y, ex.direction, ex.size
    IF GETTIMERALL() > ex.delay                 // Timer abwarten, da sonst die Darstellung zu schnell ist
      DEC ex.x, SIN(ex.direction) * ex.speed    // neue Position in Abhängigkeit von der
      DEC ex.y, COS(ex.direction) * ex.speed    // Bewegungsrichtung errechnen
      INC ex.direction, ex.rotation             // Rotation hinzufügen
      DEC ex.size, 0.03                         // Größe des Partikel verringern
                                                // je größer man diesen Wert wählt, umso schneller
                                                // verschwinden die Partikel wieder
      ex.delay = GETTIMERALL() + RND(50) + 10   // Verzögerung setzen, auch ein bißchen zufällig
      IF ex.size <= 0 THEN DELETE ex            // ist der Partikel nicht mehr sichtbar, dann
                                                // können wir ihn entfernen
    ENDIF
  NEXT

ENDFUNCTION // UPDATE_EXPLOSIONS