Entwickler-Ecke

Multimedia / Grafik - 2 Image überschneiden sich


manfred07 - Mo 25.04.05 02:17
Titel: 2 Image überschneiden sich
Hallo DF,

ich hoffe das Ihr mir weiter Helfen könnt, ich wollte
wenn sich 2 Image überschneiden das sich die Image die sich bewegt hat
neben der stehenden Image stehen bleibt. Das habe ich auch so weit fertig....
glaub ich jedenfalls :roll:
Nun möchte ich aber 20 Image verteilen und möchte jetzt nicht alle Möglichkeiten
durch programmieren. Die Image sollen sich nur Links, Rechts, Oben und Unten bewegen
können.
Nun meine Frage gibt es eine andere Möglichkeit das hin zubekommen?
Hier mal ein Code wie ich es so weit fertig habe für eine Image die sich nach rechts bewegt.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
If ssRight in Shift then begin

Image1.Left:=Image1.Left +50;
If (Image1.Top = Image2.Top)and ((Image1.Left+Image1.Width)>Image2.left)or(Image1.Top-50 = Image2.Top)and ((Image1.Left+Image1.Width)>Image2.left)or(Image1.Top-100 = Image2.Top) and ((Image1.Left+Image1.Width)>Image2.left) then begin
   Image1.Left:=Image2.left - Image1.Width;
   end;  end;



Würde mich freuen wenn Ihr mir weiter Helfen könnt

Gruß Manfred

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt.


Lossy eX - Mo 25.04.05 08:28

Benutz Schleifen!

Du kannst deine Images ein Array packen. Dann kannst du diese mit einer Schleife testen ob sich das Objekt welches du bewegen möchtest mit etwas anderem überschneidet.


Array
1:
2:
3:
4:
5:
var
  Blub: Array[0..19of TImage;
...
  Blub[0] := TImage.Create(Self);
  Blub[0].Parent := Self;



dynamisches Array
1:
2:
3:
4:
5:
6:
var
  Blub: Array of TImage;
...
  SetLength(Blub, Length(Blub) + 1);
  Blub[High(Blub)] := TImage.Create(Self);
  Blub[High(Blub)].Parent := Self;


Das Erstellen kannst du logischerweise auch in einer Schleife machen.


manfred07 - Mo 25.04.05 09:28

Hi Lossy eX,

danke schön für deine Hilfe!
Das mit der Schleife ist ja ne gute Lösung, aber ich muß da
ja auch alle Möglichkeiten einer Überschneidung durch prog.
Da muß es doch eine andere Lösung geben...... :cry: oder?


Gruß Manfred


Lossy eX - Mo 25.04.05 14:50

Du musst ja nachdem (oder auch bevor) du dein Element verschoben hast abprüfen ob eine Kollision statt gefunden hat (oder stattfinden wird). Ich denke mal, wenn du da 20 Elemente hast ist das alles andere als kritisch. Es wird bestimmt noch andere optimierte Lösungen geben aber in diesem Falle hast du höchstens 1-2 Millisekunden gut gemacht. Und ich denke mal nicht, dass das den entsprechend (überdimensionierten) Entwicklungsaufwand rechtfertigt. Viel interesannter wäre das bei 1000+ Elementen. Dann würde sich da ein wenig mehr Aufwand schon lohnen. Aber nicht bei 20.


manfred07 - Di 26.04.05 20:04

Hi Lossy eX,

na denn wird ich das mal so machen das ich für jedes Image die Abfrage
machen. Interessant wär es trotz allem gewesen :roll:
Hätte gerne gewußt wie man das halt macht.....man lernt ja nie aus :wink:

Habe es jetzt so gemacht,(siehe Code) und muß es halt für alle anderen Image
übernehmen, oder halt ändern für Top-bewegung. Habe aber ein Fehler drin den
ich nicht weg bekomme, und zwar wenn Image1 auf der linken Seite von Image2
steht und ich klicke mit der linken Maustaste springt mir Image1 auf die rechte
Seite von Image2. Siehst du den Fehler oder hast du eine andere Lösung?

Image1 Image2

Hier der Code:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
if ssRight in Shift then 
begin
image1.left:=Image1.Left +50;
If (Image1.Top = Image2.Top)and ((Image1.Left+Image1.Width)>Image2.left)or(Image1.Top-50 = Image2.Top)and ((Image1.Left+Image1.Width)>Image2.left)or(Image1.Top-100 = Image2.Top) and ((Image1.Left+Image1.Width)>Image2.left) then begin
   Image1.Left:=Image2.left - Image1.Width;
   end;  end;

if ssLeft in Shift then 
begin
image1.left:=Image1.Left -50;
If (Image1.Top = Image2.Top)and (Image1.Left<(Image2.left+Image2.Width))or(Image1.Top-50 = Image2.Top)and (Image1.Left<(Image2.left+Image2.Width))or(Image1.Top-100 = Image2.Top) and (Image1.Left<(Image2.left+Image2.Width)) then begin
//If (Image1.Top = Image2.Top) and ((Image1.Left+Image1.Width)<=Image2.left) then
   Image1.Left:=Image2.left + Image2.Width;
   endend;




Danke im voraus

Manfred

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt.


Lossy eX - Mi 27.04.05 09:16

Ähm. Irgendwie hast du mich nicht so ganz verstanden. Oder es war zu kompliziert. Ich habe das in etwa so gemeint.

Auf dem Formular befindet sich lediglich ein Button. Alles andere wird dynamisch erstellt.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    fImages: array [0..2of TImage;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function InRect(Rect1, Rect2: TRect): Boolean;
begin
  Result := False;
  // Diese Methode arbeitet nach dem ausschlussverfahren.
  // Es prüft also ob die Linke ecke des einen Recht außerhalb des anderen ligt.
  // Es kann nämlich auch sein, dass sich die Recteckte überlagern obwohl
  // keiner der Punkt in einem andern liegt. Siehe "bild".
  //     |--|
  //  ----------
  //  |        |
  //  ----------
  //     |--|
  if Rect1.Right < Rect2.Left then
    EXIT;

  if Rect1.Left > Rect2.Right then
    EXIT;

  if Rect1.Bottom < Rect2.Top then
    EXIT;

  if Rect1.Top > Rect2.Bottom then
    EXIT;

  // Okay. Wenn wir hier sind dann sind sie Kolliediert.
  Result := True;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  // Bilder erstellen
  fImages[0] := TImage.Create(Self);
  fImages[0].Parent := Self;
  fImages[0].Picture.LoadFromFile('C:\WINNT\kaffeetasse.bmp');
  fImages[0].AutoSize := True;
  fImages[0].Top := 5;
  fImages[0].Left := 5;

  fImages[1] := TImage.Create(Self);
  fImages[1].Parent := Self;
  fImages[1].Picture.LoadFromFile('C:\WINNT\kaffeetasse.bmp');
  fImages[1].AutoSize := True;
  fImages[1].Top := 200;
  fImages[1].Left := 200;

  fImages[2] := TImage.Create(Self);
  fImages[2].Parent := Self;
  fImages[2].Picture.LoadFromFile('C:\WINNT\kaffeetasse.bmp');
  fImages[2].AutoSize := True;
  fImages[2].Top := 395;
  fImages[2].Left := 395;
end;


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  Idx: Integer;
begin
  // Bilder wieder frei geben
  for Idx := Low(fImages) to High(fImages)
   do fImages[Idx].Free;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  Idx, MoveIdx : Integer;
begin
  // Bild bewegen
  MoveIdx := 0;
  fImages[MoveIdx].Top  := fImages[MoveIdx].Top + 50;
  fImages[MoveIdx].Left := fImages[MoveIdx].Left + 50;

  // Bilder auf kollision prüfen
  for Idx := Low(fImages) to High(fImages) do begin
    // Haben wir unser verschobenes
    if Idx <> MoveIdx then begin
      // auf Kollision abprüfen
      if InRect(fImages[Idx].BoundsRect, fImages[MoveIdx].BoundsRect) then
        ShowMessage('Wahhhhh');
    end;
  end;
end;


end.


PS: Du kannst die Bilder natürlich auch in einer Schleife erstellen und laden.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm1.FormCreate(Sender: TObject);
var
  Idx: Integer;
begin
  // Bilder erstellen
  for Idx := Low(fImages) to High(fImages) do begin
    fImages[Idx] := TImage.Create(Self);
    fImages[Idx].Parent := Self;
    fImages[Idx].Picture.LoadFromFile('C:\WINNT\kaffeetasse.bmp');
    fImages[Idx].AutoSize := True;
    fImages[Idx].Top := 5 + 195 * Idx;
    fImages[Idx].Left := 5 + 195 * Idx;
  end;
end;


manfred07 - Mi 27.04.05 17:15

Hi Lossy eX,

beides glaub ich :oops:
Danke dir, werde es mal ausprobieren und melde mich dann bei dir.

Gruß Manfred


manfred07 - Mi 27.04.05 19:23

Hi Lossy eX,

vielen Dank es haut alles hin :lol:
Mußte nur in der uses noch extctrls eintragen. :wink:

Danke nochmal für deine Hilfe

Gruß Manfred