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)
- Jest to przydatne gdyż po wykryciu kolizji Delphix podaje współrzędne tego kwadratu. Możemy go przykładowo zamalowac.
- Jest to jeden z kwadratów biorący udział w kolizji
- 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]
zoptymalizujmy to:
zamiast
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 =]