Link to home
Start Free TrialLog in
Avatar of Jai Sewell
Jai Sewell

asked on

Multiple image collision

Hi all,
 Back to ask another Delphi question.
Suppose i have four or more moving images on a form (panel or whatever) that are moving from the bottom of the form to the top, once they go off screen (cannot be seen anymore) they have their Top positions reset to a random value that is between the areas of the bottom most part of the form and some large number (that way the images appear at differing time intervals upon the visible part of the form), at the same time as their top positions are reset, they also have their Left property set a random value...
Now the trouble is, sometimes these images will overlap and one will be on top of the other!, i need some method of detecting this and then correcting it by assigning a new Top and Left property to the image/s

How is collision detection done with multiple images?.
two images are fine you just check
 "if (image1.top <= image2.top +image2.height) and (image1.top >= image2.top) then"
and if these conditions are met you can simply execute
 "image2.top := image1.top +(image1.height +10)"
but things get more complicated with multiple images, as you need to check the condition of each individual image and then when you change the Top and Left properties of one image you must recheck the values of all other images AGAIN to make sure that the new Top and Left values of the image you just moved do not collide with yet another image!.
Avatar of Eddie Shipman
Eddie Shipman
Flag of United States of America image

It is better to tell if the images overlap than attempting to keep track of where they are.
See how it is done with balls in the java screen saver code in the selected answer here:
http://stackoverflow.com/questions/19588605/simple-bouncing-ball-program-in-java
You know all the top and left of the objects.
Look in the controls property of the form

No need for collission detection.

You could use Ptinrect to check a point
Avatar of Jai Sewell
Jai Sewell

ASKER

So does that mean that...

if (Math.abs(x_pos2-x_pos1)<radius1+radius2){
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;
  }

becomes something like...

if ((Image2.Top-Image1.Top) < (Image1.Top +Image1.Height) +(Image2.Top +Image2.Height)) then
 begin
  Image2.Top := Image1.Top +Image1.Height +10;
 end;

And if so, i must also then account for when Image3 overlaps Image4, Image2 and Image1...
Image4 must also be checked against Image1, Image2 and Image3...
Then Image1 must be checked against Image3 and Image4
While Image2 is also checked against Image3 and Image4
I had a bit of an idea and i punched together the following code...
Please let me know what you guys think :)

procedure CheckOverlap;
var X, Y: integer;
ChkImage, RefImage: TImage;
begin
for X := 1 to 4 do
 begin
  ChkImage := FindComponent('Image' +IntToStr(X)) as TImage;
  for Y := 1 to 4 do
   begin
    if Y <> X then
     begin
      RefImage := FindComponent('Image' +IntToStr(Y)) as TImage;
      if (ChkImage.Top >= RefImage.Top) and ( (ChkImage.Top) <= (RefImage.Top +RefImage.Height) ) then
       begin
        ChkImage.Top := (RefImage.Top +RefImage.Height) +10;
       end
     end
   end
 end

Open in new window

always +10 ?
that means you're always moving the item down ?
Yes it does mean that the image is always moved down if it overlaps any other image (it wont move otherwise), that is because all the images are lined up off screen (outside of the visible area on the form, so that when they do appear on the form they are all lined up perfectly, oooh i should note that the images slowly scroll up from the bottom of the form to the top) and that is for the code above, i have since modified the code too allow for moving to the right with the Left property.

procedure TMain.CheckOverlap;
var X, Y: integer;
ChkImage, RefImage: TImage;
begin
for X := 1 to 4 do
 begin
  ChkImage := FindComponent('island' +IntToStr(X)) as TImage;
  for Y := 1 to 4 do
   begin
    if Y <> X then
     begin
      RefImage := FindComponent('island' +IntToStr(Y)) as TImage;
      if (ChkImage.Top >= RefImage.Top) and ( (ChkImage.Top) <= (RefImage.Top +RefImage.Height) ) then
       begin
        if RefImage.Left +RefImage.Width <= 307 then ChkImage.Left := (RefImage.Left +RefImage.Width) +10
        else ChkImage.Top := (RefImage.Top +RefImage.Height) +10;
       end
     end
   end
 end
end;

Open in new window

why is the overlap a problem ?
Because it does not look right, (the images have transparent properties and you can see one image "ghosting" in through the other and it becomes extremely pixelated.
I will try to attach a screen dump of this using the Attach File link, i have never used it before, so lets see how it goes :)
User generated image
May I suggest a matrix of TPoint type. Take one random object (image) with property of Width and Height into one TPoint and set to first position in a matrix. Then get second random object from a list and so on... When you take all objects - calculate position for each of them...
Matrix:
O1  O2  O3
O4  O5  O6
X position of Object1 is random value from 0 ... (<width of screen> - <sum of Width of all remain objects in a row inc. Object1>)
X position of Object2 is random value from (<pos. of obj1>+<width of obj1>) ...  (<width of screen> - <sum of Width of all remain objects in a row  inc. Object2>)
...

Y position calculate same/similar way...
----
Why I subtract <width of screen> and <sum of Width of all remain objects in a row  inc. ObjectX>?
Because I need to be sure that I will have enough room for all next objects. You can add more space around object if want.
Got any code to go with that Sinisa?
have you seen the movie Avatar ?
Change the islands to floating islands like those from Avatar

It would look better and then they can float above one another.

you'll have to calculate in 3 dimensions then ...
Yeah nope, i am not planning to make money from this and if i wanted something more graphical i would use unity and 3D studio max
ASKER CERTIFIED SOLUTION
Avatar of Sinisa Vuk
Sinisa Vuk
Flag of Croatia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial