Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   FreePascal Kollision Image Shape (https://www.delphipraxis.net/192337-kollision-image-shape.html)

Maurooon 10. Apr 2017 15:22

Delphi-Version: 5

Kollision Image Shape
 
Hey Leute,

kann mir jemand bei einer Kollisionsabfrage helfen? Es geht um folgendes: Ein Image bewegt sich per Pfeiltasten auf einer Form. Auf dieser Form finden sich aber noch mehrere Shapes, die als Hindernisse zu sehen sind. Wenn man das Image gegen eines dieser Shapes steuert, soll man sich nur noch von diesem Shape wegbewegen können. Ich habe mir bis jetzt folgende Gedanken gemacht:

Als erstes habe ich versucht, einfach eine Variable auf false zu setzen wenn entsprechende Koordinaten übereinstimmen und nur dann im KeyDown Event das Image bewegen zu können. Dann brauche ich aber ja für jedes Shape 4 Variablen, weil man ja wenn man bspw. von links in das Shape reinfährt, sich trotzdem noch nach oben, unten oder links bewegen können soll. Das muss ja eleganter gehen.

Dann habe ich versucht, in einem Timer die jeweilige Kollision abzufragen und mein Image bei Kollision automatisch wieder an den Rand des Shapes zu versetzen, doch ich konnte das Image trotzdem weiterhin durch die Shapes bewegen.

Ich suche also nach einer eleganten Version, ein Image nur dann mit den Pfeiltasten bewegen zu können, wenn es mit keinem der Shapes auf der Form kollidiert. Sollte es jedoch einmal kollidieren, sollte man das Image wieder zurückbewegen können. Damit das noch geschmeidigt aussieht, hab ich mir bisher als Kollisionszone sag ich mal immer einen 2 Pixel breiten Rand um das Shape gedacht. Bewegt man das Image da rein, ist die Bewegung in diese Richtung gesperrt.

Ich hoffe es findet sich hier jemand zurecht und die Zeit, mir bei meinem Problem behilflich zu sein.

LG

Jumpy 10. Apr 2017 16:46

AW: Kollision Image Shape
 
Wie funktioniert denn deine Steuerung? Sagen wir du drückst 1x die linke Pfeiltaste, bewegt sich das Shape dann einen "Schritt" nach links und das war's oder bewegt es sich so lange nach links bis es an Wand oder Hindernis kommt oder du eine andere Pfeiltaste drückst?

Maurooon 10. Apr 2017 18:00

AW: Kollision Image Shape
 
Zitat:

Zitat von Jumpy (Beitrag 1367015)
Wie funktioniert denn deine Steuerung? Sagen wir du drückst 1x die linke Pfeiltaste, bewegt sich das Shape dann einen "Schritt" nach links und das war's oder bewegt es sich so lange nach links bis es an Wand oder Hindernis kommt oder du eine andere Pfeiltaste drückst?

Es bewegt sich pro Tastendruck um X Pixel in die jeweilige Richtung.

Jumpy 11. Apr 2017 08:57

AW: Kollision Image Shape
 
Aber dann ist es doch einfach. Nach einem Tastendruck in eine Richtung (sagen wir mal links) prüfts du zunächst, ob das Shape sich überhaupt nach links bewegen kann, oder ob es schon zu nach an einem Hindernis in dieser Richtung ist.
Ist es zu nah, verfällt halt die Bewegung / der Tastendruck.
Ist es nicht zu nah, bewegst du das Shape halt um maximal X Pixel in die gewünschte Richtung. Maximal deshalb, weil du natürlich prüfen musst, ob es nicht schon zuvor in Kollisionsnähe kommt.

Maurooon 11. Apr 2017 16:18

AW: Kollision Image Shape
 
Das ist mir schon klar, nur ist das Hindernis nur bspw. 10 Pixel breit, das heißt wenn es um das Hindernis drum herum ist, soll es sich ja auch noch bewegen können. Deshalb brauch man ja quasi eine Zone, und dabei geht es mir darum, das elegant und einfach (im Sinne von wenig Quelltext) zu gestalten als mit 4 Variablen pro Hinderniss.

himitsu 11. Apr 2017 16:36

AW: Kollision Image Shape
 
Wenn es sich um 10px bewegt, aber das hindernis weniger als 10px breit ist, dann mußt du auch zwischenpositionen prüfen. (im Extremfall eben jedes Pixel)

Und der Rest wurde doch schon gesagt?
* Du berechnest die neue Position
* prüfst ob es eine Kollision geben würde
* und wenn es kollidiert, dann wird das Objekt eben nicht bewegt.

Delphi-Referenz durchsuchenTypes.IntersectRect
Delphi-Referenz durchsuchenTRect.IntersectRect

Delphi-Referenz durchsuchenTypes.PtInRect
Delphi-Referenz durchsuchenTRect.PtInRect bzw. Delphi-Referenz durchsuchenTPoint.PtInRect

Blup 12. Apr 2017 13:33

AW: Kollision Image Shape
 
Ein kleines Beispiel(ungetestet):
Delphi-Quellcode:
function CanPosChanging(AControl: TControl; const ANewPos: TRect): Boolean;
var
  lControl: TControl;
  lRect: TRect;
begin
  // Überschneidung mit Shape ist unzulässig
  if Assgined(AControl.Parent) then
  begin
    for lControl in AControl.Parent.Controls do
    begin
      if lControl is TShape then
      begin
        if IntersectRect(lRect, lControl.BoundsRect, ANewPos) then
        begin
          Result := False;
          Exit;
        end;
      end;
    end;
  end;
  Result := True;
end;

procedure DoPosChanging(AControl: TControl; const ANewPos: TRect);
begin
  if CanPosChanging(AControl, ANewPos) then
    AControl.BoundsRect := ANewPos;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  dx, dy: Integer;
  lNewPos: TRect;
begin
  dx := 0;
  dy := 0;
  case Key of
    VK_UP:   dy := -1;
    VK_DOWN: dy := +1;
    VK_Left: dx := -1;
    VK_RIGHT: dx := +1
  else
    Exit;
  end;
  // Testendruck nicht an anderer Stelle weiter verarbeiten
  Key := 0;

  lNewPos := MyImage.BoundsRect;
  OffsetRect(lNewPos, dx, dy);
  DoPosChanging(MyImage, lNewPos);
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:58 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