Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi [DelphiX] Kollision (https://www.delphipraxis.net/29475-%5Bdelphix%5D-kollision.html)

Matze 9. Sep 2004 14:59


[DelphiX] Kollision
 
Hi zusammen! :)

Ich weiß, das Thema hatten wir schon oft, aber mir helfen die Suchergebnise nicht.


Folgender Code wird ausgelöst, wenn eine Kollision stattfindet (2D):
Delphi-Quellcode:
  TAnimation = class(TImageSprite)
    public
      procedure DoMove(MoveCount: Integer); override;
      procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
    end;

...


procedure TAnimation.DoCollision(Sprite: TSprite; var Done: Boolean);
var InCollision: boolean;
begin
  //Bewegung nach links (ich müsste noch die Y Koorinaten überprüfen)
  if (X < TGegenstand(Sprite).X + Gegenstand.Width) then
          cangoleft := false;
end;
Hier möchte ich abfragen, ob sich eine Figur in eine bestimmte Richtung bewegen kann, in dem Beispiel, nach links.

So überprüfe ich auch die anderen benachbarten Koorinaten, das Problem ist nur, dass diese Prozedur ausgelöst wird, wenn man sich in einem Gegenstand befindet, und nicht, wenn man danaben ist.


Hier ist eine Kollisionsabfrage beschrieben, die mich jedoch nicht weiter bringt.

Ich habe schon versucht, die Kollisions-Prozedur einfach neu zu schreiben und keine von TAnimation zu nehmen, doch das hat nicht geklappt, da, da z.B. "Sprite" nicht bekannt ist.


Kann mir da evtl jemand behilflich sein? :roll:

Matze 10. Sep 2004 10:42

Re: [DelphiX] Kollision
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab jetzt mal weiter Probiert, so weit bin ich gekommen:

Im Anhang die gepackte exe, damit ihr seht, wie "seltsam" sich die Figur verhält" und hier der ausschlaggebende Source:

Delphi-Quellcode:
//////////////////////////////////////////
// DOCANGO
//////////////////////////////////////////
procedure TAnimation.DoCanGo(Enabled: Boolean);
begin
  cangoleft := Enabled;
  cangoright := Enabled;
  cangoup := Enabled;
  cangodown := Enabled;
end;


//////////////////////////////////////////
// BEWEGUNG DER ANIMATION
//////////////////////////////////////////
procedure TAnimation.DoMove(MoveCount: integer);
begin
  inherited DoMove(MoveCount);

  If cangoup and (isUp in Form1.DXInput1.States) Then
    if not Jump then
    begin
      DoCanGo(true);
      Y := Y - Step;
    end;
  If cangodown and (isDown in Form1.DXInput1.States) Then
  begin
    DoCanGo(true);
   end;
  If cangoleft and (isLeft in Form1.DXInput1.States) Then
  begin
    DoCanGo(true);
    X := X - Step;
    if not Duck then
      Form1.AnimBild('Girl1left');
  end;
  If cangoright and (isRight in Form1.DXInput1.States) Then
  begin
    DoCanGo(true);
    X := X + Step;
    if not Duck then
      Form1.AnimBild('Girl1right');
  end;

  Collision;
end;


//////////////////////////////////////////
// KOLLISIONS-ABFRAGE
//////////////////////////////////////////
procedure TAnimation.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
  DoCanGo(true);

  if (X < TGegenstand(Sprite).X - Step) then
  begin
    X := X - Step;
    cangoright := false;
  end;
  if (X > TGegenstand(Sprite).X + Step) then
  begin
    X := X + Step;
    cangoleft := false;
  end;
  if (Y + Animation.Height > TGegenstand(Sprite).Y + Step) then
  begin
    Y := Y + Step;
    cangoup := false;
    Jump := false;
  end;          
  if (Y < TGegenstand(Sprite).Y + TGegenstand(Sprite).Height - Step) then
  begin
    Y := Y - Step;
    Hoehe := 0;
    cangodown := false;
  end;
end;


//////////////////////////////////////////
// TIMER
//////////////////////////////////////////
procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer);
begin
  DXInput1.Update;
  DXSpriteEngine1.Move(1);
  DxDraw1.Surface.Fill(0);
  DXDraw1.Surface.Draw(0, 0, FSurface.ClientRect, FSurface, TRUE);
  DXSpriteEngine1.Draw;

  if Jump then
  begin
    InJump := true;
    Animation.Y := Animation.Y - Step;
    inc(Hoehe);
    if Hoehe = 30 then
      Jump := false;
  end else
  begin
    if cangodown then
    begin
      Animation.Y := Animation.Y + Step;
    end else
      InJump := false;
  end;

  DXDraw1.Flip;
end;


//////////////////////////////////////////
// FORM KEY DOWN
//////////////////////////////////////////
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (key = vk_up) and not InJump and (Hoehe <= 30) then
  begin
    Jump := true;
    InJump := true;
  end;
  if key = vk_down then
  begin
    if not Duck then
      Bild := Animation.Image.Name;
    Ducken(true);
  end;
end;


//////////////////////////////////////////
// FORM KEY UP
//////////////////////////////////////////
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if key = vk_up then
  begin
    Jump := false;
    cangodown := true;
  end;
  if key = vk_down then
    Ducken(false);
end;
Ich habe absichtlich nicht den restlichen Quelltext angehängt, weil er Dinge enthält, die ich noch nicht unbedingt veröffentlichen möchte. :roll:

Dass man in der Luft bleibt, wenn man Pfeil-Hoch klickt, wird noch behoben. ;)

mimi 12. Sep 2004 08:15

Re: [DelphiX] Kollision
 
ja ist klar das die figur in der "Mauer" ferst hängt um das zu behben müste ein if x +1 > .... reichen in der collisions funktion dabei musst du halt ermitteln in welche richtung dein player läuft und dann if x + player.dir nehmen wobei player.dir einen wert von -1 und +1 haben solle.
ich hoffe du weißt wie ich das meine, wenn nicht:

Delphi-Quellcode:
if (X-1 < TGegenstand(Sprite).X - Step) then
  begin
    X := X - Step;
    cangoright := false;
  end;
  if (X+1 > TGegenstand(Sprite).X + Step) then
  begin
    X := X + Step;
    cangoleft := false;
  end;
du musst einfach nur einen fehlt vor bzw. zurück schauen :-D

Matze 12. Sep 2004 11:38

Re: [DelphiX] Kollision
 
Danke Mimi!

Nur besteht das problem teilweise weiterhin, in der exe von oben ist es z.B. so, dass man durch die 2 aufeinandergestelten ästen durchlaufen kann, da sie Figur irgendwie im den Boden versinkt....

mimi 12. Sep 2004 12:04

Re: [DelphiX] Kollision
 
ich habe eine collisions funktion vom delphiForum bekommen, evtl. hilft sie dir ja weiter:
Delphi-Quellcode:
function TDX.kollision(nr1,nr2,nr1x,nr1y,nr2x,nr2y, pat1,pat2:integer):boolean;
var
  ueberlapp_breite, ueberlapp_hoehe:integer;
  ueberlapp_nr1_x, ueberlapp_nr1_y, ueberlapp_nr2_x,ueberlapp_nr2_y:integer;
  x,y:integer;
  nr1_breite, nr2_breite, nr1_hoehe, nr2_hoehe:integer;
  farbenr1,farbenr2:tcolor;
begin
  farbenr1:=clBlack;
  farbenr2:=clBlack;
  ueberlapp_nr1_x:=-1;
  ueberlapp_nr1_Y:=-1;

  ueberlapp_nr2_x:=-1;
  ueberlapp_nr2_Y:=-1;

  if (DXImageList1.Items[nr1].PatternWidth = 0 ) then
    begin
      nr1_breite := DXImageList1.Items[nr1].Width;
      nr1_hoehe := DXImageList1.Items[nr1].Height;
    end
  else
    begin
      nr1_breite := DXImageList1.Items[nr1].PatternWidth;
      nr1_hoehe := DXImageList1.Items[nr1].PatternHeight;
    end;
  if (DXImageList1.Items[nr2].PatternWidth = 0 ) then
    begin
      nr2_breite := DXImageList1.Items[nr2].Width;
      nr2_hoehe := DXImageList1.Items[nr2].Height;
    end
  else
    begin
      nr2_breite := DXImageList1.Items[nr2].PatternWidth;
      nr2_hoehe := DXImageList1.Items[nr2].PatternHeight;
    end;

  kollision := false;
  if nr1x < nr2x then
    ueberlapp_breite := (nr1x + nr1_breite) - (nr2x)
  else
    ueberlapp_breite := (nr2x + nr2_breite) - nr1x;
  if nr1_breite > nr2_breite then
    if ueberlapp_breite >= nr2_breite then ueberlapp_breite := nr2_breite;


 if nr1y < nr2y then
    ueberlapp_hoehe := (nr1y + nr1_hoehe) - (nr2y)
  else
    ueberlapp_hoehe := (nr2y + nr2_hoehe) - (nr1y);
  if nr1_hoehe > nr2_hoehe then
    if ueberlapp_hoehe > nr2_hoehe then ueberlapp_hoehe := nr2_hoehe;


  if (ueberlapp_breite > 0) and (ueberlapp_hoehe > 0) then
    begin
      if nr1_breite >= nr2_breite then
        begin
          if (nr2x+nr2_breite) >= (nr1x+nr1_breite) then
            begin
              ueberlapp_nr1_x := nr1_breite - ueberlapp_breite;
              ueberlapp_nr2_x := 0;
            end;
          if ((nr2x+nr2_breite) < (nr1x+nr1_breite))
               and (nr2x >= nr1x)then
            begin
              ueberlapp_nr1_x := (nr2x-nr1x);
              ueberlapp_nr2_x := 0;
            end;
          if (nr2x) < (nr1x) then
            begin
              ueberlapp_nr1_x := 0;
              ueberlapp_nr2_x := nr2_breite - ueberlapp_breite;
            end;
        end;
      if nr1_breite < nr2_breite then
        begin
          if (nr1x+nr1_breite) >= (nr2x+nr2_breite) then
            begin
              ueberlapp_nr2_x := nr2_breite - ueberlapp_breite;
              ueberlapp_nr1_x := 0;
            end;
          if ((nr1x+nr1_breite) < (nr2x+nr2_breite))
               and (nr1x >= nr2x)then
            begin
              ueberlapp_nr2_x := (nr1x-nr2x);
              ueberlapp_nr1_x := 0;
            end;
          if (nr1x < nr2x)then
            begin
              ueberlapp_nr2_x := 0;
              ueberlapp_nr1_x := nr1_breite - ueberlapp_breite;
            end;
        end;

      if nr1_hoehe >= nr2_hoehe then
        begin
          if (nr2y+nr2_hoehe) >= (nr1y+nr1_hoehe) then
            begin
              ueberlapp_nr1_y := nr1_hoehe - ueberlapp_hoehe;
              ueberlapp_nr2_y := 0;
            end;
          if ((nr2y+nr2_hoehe) < (nr1y+nr1_hoehe))
               and (nr2y >= nr1y)then
            begin
              ueberlapp_nr1_y := (nr2y-nr1y);
              ueberlapp_nr2_y := 0;
            end;
          if (nr2y) < (nr1y) then
            begin
              ueberlapp_nr1_y := 0;
              ueberlapp_nr2_y := nr2_hoehe - ueberlapp_hoehe;
            end;
        end;
      if nr1_hoehe < nr2_hoehe then
        begin
          if (nr1y+nr1_hoehe) >= (nr2y+nr2_hoehe) then
            begin
              ueberlapp_nr2_y := nr2_hoehe - ueberlapp_hoehe;
              ueberlapp_nr1_y := 0;
            end;
          if ((nr1y+nr1_hoehe) < (nr2y+nr2_hoehe))
               and (nr1y >= nr2y)then
            begin
              ueberlapp_nr2_y := (nr1y-nr2y);
              ueberlapp_nr1_y := 0;
            end;
          if (nr1y < nr2y)then
            begin
              ueberlapp_nr2_y := 0;
              ueberlapp_nr1_y := nr1_hoehe - ueberlapp_hoehe;
            end;
        end;



      for x := 0 to (ueberlapp_breite-1) div 4 do
        for y := 0 to (ueberlapp_hoehe -1)div 4 do begin
            if (pat1 = 0) and (DXImageList1.Items[nr1].PatternWidth = 0 ) then begin
               farbenr1:=DXImageList1.Items[nr1].picture.Bitmap.Canvas.Pixels[ueberlapp_nr1_x+x*4,ueberlapp_nr1_y+y*2];
            end;
            if (pat2 = 0) and (DXImageList1.Items[nr2].PatternWidth = 0 )then begin
               farbenr2:=DXImageList1.Items[nr2].picture.Bitmap.Canvas.Pixels[ueberlapp_nr2_x+x*4,ueberlapp_nr2_y+y*2];
            end;
            if (pat1 >= 0) and (DXImageList1.Items[nr1].PatternWidth > 0 ) then begin
               farbenr1:=DXImageList1.Items[nr1].PatternSurfaces[pat1].Canvas.Pixels[ueberlapp_nr1_x+x*4,ueberlapp_nr1_y+y*2];
            end;

            if (pat2 >= 0) and (DXImageList1.Items[nr2].PatternWidth > 0 ) then begin
               farbenr2:=DXImageList1.Items[nr2].PatternSurfaces[pat2].Canvas.Pixels[ueberlapp_nr2_x+x*4,ueberlapp_nr2_y+y*2];
            end;

            if ( farbenr1 <> DXImageList1.Items[nr1].TransparentColor) and (farbenr2 <> DXImageList1.Items[nr2].TransparentColor) then
              kollision := true;
          end;
         DXImageList1.Items[nr1].Restore;
         DXImageList1.Items[nr2].Restore;
    end;
end;
musst du noch anpassen dann sollte es gehen.... aber du musst immer schauen ob sich das objekt hintern den objekten befindet oder vordem objekt *G*

Matze 12. Sep 2004 12:09

Re: [DelphiX] Kollision
 
Danke, das ist die, die ich im ersten Post erwähnt habe.

Welche Parameter werden denn da übergeben?

mimi 12. Sep 2004 12:18

Re: [DelphiX] Kollision
 
also wenn ich das noch richt weißt folgende:

kollision(1,2,x1,y1,x2,y2,0,0);

1 und 2 sind die objekte aus der DXImageList die Verlichenwerden sollen
x1 und y1 und x2 und Y2 sind die objekte positionen und 0 und 0 ist der PatterIndex
für beide objekte


eine kleine bitte: sollts du diese funktion optimieren, könntes du sie mir dann auch nochmal senden ???


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:13 Uhr.

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