Entwickler-Ecke
Multimedia / Grafik - OpenGL Ballkollision bei Pong
ACiDRAiN - Mo 26.03.12 17:29
Titel: OpenGL Ballkollision bei Pong
Guten Tag liebe Community,
ich bräuchte eure Hilfe bei meinem Ballkollisionsproblem.
Ich hab viele Theorien aufgestellt, wie ich den Verlauf des Balles in x/y-Richtung (abhängig vom Gegenstand, auf den der Ball aufprallt) umkehren kann.
bx und by sind bei diesem Beispiel auch die jeweiligen Koordinaten des Balles, an denen er sich zum genauen Zeitpunkt befindet.
Ich denke auch, dass es bei mir eher ein mathematisches Problem ist, als ein Problem mit Delphi/OpenGL.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| procedure TForm1.Ball; var k1,k2,bx,by: extended; begin
if (by<=20) and (by>=-12) and (bx>=-30.5) and (bx<=30.5) then begin by:=by+0.005; k1:=bx-0.005; k2:=by-0.005; bx:=bx+0.005; end else if by>=20 then begin by:=k2; end;
if by>=20 then by:=k2;
glPushMatrix(); glTranslatef(0, 0, -50); glTranslated(bx, by, 0); glBegin(GL_QUADS); glColor3f(0, 1, 0); glVertex3f(-1,1,-1); glColor3f(0, 1, 0); glVertex3f(-1,-1,-1); glColor3f(0, 1, 0); glVertex3f(1,-1,-1); glColor3f(0, 1, 0); glVertex3f(1,1,-1); glEnd; glPopMatrix(); end; |
Ich hoffe, dass mein Code für euch verständlich ist.
Kleine Anmerkung: wenn by=20 ist, dann trifft der Ball die obere Bande, die untere trifft er bei by=-12.
bx=30.5 ist das Auftreffen beim rechten Schläger und bx=-30.5 das Auftreffen beim Linken.
EDIT: Da bx und by unbekannt sind, muss ich auf die jeweils kommen um immer 0.005 davon subtrahieren zu können und somit die Richtung umkehren kann. Da kommt wohl Mathematik infrage, die ich nicht sehr gut beherrsche.
Vielen Dank für eure Hilfe.
MfG,
acidrain
Bergmann89 - Mo 26.03.12 20:15
Hey,
ich blick zwar bei deinem Code nicht 100%tig durch, aber an der Theorie ändert sich ja nix. Hier mal der Ablauf, den du programmieren willst/musst:
Der Ball hat eine bestimmte Position P(x,y) und einen Vektor V(x,y) in dessen Richtung er sich bewegt. Die Länge des Vektors defniert die Geschwindigkeit des Balls. Bei jedem neuen Frame musst du nun die neue Position des Balls berechnen und ggf. Prüfen ob er mit irgendeinem Objekt kollidiert ist. Die neue Position des Balls ist P2(x,y) = P(x,y) + V(x,y). (Wenn du das Ganze noch von der Zeit zwischen den Frames abhängig machen willst, musst du den Vektor noch mit der vergangenen Zeit multiplizieren: P2(x,y) = P(x,y) + V(x,y) * deltaTime). Jetzt guckst du, ob zwischen P und P2 ein Objekt liegt, an dem der Ball hätte abprallen müssen. Mal angenommen da war jetzt ne Wand, dann berechnest du den Schnittpunkt S der Geraden durch P und P2 mit der Wand. Anhand der Länge des Vektors P->S (nenn ich mal d1) erkennst du, wie weit sich der Ball in diesem Schritt bewegt hat, bis er abgeprallt ist. Bis dahin muss er sich also noch mit seinem alten Bewegungsvektor bewegen. Nun berechnest du den Vektor den der Ball nach dem abprallen an der Wand hat (da findet man genug bei Wikipedia & Co. und für Wände parallel zur x- bzw. y-Achse drehst du einfach das Vorzeichen um). Wenn der neue Richtungsvektor V2 berechnet ist, muss sich der Ball noch den Rest des Schrittes weiterbewegen, den er eigentlich in der Wand gemacht hätte. Der Abstand den er zurücklegen muss ist d2 = Länge von V - d1. Also muss sich der Ball um d2 Einheiten von S in Richtung des neuen Vektors V2 bewegen: P3 = S + V2 * d2. P3 ist dann der Punkt den der Ball nach der Kollision hat.
Warum ich das so kompliziert mache? Weil du so erstens eine realistische Kollision hast und 2. verhinderst du, das dein Ball durch die Wand durchschlägt. Ich hab auch mal n Pong geschrieben und das nur mit paar if-Abfragen gemacht un bei mir is der Ball bei einer bestimmten Geschwindigkeit immer durch die Wand durchgewandert^^ Klingt am Anfang bisl kompliziert, is aber eigentlich ganz einfach. Hier noch ne Skizze, damit man das Ganze besser versteht:
€: noch 2 kleine Tipps am Rande:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| glTranslatef(0, 0, -50); glTranslated(bx, by, 0); glTranslatef(bx, by, -50); |
- glColor muss man nur einmal setzen, das bleibt solange rot, bis du eine andere Farbe festlegst
- für Anwendungen die nur zweidimensional arbeiten sollte man auch lieber zweidimensional zeichnen. Stichwort glOrtho [http://wiki.delphigl.com/index.php/glOrtho]
MfG Bergmann.
Xion - Mo 26.03.12 20:31
Dein Code ist etwas seltsam, z.B. benutzt du lokale Variblen um die Position des Balls zu speichern...das funktioniert so aber nicht.
Probiers mal so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| type TVector=record x: real; y: real; end;
var BPos: TVector; BDir: TVector; |
In BPos speicherst du die Position des Balles.
In BDir speicherst du die Geschwindigkeit des Balles.
Also ist klar, trifft der Ball an den rechten Schläger, dann setzt du einfach
Die Bewegung des Balles machst du dann so:
Delphi-Quelltext
1: 2:
| BPos.X := BPos.X + BDir.X*t; BPos.Y := BPos.Y + BDir.Y*t; |
Du kannst t=1 setzen erstmal, aber du wirst dann merken, dass das Programm unterschiedlich schnell ist auf verschiedenen Computern (Stichwort Timebased Movement).
Bleibt dir Frage der Kollision. Etwas Mathe:
Angenommen bei y=20 ist die untere Begrenzung, also gibts eine Kollision, wenn
y=20=BPos.Y+BDir.Y*a;
=> a=(20-BPos.Y)/BDir.Y;
Nach Zeit a trifft der Ball also auf diese Bande. Ist a>
t, dann gibts diese Runde keine Kollision mit dieser Bande (evtl aber mit einer anderen).
Ist a<t, dann gibt es die Kollision.
Ich hab im Folgenden Stück mal die Kollision mit einer Bande gezeigt, das sollte für deine Zwecke reichen. Im Code ist aber nur die Kollision mit der unteren Bande gezeigt, die restlichen musst du selbst erledigen. Was auch fehlt ist die Berücksichtigung der dicke der Schläger und des Balls. Das wirkt sich alles jeweils auf die Berechnung von HitTime aus und ist mit dem Codegerüst machbar.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| procedure TForm1.Ball(t: real); var HitTime: real; begin if BDir.Y<>0 then HitTime:=(20-BPos.Y)/BDir.Y else HitTime:=-1; if HitTime<t then begin BDir.Y:=-BDir.Y; BPos.Y:=BPos.Y+HitTime*BDir.Y; BPos.X:=BPos.X+HitTime*BDir.X; Ball(t-HitTime); end else begin BPos.Y:=BPos.Y+t*BDir.Y; BPos.X:=BPos.X+t*BDir.X; end;
end; |
ACiDRAiN - Mo 26.03.12 21:01
Vielen Dank für deine Hilfe, Xion.
Bei mir wird jetzt ein Problem ausgespuckt. Und zwar meint Delphi bei der Zeile (Ball(t-HitTime);) dass es zuviele Parameter gibt.
Xion - Mo 26.03.12 21:20
Xion hat folgendes geschrieben : |
Delphi-Quelltext 1:
| procedure TForm1.Ball(t: real); | |
PS: hab eben noch einen Fehler ausgebessert.
ACiDRAiN - Mo 26.03.12 21:36
Hatte es selber gemerkt, danke.
Ich habe mir das so angeschaut und mit einem Wert von 0.05 ist der ball annehmbar von der Geschwindigkeit und es kommen keine Fehlermeldungen, wie bei dem Wert von 1.
Nun wollte ich noch letztendlich um eine Denkanregung für die andere bande bzw. schläger alles zu ende zu programmieren.
Als ich das für die untere bande geändert habe, dann flog der ball direkt nach unten, ohne einen winkel einzugehen, vor dem programmieren war's genauso, nur dass der halt nach oben ging. Muss ich da noch mit welchen winkeln spielen/diese zufällig machen? Wieso prallt der Ball nicht von der Bande ab, obwohl er diese erreicht? Auf welche Variablen muss ich achten, beim Konfigurieren für die restlichen Kollisionen?
Mit freundlichem Gruß,
acidrain
Xion - Mo 26.03.12 22:14
ACiDRAiN hat folgendes geschrieben : |
Ich habe mir das so angeschaut und mit einem Wert von 0.05 ist der ball annehmbar von der Geschwindigkeit und es kommen keine Fehlermeldungen, wie bei dem Wert von 1. |
Du musst natürlich BPos (Position des Balls) und BDir (Geschwindigkeit des Balls) am Anfang setzen :!: . BDir wäre z.B. die Geschwindigkeit pro Sekunde und t die vergangene Zeit in Sekunden.
ACiDRAiN hat folgendes geschrieben : |
Nun wollte ich noch letztendlich um eine Denkanregung für die andere bande bzw. schläger alles zu ende zu programmieren.
Als ich das für die untere bande geändert habe, dann flog der ball direkt nach unten, ohne einen winkel einzugehen, vor dem programmieren war's genauso, nur dass der halt nach oben ging. |
Kannst du mal deinen Code dazu zeigen?
ACiDRAiN hat folgendes geschrieben : |
Muss ich da noch mit welchen winkeln spielen/diese zufällig machen? |
Nein, es gibt hier keine Winkel (nur -x, -y) und nichts zufälliges ;)
Bei Y=20 gibts die Kollision. Wenn du also auch bei der oberen Wand eine Kollision machen willst, dann nimmst du einfach bei Y=-20
Delphi-Quelltext
1:
| b:=(-20-BPos.Y)/BDir.Y |
Das heißt nach Zeit a triffst du die eine und nach Zeit b die andere Bande.
Die kleinste der Zeiten macht also die Kollision (solange sie nicht negativ ist, also der
kleinste positive dieser Werte). Je nachdem welche Zeit eben die kleinste ist, musst du nun den Geschwindigkeitsvektor verändern.
ACiDRAiN - Mo 26.03.12 22:24
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| procedure TForm1.Ball(t: real); var Kollision: real; begin
if BDir.Y<>0 then Kollision:=(20-BPos.Y)/BDir.Y else BDir.Y:=-t;
if BallRi.Y<>0 then Kollision:=(-20-BallPos.Y)/BallRi.Y else BallRi.Y:=-t;
if Kollision<t then begin BDir.Y:=-BDir.Y; BPos.Y:=BPos.Y+Kollision*BDir.Y; BPos.X:=BPos.X+Kollision*BDir.X; t:=t-Kollision; Ballbewegung(t-Kollision); end else begin BPos.Y:=BPos.Y+t*BDir.Y; BPos.X:=BPos.X+t*BDir.X; end; end; |
Hierbei bewegt sich der Ball dann automatisch nach unten und egal, ob mit oder ohne die neue Kollision, der Ball bleibt an der Wand stehen und macht garnichts mehr.
Vielen Dank im Vorraus,
acidrain
Blup - Di 27.03.12 17:41
Quelltext
1: 2: 3: 4:
| t = die seit der letzten Berechnung vergangene Zeit Kollision = die Zeit, nach der eine Kollision eingetreten ist oder eintreten würde BDir = der aktuelle Geschwindigkeitsvektor (x, y) des Balls BPos = die aktuelle Position (x, y) des Balls |
Welche Bedeutung haben diese Variablen?
BallRi = ?
BallPos = ?
Wenn die Geschwindigkeit in Richtung y = 0 ist, gibt es keine Kollision.
Warum weist du in diesem Falls der Ballgeschwindigkeit die vergangene Zeit zu?
Vereinfacht nur für die Kollision mit der unteren Bande:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| procedure TForm1.Ball(t: real); var Kollision: real; begin if BDir.Y > 0 then Kollision := (20 - BPos.Y) / BDir.Y else Kollision := t;
if Kollision < t then begin BPos.Y := BPos.Y + Kollision * BDir.Y; BPos.X := BPos.X + Kollision * BDir.X;
BDir.Y := -BDir.Y; t := t - Kollision; end;
BPos.Y := BPos.Y + t * BDir.Y; BPos.X := BPos.X + t * BDir.X; end; |
ACiDRAiN - Di 27.03.12 20:01
Ich hab einfach BPos und BDir umbenannt für's Verständnis.
Komischerweise funktioniert das Programm nicht, wenn ich deine Vereinfachung anwende :/
Ich bin für jede mögliche Hilfe dankbar!
EDIT: hab das auch mal für andere Kollisionen umgesetzt um euch um kontrolle zu bitten :)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| if BallRi.Y < -20 then Kollision := (-20 - BallPos.Y) / BallRi.Y else Kollision := t;
if (BallRi.Y > s1) and (BallRi.x > 30.5) then Kollision := (30.5 - BallPos.y) / BallRi.Y else Kollision := t;
if (BallRi.Y < s2) and (BallRi.x < -30.5) then Kollision := (-30.5 - BallPos.y) / BallRi.Y else Kollision := t; |
s1 und s2 sind die koordinaten der schläger, die sich ja durch den tastendruck ändern.
Vielen Dank im Vorraus!
acidrain
Xion - Di 27.03.12 22:03
Diese Zeile muss weg, die hatte ich in meinem Code fälschlicherweise drin.
ACiDRAiN hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4:
| if BallRi.Y < -20 then Kollision := (-20 - BallPos.Y) / BallRi.Y else Kollision := t; | |
Müsste hier nicht > stehen? Dann hast du aber ein Problem, da dies nicht =0 abfängt. Im Wesentlichen brauchst du hier auch nichts groß berücksichtigen, mit if solltest du nur Abfangen, ob die Geschwindigkeit=0 ist (weil sonst gibts einen Fehler). Also
if BallRi.Y<>0 then
Bei den Schlägern wäre eigentlich das Auftreffen durch x-Geschwindigkeit sinnvoller, oder? Also
Delphi-Quelltext
1: 2: 3: 4:
| if (BallRi.X <> 0) then Kollision := (s1 - BallPos.X) / BallRi.X else Kollision := t; |
ACiDRAiN - Di 27.03.12 22:29
Danke, Xion du bringst mich echt weiter!
Hier nochmal alles:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| if (BallRi.y <> 0) then Kollision := (20 - BallPos.Y) / BallRi.Y else Kollision := t;
if (BallRi.Y <> 0) then Kollision := (-20 - BallPos.Y) / BallRi.Y else Kollision := t;
if (BallRi.X <> 0) then Kollision := (s1 - BallPos.X) / BallRi.X else Kollision := t;
if (BallRi.X <> 0) then Kollision := (s2 - BallPos.X) / BallRi.X else Kollision := t;
if Kollision < t then begin BallPos.Y := BallPos.Y + Kollision * BallRi.Y; BallPos.X := BallPos.X + Kollision * BallRi.X;
BallRi.Y := -BallRi.Y; end;
BallPos.Y := BallPos.Y + t * BallRi.Y; BallPos.X := BallPos.X + t * BallRi.X; end; |
Alles, so wie beschrieben. Der Ball will sich aber nicht bewegen :/
Es kommt eine Art Fehlermeldung: Auf 'Kollision' zugewiesener Wert wird niemals benutzt.
Hast du eine Idee wodran das liegen kann?
Grüße,
Acidrain
Xion - Mi 28.03.12 11:20
Ah, ok, da fallen mir noch 3 Sachen auf:
:arrow: Du berechnest die Kollision soweit ok imho. Das Problem ist, dass du den Kollisionswert jedesmal überschreibst. Das letzte if verändert IMMER den Kollisionswert, also ist alles was du vorher berechnet hast, eigentlich hinfällig ;)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
| Kollision:=1+t; if (BallRi.y <> 0) then begin Temp := (20 - BallPos.Y) / BallRi.Y; if (Temp>=0)and (Temp<Kollision) then Kollision:=Temp; end; if (BallRi.Y <> 0) then begin Temp := (-20 - BallPos.Y) / BallRi.Y; if (Temp>=0)and (Temp<Kollision) then Kollision:=Temp; end;
if (BallRi.X <> 0) then begin Temp:= (s1 - BallPos.X) / BallRi.X; if (Temp>=0)and (Temp<Kollision) then Kollision:=Temp; end; if (BallRi.X <> 0) then begin Temp:= (s2 - BallPos.X) / BallRi.X; if (Temp>=0)and (Temp<Kollision) then Kollision:=Temp; end;
if Kollision<t then ... |
:arrow: Du musst dir irgendwo merken, wie die Kollision stattfinden muss. Momentan prallt der Ball immer in Y-Richtung ab, aber das ist natürlich bei dem Schläger falsch.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| if (BallRi.X <> 0) then begin Temp:= (s2 - BallPos.X) / BallRi.X; if (Temp>=0)and (Temp<Kollision) then begin Kollision:=Temp; KollisionDir:=1; end; end; if Kollision < t then begin BallPos.Y := BallPos.Y + Kollision * BallRi.Y; BallPos.X := BallPos.X + Kollision * BallRi.X;
if KollisionDir=0 then BallRi.Y := -BallRi.Y else if KollisionDir=1 then BallRi.X := -BallRi.X end; |
:arrow: Erstmal nicht so wichtig: Bei der Kollision mit dem Schläger musst du die Y-Koordinate vorher abfragen, weil momentan ist der Schläger unendlich groß und man kann nicht verlieren ;)
Blup - Mi 28.03.12 11:21
Das ist keine Fehlermeldung sondern ein freundlicher Hinweis des Kompilers.
Deine Berechnungen in Zeile 1..4 sind überflüssig, da du das Ergebnis nicht auswertest, sondern in Zeile 7 oder 9 auf jeden Fall überschreibst. Das wiederholt sich dann auch noch...
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59:
| procedure TForm1.Ball(t: real); type TKollisonObjekt = (oKeine, oLinks, oRechts, oOben, oUnten, oS1, oS2); var Kollision: record Objekt: TKollisonObjekt; Zeit: real; end; t2: real; begin Kollision.Objekt := oKeine; Kollision.Zeit := t;
if BallRi.y < 0 then begin t2 := (20 - BallPos.Y) / BallRi.Y; if t2 < Kollision.Zeit then begin Kollision.Objekt := oUnten; Kollision.Zeit := t2; end; end;
if BallRi.y > 0 then begin t2 := (-20 - BallPos.Y) / BallRi.Y; if t2 < Kollision.Zeit then begin Kollision.Objekt := oOben; Kollision.Zeit := t2; end; end;
BallPos.Y := BallPos.Y + Kollision.Zeit * BallRi.Y; BallPos.X := BallPos.X + Kollision.Zeit * BallRi.X;
if Kollision.Objekt <> oKeine then begin case Kollision.Objekt of oUnten, oOben: BallRi.Y := -BallRi.Y; oLinks, oRechts: BallRi.X := -BallRi.X;
end; Ball(t - Kollision.Zeit); end; end; |
ACiDRAiN - Mi 28.03.12 17:08
Xion, was sind denn KollisionDir und Temp für Variablen?
Wie würde das letztendlich aussehen, denn ich komm mit dem ganzen Zeug irgendwie nicht ganz zurecht. Ich kann sowas eher nachvollziehen, wenn es vollständig ist.
Würde mich freuen, wenn du mir dabei helfen könntest.
Blup, wäre das dann vollständig? Ich hab's nämlich genauso versucht, doch es klappt ebenfalls nicht, es kommt eine Fehlermeldung bei der Rekursion, die sagt, dass es zu viele Parameter gibt.
Grüße,
acidrain
Blup - Mi 28.03.12 17:46
ACiDRAiN hat folgendes geschrieben : |
Blup, wäre das dann vollständig? Ich hab's nämlich genauso versucht, doch es klappt ebenfalls nicht, es kommen Meldungen, wie Kollision sei ein Undefinierter Bezeichner. |
Ich habe den kleinen Rechtschreibfehler bei "Kollision" korrigiert.
Der Quelltext lässt sich jetzt so wie er ist kompilieren.
Das hätte dich aber nicht davon abhalten sollen den Programmablauf zu verstehen.
Unten und Oben sollte der Ball schon richtig abprallen.
Die Stellen die du für die Kollision mit weiteren Objekten ergänzen musst sind mit {...} kommentiert.
Ich werde dir sicher kein vollständiges Programm schreiben.
ACiDRAiN - Mi 28.03.12 18:23
EDIT:
Also, Xion. Ich glaub ich hatte ein paar Fehler gefunden, oder bei mir ist was mit OpenGL falsch, denn egal was ich einstelle der Ball geht durch die Bande.
Hier mein Ball:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TForm1.Ball; begin glPushMatrix(); glTranslatef(BallPos.x, BallPos.y, -50); glTranslated(BallRi.x, BallRi.y, 0); glBegin(GL_QUADS); glColor3f(0, 1, 0); glVertex3f(-1,1,-1); glColor3f(0, 1, 0); glVertex3f(-1,-1,-1); glColor3f(0, 1, 0); glVertex3f(1,-1,-1); glColor3f(0, 1, 0); glVertex3f(1,1,-1); glEnd; glPopMatrix(); end; |
Entweder ich hab da was falsch, oder ich muss deinen Vorschlag gemäß meinen Bedingungen ändern. Ich sitze auch schon wieder vier Stunden dran, um das hinzukriegen und hab, wie gestern, keinen Fortschritt gemacht.
EDIT2: Ich hab's selbst hingekriegt!!! Ich kann's einfach nicht glauben, dass jemand so inkompetentes, wie ich, endlich mal was in Delphi auf die Reihe kriegt.
Jetzt kommen die Kollisionen der Schläger. Hiermit bedanke ich mich herzlichst für EURE Unterstützung, denn ohne EUCH wäre ich nie so weit gekommen!
Grüße,
acidrain
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!