Welcome to the new Friends-of-FPC!

Here you can find all kinds of information about the FreePascal Compiler. We have many tutorials and howtos as well as a selection of tools to help you with your programming. We also have some example codes for you. And if you want to contribute some information/ sources/ tools yourself you can do so.
Also we have finally relaunched the FoFPC forum. It's your chance for some Q&A about everything FreePascal.

Friends-of-FPC

Tutorials: Learn how to code with FreePascal.

Source Codes: A collection of examples, miscellaneous source codes and open source stuff.

Tools and Help Files: Intro- duction of some tools that might help you with FPC.

Community

Forum: Ask or answer questions about the FreePascal Compiler, programming or just babble about coding.

Contribute! Contribute your own Tutorial, Source Codes or Tools and send them to us!

Website

About: Information about Friends-of-FPC.org.

Grundlagen der Grafikprogrammierung - Teil 16 - by Delax

Grüße!

Also der Titel lautet "Partikel" und vielleicht können sich auch einige vorstellen, was damit gemeint ist. Was ihr aber nicht erwarten solltet ist ein Hyper-Hooper 3D Partikel-System. Erstens mal sind wir noch nicht bei 3D und zweitens ist so was, wenn man es richtig macht, ziemlich kompliziert. Wir nehmen eher den "kleinen Bruder" durch.

Also was erwartet euch? Ich werde euch zeigen wie man eine Struktur erstellt, mit der man mühelos eine beliebige Anzahl Partikel unter Kontrolle halten kann und diese steuert. Und für alle die nicht wissen, was überhaupt ein Partikel ist fange ich jetzt lieber einmal von vorne an...

Ein Partikel ist laut Definition ein kleiner materieller Körper (interessanterweise anscheinend abgeleitet von einem Splitter des Kreuzes Christi). In der Grafikprogrammierung bedeutet es ähnliches. Hier kann man einen Partikel als kleinstes Element einer größeren Struktur definieren. Partikelsysteme werden an den unterschiedlichsten Stellen eingesetzt. Ein Anwendungsgebiet ist die korrekte Darstellung von Objekten, die streng genommen aus vielen kleinen Objekten (Partikeln) bestehen: Wasser, Nebel, Explosionen, ... aber auch, um andere Effekte zu erzeugen, die mit vielen einzelnen Elementen arbeiten.

Bleiben wir einmal bei dem Wasser. Das gesamte Objekt ist hierbei der See und die Partikel die einzelnen Wassertropfen, die einen Wasserfall hinunter stürzen. Da jeder Tropfen einzeln berechnet wird, kostet ein Partikelsystem eine Menge Leistung. Doch keine Sorge - ihr müsst nicht jeden Frame euren Partikeln neuen Werte liefern, ihr könnt schon in der Struktur festlegen, wie sie sich verhalten sollen und bei jedem Programm/ Effekt einfach nur noch die Umweltvariablen festlegen.

Fangen wir also an einmal an die Sache durchzudenken. Jeder Partikel benötigt einen X/ Y Wert, an den er gezeichnet wird. Dazu kommt noch ein VektorX/ VektorY, der die grundlegende Geschwindigkeit des Partikel festlegt (Beispielsweise wie schnell er bei einer Explosion weggeschleudert wird). Als nächstes benötigen wir einen Wert für die Gravitation (die Teile der Explosion werden natürlich nach unten gezogen), einen für die Lichtintensität des Pixels (die Teile verglühen langsam) und dann einen Status (aktiv, inaktiv, was auch immer). Dazu ist es immer klug einfach mal 2 Variablen für zusätzliche Modifikationen zu deklarieren. Hier nun die gesamte Struktur:

TYPE  partikelsystem =	record
			 PositionX, PositionY : Longint;
			 VektorX, VektorY : Longint;
			 ModX, ModY : Longint;
			 Status, Intensity : Longint;
			 Gravity : Longint;
			end;

So. Tief durchatmen. Das sieht auf den ersten Blick nach zu vielen Variablen und verschwenderischer Programmierung aus. Ist es wohl auch, aber zur Hölle mit Speicher sparen! Sind wir im DOS und haben nur 640Kb? Mal angenommen man würde 2 Variablen a 4 Byte sparen - bei 5000 Partikeln macht das 40.000 Byte oder auch ~39Kb. Lächerlich. Sparen sollte man am richtigen Ende und Variablen und Hauptspeicher gehören seit 1997 nicht mehr zu einer wertvollen Ressource (jaja - was Microsoft uns doch alles beschert).

Das sind im Moment alles Longint Werte. In Wirklichkeit würde man für einige eher Real Werte nehmen, um in komplexeren Formeln mehr Spielraum zu haben, aber für uns reicht es erst einmal.

Wie man mit dieser Struktur nun etwas anfängt erkläre ich euch am besten an einem Beispiel. Nehmen wir einmal ein typisches Partikelsystem, wie ihr es schon bestimmt in Spielen, Demos und sonstwo gesehen habt: Partikel werden aus einem Punkt auf dem Bildschirm in zufällige Richtungen geschleudert.

Nehmen wir mal eine moderate Anzahl von Partikeln...sagen wir 200. Dazu definieren wir einen Array vom Typ unserer Struktur:

      partikel : ARRAY[1..200] of partikelsystem;

Jetzt haben wir 200 Partikel, die alle die Struktur besitzen, die wir vorhin definiert haben. Nun müssen wir als erstes die ganzen Partikel initialisieren:

for counter1 := 1 TO 200 DO BEGIN
Partikel[counter1].PositionX := 320;
Partikel[counter1].PositionY := 240;
Repeat Partikel[counter1].VektorX := random(10)-5 
	until Partikel[counter1].VektorX <> 0;
Repeat Partikel[counter1].VektorY := random(10)-5 
	until Partikel[counter1].VektorY <> 0;
Partikel[counter1].Status := 0;
Partikel[counter1].Intensity := 32;
Partikel[counter1].Gravity := 0;
END;

Nun, zuerst sorgen wir mit einer FOR/ DO Schleife dafür das alle 200 Partikel auch wirklich initialisiert werden. Die Zählervariable (hier counter1) ist ziemlich egal, sollte halt nur vorhanden sein.

Die X und Y Position der Partikel setzen wir auf 320/ 240 fest. Dies entspricht dem Mittelpunkt eines 640/ 480 Bildschirms. Wer es allgemeiner haben will nimmt MaxX/2 und MaxY/2. Die Vektoren werden mit zufälligen Werten gefüllt. Das ist die Version "Supersimpel" eine Explosion zu erzeugen- man muß nur darauf achten das die Werte nicht 0/ 0 sind (also unbeweglich). Sicher nicht der tollste Algorithmus, aber er taugt zu Lehrzwecken. Intensity ist 32. Status und Gravity werden mit 0815 Werten initialisiert.

Jetzt geht es weiter - jeden Frame sollen die 200 Partikel gezeichnet werden:

FOR counter1 := 1 TO 200 DO BEGIN
Putpixel(vidvscr,
         Partikel[Counter1].PositionX,
		 Partikel[counter1].PositionY,
		 Partikel[counter1].Intensity,10+
trunc(Partikel[counter1].Intensity div 8));
END;

Zugegeben - das BEGIN/ END könnte auch weg gelassen werden, aber wer weiß was man da noch alles darstellen will.. Der nächste Schritt ist die Bewegung und Überprüfung, ob ein Partikel den Rand erreicht hat. In diesem Falle wird es erneuert.

FOR counter1 := 1 TO 200 DO BEGIN

IF (Partikel[counter1].PositionX > 630) OR 
   (Partikel[counter1].PositionX < 10) OR 
   (Partikel[counter1].PositionY > 470) OR 
   (Partikel[counter1].PositionY < 10) THEN 
 BEGIN
  Partikel[counter1].PositionX := 320;
  Partikel[counter1].PositionY := 240;
  Repeat Partikel[counter1].VektorX := random(10)-5 
		until Partikel[counter1].VektorX <> 0;
  Repeat Partikel[counter1].VektorY := random(10)-5 
		until Partikel[counter1].VektorY <> 0;
  Partikel[counter1].Intensity := 32;
 END;

Partikel[counter1].PositionX := 
	Partikel[counter1].PositionX + Partikel[counter1].VektorX;

Partikel[counter1].PositionY := 
	Partikel[counter1].PositionY + Partikel[counter1].VektorY;

IF (Partikel[counter1].Intensity > 2) 
		THEN Partikel[counter1].Intensity -= 1 
		ELSE Partikel[counter1].Intensity := 1;

END;

Also - jedesmal wird bei jedem Pixel geprüft, ob er außerhalb des sichtbaren Bereiches ist (nicht elegant, aber wirksam). Wenn er außerhalb ist wird die Initialisierung wiederholt und der Partikel somit zurückgesetzt. Wenn er noch sichtbar ist wird er einfach nur bewegt und seine Intesität herabgesetzt. Und genau bei dem bewegen kann man nun noch zusätzliche Spielereien einbinden. Man kann die Gravitation beachten und deren Wert als ansteigenden Multiplikator zu der Bewegung addieren.

Ihr seht: ein Partikelsystem ist viel zum spielen. Man kann die Partikel auch nach einer Sinus-Kurve laufen lassen - jeden Partikel vielleicht noch mit einer Abweichung damit es nicht so starr aussieht. Mann kann sie zu Galaxien zusammenfügen. Man kann aus ihnen Buchstaben bilden. Für ein Partikelsystem gibt es schier unendlich Anwendungen, also denkt euch was aus und seid kreativ.

Zum Schluß noch der Source zu unserem Beispiel als eine Datei: hier zum Download. Mit eingebaut ist eine kleine "Debug-Schleife": wenn ihr einen Event erzeugt (Bsp: die Maus bewegt), wird die Animation langsamer und ihr könnt den Farbverlauf deutlicher sehen. Viel Spaß beim spielen!

Delax/ Sundancer Inc.
[delax@sundancerinc.de]

Back to previous page

Useful Links









Link to us