![]() |
viele fliegende sich abstoßende Bälle??
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
ich habe in meinem Info Kurs ein Delphi Programm geschrieben, wobei 2 Bälle erstellt werden, welche in einem gewissen fenster rumfliegen und sich von den enden dieses fensters sowie voneinander selbst abstoßen. Um genauer zu sein wurde eine mutterklasse erstellt namens "tfigure" und nun können davon Bälle oder vierecke oder dreiecke etc. als Tochterklasse abgeleitet werden. Mein Problem ist nun wie ich es schaffe beispielsweise 30 Bälle rumfliegenzulassen, welche sich aber auch alle gegenseitig abstoßen wenn sie sich berühren?? Mein Infolehrer gab mir den tipp es mit einem array zu machen also das die 30 Bälle ein array von 1..30 sind. Und dann eine Schleife einzusetzen die überprüft ob sich die bälle berühren und wenn dies der fall ist auch abstoßen. Nur tapp ich da echt voll im Dunklen?? Hat jemand von euch evtl ma nen Tipp wie ich das mit den 30 Bällen hinbekomme? Im Anhang sollte sich das Delphi Programm befinden! Wäre für alle Hinweise dankbar :-) |
Re: viele fliegende sich abstoßende Bälle??
Hi!
Zunächst mal läuft das Abstoßen der Bälle nicht wirklich korrekt (nur für einen sog. "zentralen Stoß" stimmts) - dazu findest du hier auch min. 2 Threads die vor kurzem zu dem Thema entstanden sind. Zum eigentlichen Problem: Du erstellst ein Array von Bällen, und prüfst in einer Doppelschleife jeden Ball gegen jeden anderen, wobei du darauf achten musst, dass ein Ball nicht gegen sich selbst geprüft werden darf (macht in deinem Programm keinen unterschied, aber kostet Zeit und ist ja schon rein philosophisch fragwürdig ;)). Pseudocode:
Delphi-Quellcode:
Der Trick hier liegt dabei die innere Schleife bei a+1 beginnen zu lassen, damit 2 Bälle nicht doppelt überprüft werden. (Und schneller ists zudem auch :))
for a := 0 to High(BallArray)-2 do
begin for b := a+1 to High(BallArray)-1 do begin wenn sich Ball a und Ball b berühren begin abstoßung; end; end; end; Gruss, Fabian |
Re: viele fliegende sich abstoßende Bälle??
hey,
erstma lieben dank für die schnelle antwort! Nur erlich gesagt versteh ich das mit den 2 schleifen net sooo ganz... :?: Wärs machbar das du mir das kurz in 1-2 sätzen erläuterst? Wär nett!! Ansonsten hätt ich zwar das programm aber wüsst net was ich gemacht hab... ;-) mfg caro |
Re: viele fliegende sich abstoßende Bälle??
Dizzy's Code funkioniert etwa so:
Erst wird der erste Ball mit allen anderen Verglichen und dann der Zweite mit allen, ausser dem ersten, usw. Also sehen die Abfragen dann so aus: // Sechs Bälle 1,2 1,3 1,4 1,5 1,6 2,3 2,4 2,5 2,6 3,4 3,5 3,6 usw. |
Re: viele fliegende sich abstoßende Bälle??
aaaahhhh ok denke habe es nun verstanden!!
schönen dank nochmal!! :-) |
Re: viele fliegende sich abstoßende Bälle??
hallo nochmal,
leider gottes bekomm ich das programm irgendwie nicht zum laufen...*heul* wäre es viel arbeit mein onlinegestelltes programm umzuschreiben und an mich zu senden?? Naj,a also wer die Zeit und die Lust hat kann dies gern tun ;-) Also weitergehts...das prinzip hab ich (denke ich jedenfalls...) verstanden nur beim Umsetzen haperts noch! ich hab da probleme mit dem "a" und "b"....ich mein ich erstell also ein array
Code:
doch was stell ich mitm a und b nun an...?
procedure stoss ;
var ball: array [1..30] of tball ; for a := 0 to High(BallArray)-2 do begin for b := a+1 to High(BallArray)-1 do begin wenn sich Ball a und Ball b berühren begin abstoßung; end; end; end; Sorry, bin noch echt ne blutige Angängerin :pale: |
Re: viele fliegende sich abstoßende Bälle??
Fertigschreiben??? Da wirst du sicher niemand finden. Dein Problem liegt bei dir bei deiner hardgecodeten Procedure 'Stoss';
Delphi-Quellcode:
procedure stoss ;
begin if sqrt ( sqr(ball1.getx-ball2.getx)+sqr(ball1.gety-ball2.gety)) <= (ball1.r+ball2.r) then begin tausche (ball1.vx,ball2.vx); tausche (ball1.vy,ball2.vy); end; end;
Delphi-Quellcode:
Das var ist wichtig, sonst darf deine procedure keine Werte von b1 oder b2 schreiben, sondern nur lesen.
// Mach mal was in diese Richtung;
procedure stoss(var b1,b2: TBall) ; begin if sqrt ( sqr(b1.getx-b2.getx usw. ... end; Mit deiner Procedure kannst du nur Ball1 und 2 vergleichen und du zwingst die Programmierer, die auch noch deine Klasse nutzen wollen, immer ihre Bälle so wie du zu benennen. Das ist sehr schlechter Stil. [edit=Christian Seehase]Delphi-Tags korrigiert. Mfg, Christian Seehase[/edit] |
Re: viele fliegende sich abstoßende Bälle??
Ich würde es so machen:
Delphi-Quellcode:
procedure stoss;
var ball: array [1..30] of tball; for a := 0 to High(BallArray)-2 do begin for b := a+1 to High(BallArray)-1 do begin if ball[a].Left+ball[a].Width=ball[b].Left then // Wenn es in tball Left, Top, Width und Height gibt... begin //(...X-Abstoßung...) end; if ball[a].Top+ball[a].Height=ball[b].Top then // Wenn es in tball Left, Top, Width und Height gibt... begin //(...Y-Abstoßung...) end end; end; Florian K. |
Re: viele fliegende sich abstoßende Bälle??
Zitat:
1) So wie das Array deklariert ist gibts dirket eine Zugriffsverletzung, da ich von einem null-basierten Array ausging (array[0..max] oder dynamisch). 2) Die Klasse TBall, so wie sie implemietert ist, hat kein "left" oder "top". Du gehst von TShapes aus, und das ist a) saumäßiger Stil, und b) unhandlich. Wie im Programm ist es am besten gelöst: Mittelpunkt und Radius beschreiben einen Ball. Die reine Technik mit der die Kollision überprüft wird ist okay, nur muss die Prozedur wie Toxman es schrieb universeller gemacht werden, so dass sie beliebige Instanzen von TBall entgegen nehmen kann. Und das hat Toxman ja schon erledigt ;) Grundsätzlich @Carolin: Die Formatierung deines Codes ist gelinde gesagt grausam. Macht das euer Lehrer auch so!? |
Re: viele fliegende sich abstoßende Bälle??
Liste der Anhänge anzeigen (Anzahl: 1)
Hi
Wir haben sowas auch in der Schule gemacht. Daher kann ich Dir hiermit mein Programm an die Hand geben. Zumindest hilft es Dir bestimmt in eineigen Punkten, da ich es genauso gemacht habe wie hier vorgeschlagen. Einzig die Berechnung der Winkel zweier Bälle nach dem Zusammenstoß ist nicht schön gelöst - es werden einfach beide Winkel ausgetauscht, was in den meißten Fällen richtig aussieht (ich wäre übrigens sehr dankbar, wenn mir dabei jemand einen Tipp geben könnte, unsere Kurs-Spitze hat sich lange damit beschäftigt, es aber letzten Endes sein lassen) Zurück zum Programm: Ich habe eine Klasse TBall geschrieben, die Funktionen und Prozeduren zum darstellen eines einzelnen Balls enthält. Dem übergeordnet eine Klasse TBaelle, die dann einen Array of TBall enthält und diese Bälle steuert. Die Kollisionsabfrage erfolgt also in der Klasse TBaelle und zwar so:
Delphi-Quellcode:
(Ich habe die Proc ein wenig verändert, ich hoffe sie stimmt noch)
procedure TBaelle.MoveBalls;
var dist,rrad:real; i,j:integer; Ball1,Ball2:TBall; begin if not (High(Ball)<0) then begin for i := 0 to High(Ball) do if Ball[i] <> nil then Ball[i].Bewegen; for i := 0 to High(Ball) do begin // jeder Ball wird mit jedem verglichen Ball1:=Ball[i]; for j := i to High(Ball) do begin Ball2:=Ball[j]; if Ball1 <> Ball2 then begin dist := sqrt(sqr(Ball1.GetX-Ball2.GetX)+sqr(Ball1.GetY-Ball2.GetY)); // Abstand der Bälle nach Pythagoras if (dist <= Ball1.GetRadius+Ball2.GetRadius) then begin rrad:=Ball1.GetAngle; // Winkel werden bei Kollision vertauscht Ball1.SetAngle(Ball2.GetAngle); Ball2.SetAngle(rrad); end; end; end; end; end; end; Außerdem wollte Dir noch den Tipp geben dass - damit gewährleistet ist dass die Bälle immer eine Gleichmäßige Geschwindigkeite haben - es mit Winkeln arbeitet und nicht mit x- und y-Geschwindigkeiten. Den x-Wert der Steigung bei einem Winkel alpha bekommst Du dann mit
Delphi-Quellcode:
und den y-Wert mit
cos( DegToRad(angle-90) ) * speed
Delphi-Quellcode:
Siehe hierzu die Funktionen NextX und NextY in der Klasse TBall.
sin( DegToRad(angle-90) ) * speed
Naja, Du musst natürlich Dein eigenes Programm schreiben, aber vielleicht hast Du ja Lust in den Source mal reinzuschauen. Viel Erfolg und Grüße, Christoph edit: Sorry, da haben wohl Toxman, FlorianK und dizzy gepostet während ich noch geschrieben habn :? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz