[Delphi] Problem z grą - algorytm kolizji

0

Witam, mam mały problem. Piszę na infę gierkę w delphi, a mianowicie Pilsnera (butelki spadają i trzeba je łapać). Tylko mam problem z deklaracją kolizji butelki ze skrzynką i naliczania punktów.

Pierwszą butelkę zlicza jako 50 punktów zamiast 100, potem już normalnie. Kto ma pomysl czemu tak jest?

Tu kod z timera, który zlicza pkt-y i sprawdza czy nie doszło do kolizji.
[code]procedure TForm1.TimerekTimer(Sender: TObject);
var
i,j:integer;
begin
for i:=1 to a do
begin
obrazy[i].Top:=obrazy[i].Top+10;
if i >= 2 then for j := (i-1) to i do
if (obrazy[j].top+obrazy[j].Height>=389) and
(obrazy[j].top+obrazy[j].Height<=395) and
(obrazy[j].left+15>=image1.left) and
(obrazy[j].Left+15<=image1.Left+image1.Width) then
begin
obrazy[j].Visible:=False;
pkt:=pkt+50;
end;
end;
Label1.Caption:='Punkty: '+IntToStr(pkt);[/code]

A tu kod całego progsa:

[code]unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, jpeg, ExtCtrls, StdCtrls, ShellAPI;
var
a,pkt:integer;
type
TForm1 = class(TForm)
Panel1: TPanel;
Image1: TImage;
Label1: TLabel;
Timer1: TTimer;
i4: TImage;
Timerek: TTimer;
procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure TimerekTimer(Sender: TObject);

private
{private declarations}
obrazy:array [1..100] of TImage;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
Image1.Left:=x-52;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
pkt:=0;
ShowCursor(False);
Form1.DoubleBuffered := true;
a:=0;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
inc(a);
obrazy[a]:= TImage.Create(Self);
with obrazy[a] do
begin
parent:=Panel1;
left:=random(473);
top:=0;
Picture.LoadFromFile('asd.jpg');
Visible:=True;
Width:=30;
height:=90;
end;
end;

procedure TForm1.TimerekTimer(Sender: TObject);
var
i,j:integer;
begin
for i:=1 to a do
begin
obrazy[i].Top:=obrazy[i].Top+10;
if i >= 2 then for j := (i-1) to i do
if (obrazy[j].top+obrazy[j].Height>=389) and
(obrazy[j].top+obrazy[j].Height<=395) and
(obrazy[j].left+15>=image1.left) and
(obrazy[j].Left+15<=image1.Left+image1.Width) then
begin
obrazy[j].Visible:=False;
pkt:=pkt+50;
end;
end;
Label1.Caption:='Punkty: '+IntToStr(pkt);
end;
end.[/code]

Kto zna jakiś prostszy algorytm na sprawdzanie kolizji? Bo ten wydaje mi sie strasznie łopatologiczny. Jest w delphi coś na styl flashowego hittesta??

0
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, jpeg, ExtCtrls, StdCtrls, ShellAPI;
var
  a, pkt: integer;
type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Image1: TImage;
    Label1: TLabel;
    Timer1: TTimer;
    i4: TImage;
    Timerek: TTimer;
    procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure TimerekTimer(Sender: TObject);

  private
    {private declarations}
    obrazy: array[1..100] of TImage;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Image1.Left := x - 52;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  pkt := 0;
  ShowCursor(False);
  Form1.DoubleBuffered := true;
  a := 0;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  inc(a);
  obrazy[a] := TImage.Create(Self);
  with obrazy[a] do
  begin
    parent := Panel1;
    left := random(473);
    top := 0;
    Picture.LoadFromFile('asd.jpg');
    Visible := True;
    Width := 30;
    height := 90;
  end;
end;

procedure TForm1.TimerekTimer(Sender: TObject);
var
  i, j: integer;
begin
  for i := 1 to a do
  begin
    obrazy[i].Top := obrazy[i].Top + 10;
    if i >= 2 then
      for j := (i - 1) to i do
        if (obrazy[j].top + obrazy[j].Height >= 389) and
          (obrazy[j].top + obrazy[j].Height <= 395) and
          (obrazy[j].left + 15 >= image1.left) and
          (obrazy[j].Left + 15 <= image1.Left + image1.Width) then
        begin
          obrazy[j].Visible := False;
          pkt := pkt + 50;
        end;
  end;
  Label1.Caption := 'Punkty: ' + IntToStr(pkt);
end;

end.
  1. naucz się formatować kod
  2. nazywaj zmienne zamiast image1, label1 itp
  3. czemu ma zwiększać pkt o 100 jak masz pkt := pkt + 50;
  4. PtInRect, IntersectRect
0

a <- butelka
b <- skrzynia

if a.top + a.height = b.top then
  showmessage('Kolizja');
0

Misiekd, niechcący użyłem złego tagu, a potem nie było już możliwości edycji za co przepraszam. Przejęzyczyłem się, ma zliczać co 50. i pierwszy zlicza dobrze, a potem już po 100. Jak sądzicie, czemu?
Co natomiast oznacza pkt. 4?
Co do wypowiedzi @vecco_off, to nie masz racji. to co Ty napisaleś to sprawdza tylko czy dół butelki jest równy górze skrzynki ale to nie znaczy że doszło do kolizji bo może być obok. Ja tym myśleniem dopisałem jeszcze zależność prawo-lewo, ale myślłem że jest jakiś prostszy sposób bo tak to wychodzi strasznie zawiły kod i chyba niezbyt poprawny.
</url>

0

Sory za post pod postem, ale nie mam niestety opcji edycji:(
@Misiekd, dzieki wielkie za te funkcje! Są super;)
Tylko wyrzuca mi taki błąd:
[Error] Unit1.pas(96): Incompatible types: 'Types.TRect' and 'Unit1.TRect'

A typy mam zadeklarowane tak:

type
  TRect = packed record
  Left, Top, Right, Bottom: Integer;
  end;

  TPoint = packed record
  X: integer;
  Y: integer;
  end;

Błąd podświetla w tej linijce:
for i := 1 to a do if PtInRect(R, butle[i]) then pkt := pkt + 100;

Wcześniej wyrzucało też błąd przy użyciu funkcji Point i Rect, ale usunałem je i dane wpisałem ręcznie, tj:

R.left :=Image1.left;
R.top:=Image1.top;

itp;

0
Wojcieszek napisał(a)

Sory za post pod postem, ale nie mam niestety opcji edycji:(

Opcja bezdie jak sie zarejestrujesz? ;)

Wojcieszek napisał(a)

Tylko wyrzuca mi taki błąd:
[Error] Unit1.pas(96): Incompatible types: 'Types.TRect' and 'Unit1.TRect'

Wyrzuca Ci taki blad, poniewaz definiujesz na nowo zmienne TRect i TPoint. Po co? To standardowe typy, zdefiniowane w unicie Types. Wywal te definicje ze swojego programu.

A jesli chodzi o ta punktacje to jest jakis galimatias;) Raz masz inkrementacje o 50 raz o 100.

Podaj kompilowane zrodlo programu i jeszcze raz zreferuj problem ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1