Autor Beitrag
Caro:3
Hält's aus hier
Beiträge: 7



BeitragVerfasst: So 28.03.21 23:32 
Hey ihr Lieben :wave:
ich arbeite derzeit an einem Jump 'n' Run Spiel für die Schule (in Lazarus) und leider bekomme ich einen der wichtigsten Punkte gar nicht hin: die Kollision! :cry: Ich habe schon einige Beiträge gelesen und ausprobiert, aber nichts funktioniert so wirklich :cry: .
Mein Ziel ist es ein Image (Spielfigur) mit Hindernissen (auch Image) "zusammenstoßen" zu lassen, so dass meine Figur eben nicht hindurch kann. Mit einem einzelnen Hindernis habe ich das schon geschafft, aber für mehrere funktioniert es einfach nicht! :nixweiss:
Vielleicht kann mir da ja jemand behilflich sein, ich würde mich über jede Hilfe freuen! :angel:
LG Caro:3


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Di 30.03.2021 um 08:41
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4392
Erhaltene Danke: 944

Win10
C#, C++ (VS 2015/17/19)
BeitragVerfasst: Mo 29.03.21 09:40 
Was genau funktioniert "für mehrere nicht"?
Du mußt eigentlich nur in einer Schleife alle Hindernisse durchgehen und jeweils mit der (neuen) Position der Spielfigur auf eine Kollision prüfen (ich nehme mal an, die Kollision zweier Objekte hast du schon als Funktion).
Caro:3 Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Mo 29.03.21 15:47 
Hey, vielen Dank für deine Antwort!
Leider fällt mir das gar nicht soo leicht :oops:
Ich habe für die Kollision von zwei Objekten einfach bei der Abfrage, ob die Taste gedrückt wurde ein "and" und dann die Kollision dahinter geschoben... Von einer Funktion habe ich auch schon gehört und sie auch ausprobiert, nur bin ich noch nicht dahinter gekommen, wie ich das Ergebnis einer Funktion in eine Prozedur einbaue. So etwas hatten wir auch leider nicht im Unterricht :oops:
Ich müsste für die Kollision doch abfragen:
ausblenden Delphi-Quelltext
1:
2:
If (Image1.left+10 = Image2.left) or (Image1.left = Image3.left) then
  result:=true;

oder? Bietet sich hierbei eigentlich überhaupt das "=" an?
Sind wahrscheinlich totale Anfängerfragen, aber das bin ich nun mal :oops:
Ich hoffe du bzw. jemand kann mir dabei helfen,
Caro:3 :angel:

Moderiert von user profile iconTh69: Color- durch Delphi-Tags ersetzt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4392
Erhaltene Danke: 944

Win10
C#, C++ (VS 2015/17/19)
BeitragVerfasst: Mo 29.03.21 16:17 
Nein, so funktioniert keine Kollisionsabfrage (so fragst du ja nur genau auf exakte Übereinstimmung der Position ab).

Schau mal in Feststellen, ob zwei Rechtecke kollidieren und Kollisionsabfrage.
Caro:3 Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Mo 29.03.21 17:12 
Ich hab mir das angeguckt und es funktioniert auch fast, allerdings "bugt" sich Shape1 durch die andern beiden Shapes, wenn man nach der Kollision die jeweils andere Taste drückt. Das ist das was ich bisher fabriziert hab:

ausblenden 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:
function KollisionL (Shape1, Shape2, Shape3: TShape): Boolean;
begin
 result:=true ;
 If (Shape1.left+Shape1.width >= Shape2.Left) and (Shape2.left+Shape2.width >= Shape1.Left) or
    (Shape1.left+Shape1.width >= Shape3.Left) and (Shape3.left+Shape3.width >= Shape1.Left) 
 then
 result:=false;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState
  );
begin
  If (key=$44and (KollisionL (Shape1, Shape2, Shape3))then
  Shape1.left:=shape1.left+10
  else if (key=$44then
  Shape1.Left:=Shape1.left-5;


  If (key=$41and (KollisionL (Shape1, Shape2, Shape3)) then
  Shape1.left:=shape1.left-10
  else if (key=$41then
  Shape1.Left:=Shape1.left+5;
end;
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1242
Erhaltene Danke: 112

Win7
DXE2 Prof, Lazarus
BeitragVerfasst: Mo 29.03.21 17:37 

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Jetzt rächt sich die Natur und tötet uns.
Caro:3 Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Mo 29.03.21 19:57 
user profile iconSinspin hat folgendes geschrieben Zum zitierten Posting springen:
Crosspost!

darf ich fragen was das bedeutet? :oops:
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1242
Erhaltene Danke: 112

Win7
DXE2 Prof, Lazarus
BeitragVerfasst: Mo 29.03.21 22:32 
Klar. ;-) Du stellst in mehr als einem Forum die gleiche Frage. In allen Foren reißen sich die Leute ein Bein aus um dir zu helfen, obwohl du in irgend einem anderen Forum schon längst die Antworten bekommen hast und es dich garnicht mehr interessiert was noch kommt.

Du kannst gerne weiterhin in mehr als einem Forum posten. Nur verlinke deine Beiträge dann bitte.
Wir helfen ja gerne, nur wenn es für die Katz ist dann fühlt sich das so :puke: an.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Jetzt rächt sich die Natur und tötet uns.
Caro:3 Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Mo 29.03.21 22:48 
Ohje :oops: So war das eigentlich gar nicht gedacht :oops:
Ich hatte dabei eigentlich 2 verschiedene Fragen angedacht, also einmal Springen und einmal Kollision mit Hindernissen und es war mir ein wenig peinlich 2 doofe Fragen auf einmal zu stellen...
Wenn das jetzt aber so ist, tuts mir Leid :angel:
Fiete
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 566
Erhaltene Danke: 272

W7
Delphi 6 pro
BeitragVerfasst: Di 30.03.21 17:24 
Moin Caro:3,

Hinter Kollisionsabfragen steckt ein bißchen Mathematik.

Ein altes Beispiel für Rechtecke
Mensch ist ein TImage
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function TLaby.Kollision:Boolean;
  var K:Integer;
      A1,A2,B1,B2:TPoint;
  begin
   Kollision:=False;
   A1.X:=Mensch.Left;A1.Y:=Mensch.Top; // oben links - A1
   A2.X:=Mensch.Left+Mensch.Width;
   A2.Y:=Mensch.Top+Mensch.Height;   // unten rechts - A2
   for K:=1 to 31 do
    begin
     Hindernis:=TImage(FindComponent('Image'+IntToStr(K)));
     B1.X:=Hindernis.Left;B1.Y:=Hindernis.Top; // oben links - B1
     B2.X:=Hindernis.Left+Hindernis.Width;
     B2.Y:=Hindernis.Top+Hindernis.Height;   // unten rechts - B2
     if ((A1.Y<B1.Y) and (B1.Y<A2.Y)) or ((B1.Y<A1.Y) and (A1.Y<B2.Y)) then // Kollision möglich
      if ((B1.X<=A1.X) and (A1.X<=B2.X)) or ((A1.X<=B1.X) and (B1.X<=A2.X)) then
       begin Kollision:=True;exit end;
    end;
  end;

Ein altes Beispiel für Kreise
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function TEskiv.Kollision(Ball,Hindernis:TShape):Boolean;  // Ball mit Hindernis
  var P1,P2:TPoint;
      R1,R2:Integer;
  begin
   P1.X:=Ball.Left+Ball.Width div 2;
   P1.Y:=Ball.Top+Ball.Height div 2;
   P2.X:=Hindernis.Left+Hindernis.Width div 2;
   P2.Y:=Hindernis.Top+Hindernis.Height div 2;
   R1:=Ball.Width div 2;
   R2:=Hindernis.Width div 2;
   Result:=sqr(P1.X-P2.X)+sqr(P1.Y-P2.Y)<=sqr(R1+R2) 
  end;

Ich hoffe die Mathematik ist nicht zu kompliziert :wink:
Gruß
Fiete

_________________
Fietes Gesetz: use your brain (THINK)