![]() |
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:
Hier geht es um die Bewegung nach oben von der Kiste 1, also k1.
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; Und einmal meine "richtige" Lösung von dem Problem bei zwei Kisten:
Delphi-Quellcode:
Danke schon einmal für eure Hilfe!
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; |
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; |
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!
|
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.
|
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:
Dann erkennt man, dass alle Prüfungen nur erfolgen, wenn player.top = k1.top ist.
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; 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. |
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. :) |
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:
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..
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; |
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. |
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. :) |
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 11:11 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