Entwickler-Ecke

Multimedia / Grafik - Kollision mit Unbekannt


Delete - Sa 27.05.17 10:13
Titel: Kollision mit Unbekannt
- Nachträglich durch die Entwickler-Ecke gelöscht -


Jann1k - Sa 27.05.17 16:08

Du kannst in einer Schleife deinen Kollisionstest für alle möglichen TImages ausführen.


Delete - Sa 27.05.17 16:24

- Nachträglich durch die Entwickler-Ecke gelöscht -


Jann1k - Sa 27.05.17 16:34

Was genau meinst du mit

Delphi-Quelltext
1:
2:
3:
4:
1 --> 5
2 --> 5
3 --> 5
4 <-> 5


Vom Prinzip her ist deine Schleife richtig. Da du die caption aber bei jeder Kollisionerkennung überschreibst, siehst du am Ende natürlich nur das Ergebnis mit dem letzten Timage.


Delete - Sa 27.05.17 16:40

- Nachträglich durch die Entwickler-Ecke gelöscht -


Jann1k - Sa 27.05.17 16:48

Okay, jetzt wäre natürlich dein genauer Code hilfreich. Wenn du so etwas machst, sollte es klappen.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function KollTest;
var i, j : integer;
begin
  result := false;
  with Form1 do
  begin
    for i := 0 to 3 do
      for j := i+1 to 4 do
        if Kollision(imgArray[i], imgArray[j]) then
        result := true;  
  end;
end;


Die Funktion prüft, ob irgendwas mit irgendwas anderem kollidiert und gibt entsprechend true/false zurück.


Delete - Sa 27.05.17 17:10

- Nachträglich durch die Entwickler-Ecke gelöscht -


FinnO - Sa 27.05.17 17:25

Moin,

auch wenn es bei höchstens fünf Iterationen keine wirkliche Rolle spielt: Bei der Implementierung einer solchen any-Überprüfung ist es idiomatischer, wenn man nach dem ersten positiven Test die Iteration abbricht.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
function KollTest: Boolean;
var
  i: Byte;
begin
  result := false;
  with Form1 do
  begin
    for i := Low(imgArray) to High(imgArray) do
      if imgArray[i] <> img then
        if Kollision(img, imgArray[i]) then 
        begin
          result := true;
          break;
        end;
  end;
end;


Weiterhin sollte man die Grenzen der Iteration natürlich auch nicht hardcodieren, da sich so sehr leicht recht unnötige Fehler einschleichen können ;-)

Viele Grüße


Delete - Sa 27.05.17 17:59

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delete - Mo 29.05.17 21:48

- Nachträglich durch die Entwickler-Ecke gelöscht -


Bergmann89 - Mo 29.05.17 22:08

Hey,

da musst du dann ein bischen tiefer in die Trickkiste greifen. Kurzer Abriss wie ich es machen würde:

Quelltext
1:
2:
3:
4:
5:
6:
- TImages als Kugeln betrachten (mit Mittelpunkt und Radius)
- Kollision zwischen den 2 Kugeln erkennen (geht bei Kugeln auch viel einfacher als bei Rects)
- Vektor zwischen den 2 Kugeln bestimmen
- eine der beiden Kugeln so lange in Richtung des Vectors verschieben, bis sie nicht mehr kollidieren
  - Anmerkung: letzten Punkt könnte man auch ausrechnen
        - neuer Punkt von Kugel 1 = Punkt Kugel 2 + Normierter Vektor * (Radius Kugel 1 + Raduis Kugel 2)


Zum Test kannst du das ja mit den TImages weiter machen, aber für deinen produktiv Code würde ich mir eine entsprechene Klasse schreiben, die alle benötigten Eigenschaften deiner Kugeln kapselt (Mittelpunkt und Radius) und dann mit dieser Klassen die Kollisionsberechnung machen. Zum Zeichen kannt du der Klasse ja noch eine Render oder Paint Methode geben, die dann das TImage an die richtige Stelle schiebt. Auf alle Fälle sollte man sowas nicht über die TImages direkt machen.

MfG Bergmann.


Delete - Mo 29.05.17 22:39

- Nachträglich durch die Entwickler-Ecke gelöscht -


cryptnex - Di 30.05.17 15:16

Zitat:
Wie man sieht, wird manchmal eine Kollision erkannt, obwohl keine (optisch) gegeben ist.
Liegt das nun an der Routine oder an der Komponente TImage per se?

Du vergleichst jeweils die linkere obere Koordinate der beiden rechteckigen TImages miteinander. Du möchtest aber die Abstände der Mittelpunkte vergleichen. ;-)


Delete - Di 30.05.17 19:27

- Nachträglich durch die Entwickler-Ecke gelöscht -


cryptnex - Di 30.05.17 20:30

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Richtig, die Mittelpunkt-Abstände interessiere mich, und die rechne ich mitn "Pythagoras" aus, siehe Methode KollisionKreis()!

Stimmt.

Quelltext
1:
2:
Delta x = (L1 + B1/2) - (L2 + B2/2) 
Delta y = (T1 - H1/2) - (T2 - H2/2)

Wobei L für Left, T für Top und B für Breite und H für Höhe steht. Sind denn Breiten und Höhen von allen Images identisch? Falls ja, fällt das tatsächlich aus den Differenzen raus und ich bin selbst erstmal einmal ideenlos.


Delete - Di 30.05.17 21:23

- Nachträglich durch die Entwickler-Ecke gelöscht -


Bergmann89 - Mi 31.05.17 11:25

Hey,

in deiner Methode AllleMove verschiebst du die TImage, machst den KollisionsTest und wenn eine Kollision erkannt wurde schiebst du die Image an ihren alten Platz zurück. Wenn das Delta zwischen neuer und alter Maus Position jetzt sehr groß ist, dann siehst du da den Spalt zwischen deinen Kugeln. Guck dir nochma den Pseudo-Code von oben an. Wenn die Kollision erkantn wurde soll die Image nicht auf ihren alten Platz zurück gesetzt werden, sondern es soll die Position ausgerechnet werden, wo beide Kugeln direkt nebeneinander liegen.

user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:

Quelltext
1:
2:
3:
4:
5:
6:
- TImages als Kugeln betrachten (mit Mittelpunkt und Radius)
- Kollision zwischen den 2 Kugeln erkennen (geht bei Kugeln auch viel einfacher als bei Rects)
- Vektor zwischen den 2 Kugeln bestimmen
- eine der beiden Kugeln so lange in Richtung des Vectors verschieben, bis sie nicht mehr kollidieren
    - Anmerkung: letzten Punkt könnte man auch ausrechnen
        - neuer Punkt von Kugel 1 = Punkt Kugel 2 + Normierter Vektor * (Radius Kugel 1 + Raduis Kugel 2)


€: nochmal die Anmerkung: schreib dir Klassen dafür. Da must du nich so viel mit deinem Left/Top/Width/Height rum rechnen, der Code wird übersichtlicher und vorallem sparst du Rechenzeit! Jedesmal wenn du die Position deiner TImage änderst muss die Form neu gerendert werden :/

MfG Bergmann


FinnO - Mi 31.05.17 21:16

Moin,

ich war mal so frei, dir in JavaScript was zusammenzuschreiben [https://jsfiddle.net/86rt36ds/1/]. Vielleicht hilft's ja als Inspiration.

Gruß
Finn


Delete - Mi 31.05.17 23:32

- Nachträglich durch die Entwickler-Ecke gelöscht -