Wykrywanie kolizji w DelphiX za pomaca kwadratu

Rus3k

Delphix - wykrywanie kolizji – kwadrat

Na pierwszy rzut oka wydaje się to trudniejsze niż myślimy. Służy do tego funkcja InterSectRect(1kwadrat_w_ktorym_nastopila_kolizja, 2jeden_z_kwadratów, 3drugi_z_kwadratów)

  1. Jest to przydatne gdyż po wykryciu kolizji Delphix podaje współrzędne tego kwadratu. Możemy go przykładowo zamalowac.
  2. Jest to jeden z kwadratów biorący udział w kolizji
  3. Jest to drugi z kwadratów biorący udział w kolizji
    Jak sądzicie czyż nie jest to łatwe. Teraz kod gotowca wraz z komentarzami:
Unit MainUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, DXClass, DXInput, DXDraws;

type
  TMainForm = class(TForm)
    DXDraw1: TDXDraw;
    DXInput1: TDXInput;
    DXTimer1: TDXTimer;
     procedure FormCreate(Sender: TObject);
    procedure DXTimer1Timer(Sender: TObject; LagCount: Integer);
  private
    { Private declarations }
  public
    MoveRect,StayRect,CollisionRect:TRect;//tu deklaracja trzech kwadratów
    Collision:boolean;                    //tu zmienna boolean kolizji
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.DFM}

procedure TMainForm.FormCreate(Sender: TObject);
begin
 Randomize;
 // tutaj narysujemy dwa kwadraty losowo
 MoveRect.Left:=Random(DXDraw1.SurfaceWidth-60);
 MoveRect.Top:=Random(DXDraw1.SurfaceHeight-40);
 MoveRect.Right:=MoveRect.Left+60;
 MoveRect.Bottom:=MoveRect.Top+40;

 StayRect.Left:=Random(DXDraw1.SurfaceWidth-120);
 StayRect.Top:=Random(DXDraw1.SurfaceHeight-80);
 StayRect.Right:=StayRect.Left+120;
 StayRect.Bottom:=StayRect.Top+80;
 //i ustawimy kolizjie na falsz
 Collision:=false;
end;

procedure TMainForm.DXTimer1Timer(Sender: TObject; LagCount: Integer);
begin
 // jesli niemozliwe jest rysowanie  wtedy wyjdz z programu
 if not DXDraw1.CanDraw then exit;

 // wlaczamy obsluge klawiatury
 DXInput1.Keyboard.Update;
//czarne tlo 
 DXDraw1.Surface.Fill(0);
 // obsluga ruchu
 if isLeft in DXInput1.Keyboard.States then // w lewo
  begin
   Dec(MoveRect.Left);
   Dec(MoveRect.Right);
  end;
 if isRight in DXInput1.Keyboard.States then // w prawo
  begin
   Inc(MoveRect.Left);
   Inc(MoveRect.Right);
  end;
 if isUp in DXInput1.Keyboard.States then // do gory
  begin
   Dec(MoveRect.Top);
   Dec(MoveRect.Bottom);
  end;
 if isDown in DXInput1.Keyboard.States then // do dolu
  begin
   Inc(MoveRect.Top);
   Inc(MoveRect.Bottom);
  end;

 // i tu nasza magiczna funkcja
 if InterSectRect(CollisionRect{patrz 1.},MoveRect{patrz 2.},StayRect{patrz 3.})
 then
  Collision:=true
 else collision:=false;

 // jesli kolizji nie ma dalej rysujemy kwadraty
 with DXDraw1.Surface.Canvas do
  begin
   Pen.Width:=2;
   Brush.Style:=bsClear;
   Pen.Color:=clYellow;
   Rectangle(MoveRect);
   Rectangle(StayRect);

   // jesli jest ......
   if Collision then
    begin
     Pen.Color:=clLime;
     Font.Color:=clWhite;
     Font.Name:='Tahoma';
     Font.Style:=[fsBold];
     Font.Size:=15;
     TextOut(10,10,'!! Kolizjia !!');

     Brush.Style:=bsSolid;
     Brush.Color:=clRed;
     rectangle(collisionrect);// zmalowywujemy ten kwadrat w ktorym miala miejsce
    end;                     //kolizjia

   // zwalniamy pamiec
   Release;
  end;

 // i wyswietlamy
 DXDraw1.Flip;
end;

end.

jeśli cos nie dziala(prawdopodobnie zle ustawiles DXDraw) zamieszczam gotowca.....
[url]http://www.4programmers.net/download.php?id=943[/url]

2 komentarzy

zoptymalizujmy to:

Collision:=InterSectRect(CollisionRect{patrz 1.},MoveRect{patrz 2.},StayRect{patrz 3.});

zamiast

if InterSectRect(CollisionRect{patrz 1.},MoveRect{patrz 2.},StayRect{patrz 3.})
 then
  Collision:=true
 else collision:=false;

No wiesz, jakbys czytal moj kurs delphiX to bys zobaczyl tam, ze taka funkcjasprawdzenia kolizji w kwadracie jest dostepna w jednej funkcji, i ma chyba o 80% mniej kodu =]