Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi "Kollidieren" von drei Objekten verhindern (https://www.delphipraxis.net/199125-kollidieren-von-drei-objekten-verhindern.html)

Luis 26. Dez 2018 15:40

Delphi-Version: 5

"Kollidieren" von drei Objekten verhindern
 
Hallo ihr Lieben,

ich "muss" im Rahmen eines Schulprojektes ein kleines Spiel in Delphi programmieren und stoße dort an eine Hürde. Habe viele Möglichkeiten probiert ohne jeglichen Erfolg, weswegen ich nun anderweitig Hilfe benötige.
Im groben soll ein Spieler Kisten zu ihrem vorgegebenen Platz schieben. Mit zwei Kisten konnte ich auch noch ausdrücken, dass diese nie ineinander "verschmelzen" (also die gleichen Koordinaten haben), bei dreien scheitere ich daran. Ich werde einmal meinen letzten Lösungsversuch euch mitteilen:
Delphi-Quellcode:
 if player.top = k1.Top then
 if player.Left =k1.left then
 begin
 if k1.Top-50 =k2.Top then
 if k1.Left = k2.Left then
 k1.Top:=k1.Top
 else
 if k1.Top-50 =k3.Top then
 if k1.Left = k3.Left then
 k1.top:=k1.Top
 else
  k1.Top:=k1.Top-50;
  end;
Hier geht es um die Bewegung nach oben von der Kiste 1, also k1.


Und einmal meine "richtige" Lösung von dem Problem bei zwei Kisten:

Delphi-Quellcode:
 if player.top = k1.Top then
 if player.left = k1.left then
 if k1.Top-50 <> k2.Top then
 k1.Top:= k1.top-50
 else
 if k1.left <> k2.left then
 k1.Top:= k1.top-50
 else
 k1.Top:=k1.Top;
Danke schon einmal für eure Hilfe!

stahli 26. Dez 2018 16:53

AW: "Kollidieren" von drei Objekten verhindern
 
Hi,

nur mal so als grundlegenden Ansatz:

So ist die Vergleichsfunktion in eine Funktion verpackt, die man dann immer wieder verwenden kann.

Später werden alle Objekte miteinander geprüft oder ein spezielles gegen alle anderen.

Der Code ist natürlich nur symbolisch.
Aber hilft Dir das etwas weiter?

Delphi-Quellcode:
function IntersectObject(O1, O2: TObjectIregendwas): Boolean;
begin
  Result := ... True or False ...;
end;

  ...
  for I := 0 to Objects.Count - 2 do
  begin
    iO := Objects[I];
    for J := Succ(I) to Objects.Count - 1 do
    begin
      jO := Objects[J];
      if IntersectObject(iO, jO) then
        Beep;
    end;
  end;

  TestO := Objects[Irgendeins];
  for I := 0 to Objects.Count - 1 do
  begin
    iO := Objects[I];
    if (TestO <> iO) then
    begin
      if IntersectObject(TestO, iO) then
        Beep;
    end;
  end;

Luis 26. Dez 2018 18:08

AW: "Kollidieren" von drei Objekten verhindern
 
Ich muss ehrlich gestehen viele Sachen in diesem Quellcode kann ich (noch) nicht ganz nachvollziehen, aber das ist nicht deine Aufgabe. :) Werde mich in die Aspekte, die ich nicht nachvollziehen kann jetzt rein lesen und hoffe es dann zu verstehen. Mein simples Schul-Delphi wird für das Problem anscheinend einfach nicht ausreichen. Danke dir!

Luis 26. Dez 2018 18:44

AW: "Kollidieren" von drei Objekten verhindern
 
Ok ist jetzt bisschen doof, aber nach fast einer Stunde bin ich noch immer am selben Punkt, weil ich einfach nichts finde. Könntest du u.U. erläutern wie man z.B. objects.count verstehen muss? Also auf Deutsch ich verstehe das Grundprinzip, aber manche Sachen sind doch Neuland für mich.

stahli 26. Dez 2018 19:30

AW: "Kollidieren" von drei Objekten verhindern
 
Ich bin davon ausgegangen, dass Du einen Vergleich im Griff hast (habe das aber nicht weiter nachvollzogen).

Entsprechend habe ich das Problem so verstanden, dass Du auch weitere Kisten prüfen willst.
Dazu musst Du diese in einer Liste speichern und alle Einträge dann abarbeiten (statt einem Vergleich halt nacheinander alle vergleichen).

Die Vergleichslogik selbst kannst Du dazu am besten in eine eigene Funktion auslagern.


Zu Deinem Code würde ich empfehlen, den immer ordentlich einzurücken:
Delphi-Quellcode:
 if player.top = k1.Top then
   if player.left = k1.left then
     if k1.Top-50 <> k2.Top then
       k1.Top:= k1.top-50
     else
       if k1.left <> k2.left then
         k1.Top:= k1.top-50
       else
         k1.Top:=k1.Top;
Dann erkennt man, dass alle Prüfungen nur erfolgen, wenn player.top = k1.top ist.


So richtig verstehe ich nicht, was Du da machst.
Auf jeden Fall müsstest Du wohl Deine Kisten in einer Liste speichern und die Einträge nacheinander bearbeiten.

Sorry, falls ich Dich ganz falsch verstanden haben sollte.

Luis 26. Dez 2018 19:42

AW: "Kollidieren" von drei Objekten verhindern
 
Ich glaube, wir haben uns wirklich falsch verstanden. Ich möchte einen Spieler haben, welcher die Kisten (k1 und k2) bewegt, wenn er auf das "Feld" (also die gl Koordinaten wie eine Kiste hat) von diesen Kisten geht. Deswegen player.top = k1.top (und left). Nun soll sich eine Kiste nicht bewegen (und somit auch nicht der Spieler, aber das ist hier jetzt nicht so wichtig), wenn sie nach der Bewegung auf dem selben Feld wie eine andere Kiste wäre. Am Ende funktioniert also mein Quellcode für dieses Problem bei einer Kiste. Wahrscheinlich war die Lösung aber nicht die beste, weil ich es für alle Richtungen schreiben muss, das stimmt.

Nun möchte ich das selbe wie für zwei Kisten mit drei Kisten umsetzen und dort reichen mir (wahrscheinlich) diese Mittel nicht aus, weswegen ich ja nun nach Hilfe frage. :)

Luis 26. Dez 2018 20:17

AW: "Kollidieren" von drei Objekten verhindern
 
Ich habe es jetzt mit folgendem Code probiert (natürlich noch in alle Richtungen und mit allen drei Kisten, aber das ist ja prinzipiell gleich aufgebaut)
Delphi-Quellcode:
 if player.top = k1.Top then
 if player.Left =k1.left then
begin
     if k1.Top-50<>k2.Top then
     if k1.Top-50<>k3.Top then
     k1.Top:=k1.Top-50;

     if k1.Top-50 <>k2.Top then
     if k1.Top-50 = k3.top then
     begin
       if k1.Left <>k3.Left then
       k1.Top:=k1.Top-50;

       if k1.Left = k3.Left then
       k1.Top:= k1.Top;
     end;
     if k1.Top-50 = k2.Top then
     if k1.Top-50 <> k3.Top then
     begin
        if k1.Left <>k2.Left then
        k1.Top:=k1.Top-50;

        if k1.Left =k2.Left then
        k1.Top:=k1.Top;
     end;
     if k1.Top-50 = k2.Top then
     if k1.Top-50 = k3.Top then
     begin
       if k1.Left <> k2.Left then
       if k1.Left <> k3.Left then
       k1.Top:=k1.Top-50;

       if k1.Left = k2.Left then
       k1.Top:=k1.Top;

       if k1.Left = k3.Left then
       k1.Top:=k1.Top;
     end;
end;
Hier kollidiert zwar keine Kiste mehr mit einer anderen, allerdings springt gern mal eine Kiste zwei Felder, also 100 Pixel statt den gewünschten 50..

hoika 27. Dez 2018 16:34

AW: "Kollidieren" von drei Objekten verhindern
 
Hallo,
Augenkrebs ;)

Rücke bitte richtig ein und benutze (hier) immer begin end
Ab Kiste k4 wirst Du mächtig Probleme bekommen,
wenn Du nicht wie vorgeschlagen alle Kisten in eine Liste packst.

Du musst dann nur eine Prüfung auf 2 Kisten machen,
benutzt aber die Schleife.

Ausserdem würde ich mit einer virtuellen Kiste arbeiten,
die die Ziel-Position der bewegten Kiste enthält, als ob es keine anderen Kisten gibt.

k_Ziel:= k1; // Daten von Kiste 1 holen
K_Ziel.Top:= K_Ziel.Top-50;

Jetzt k_Ziel mit kx (k2-k10) prüfen, ob es eine Überlappung gibt.

Bei der Überlappung würde ich nicht auf Überlappung, sondern auf Nicht-Überlappung testen.
Das ist einfacher, Bsp:

Frage: Liegt ky von der Höhe überlappend auf kx?
ky.Top<kx.Top+kx.Height

Und das gleiche für links, rechts, oben unten.
Am besten mal auf Quadrat-Papier aufmalen oder 2 Kisten ausschneiden und übereinanderlegen.

Luis 27. Dez 2018 20:54

AW: "Kollidieren" von drei Objekten verhindern
 
Danke erstmal für die Antwort!
Was mich jetzt etwas verwirrt, ist die Tatsache, dass sich bei deinem Vorschlag doch wenig am Aufbau ändert (wenn ich jetzt nichts falsch verstanden habe, wovon ich ausgehe).
Somit sollte sich doch auch wenig an meinem Problem, dass die Kisten nun gern zwei Felder (also 100 statt den gewünschten 50 Pixeln) springen, ändern, oder?

Ich würde den Lösungsansatz mit besagter Liste ja gern nachvollziehen können, nur fällt mir das schwer und Google hat da auch nicht den besten Job gemacht. :/
Bitte steinigt mich nicht für dieses wahrscheinlich simple Problem, bin halt noch am Anfang. :)

stahli 27. Dez 2018 21:41

AW: "Kollidieren" von drei Objekten verhindern
 
Also Deinen Lösungsansatz habe ich jetzt nicht im Detail nachvollzogen. Dafür ist er etwas unübersichtlich.

Aber das ist letztlich kein Problem.
Dein Code erledigt ja offenbar alles, was er soll, bis auf einen Sprung.

Dann setze Dir einen Breakpoint und verfolge den Programmablauf schrittweise incl. Kontrolle der Variableninhalte.
Dann wirst Du den Grund für den fehlerhaften Sprung schon finden.

Hilfreich ist dafür, jede Verzweigung (nach "then", "else" und "do" in begin...end zu setzen.
Dadurch lässt sich der Code besser debuggen.

Das mit den Schleifen lernst Du sicher auch noch später.

Hast Du selbst Interesse am programmieren oder willst Du eher nur Deine Aufgabe erledigen?
Bei einem ernsthaften Interesse musst Du Dich sicher auf eine gewisse Lernkurve einstellen aber wenn man dran bleibt macht man dann schon bald Fortschritte. Das hat jeder hier durchgemacht. :-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:06 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz