Консультация № 175884
07.01.2010, 03:31
0.00 руб.
0 11 1
Здраствуйте Уважаемые эксперты. Помогите написать одну вещь. А именно:
У меня на форме есть два компонента TImage - Image1, Image2.
Они двигаются по диагонали. Я хочу сделать так, чтобы при столкновении они друг от друга отскакивали. Как они отскакивают я уже написал. Работает нормально. Но со столкновением не могу разобраться. Очень долго сидел, но зачастую добивался только того, что они когда уже пролетят друг через друга срабатывает действие.
Я прошу помочь прописать именно момент столкновения. Как в сравненнии изобразить все это, а именно каждую ситуацию столкновения, сверху снизу, слева справа, не зависимо от того толи то Image1 задела Image2 или наоборот.
Для того чтобы это прописать нужно знать размеры компонентов.
У обоих компонентов:
Width=33;
Height=33;

Вот мои наработки, но это вовсе не рабочий вариант. Хотя вроде бы некоторые ситуции предусмотрел.
if (((image1.left+33>=image2.left) and (image1.left+40<=image2.left))or ((image2.left+33>=image1.left) and (image2.left+40<=image1.left)) ) And (((image1.top+50>=image2.top) and (image1.top+80<=image2.top)) or ((image2.top>=image1.top+50) and (image2.top+80<=image1.top))) then
...
Конечно я мог ошибиться в самой логике. Поэтому прошу вас помочь доработать код.
Заранее благодарен.

Обсуждение

Неизвестный
07.01.2010, 11:05
общий
Условие по-моему должно быть таким:

if ((Image1.Top+Image1.Height>=Image2.Top) and (Image1.Top<=Image2.Top) or (Image2.Top+Image2.Height>=Image1.Top) and (Image2.Top<=Image1.Top)) and ((Image1.Left+Image1.Width>=Image2.Left) and (Image1.Left<=Image2.Left) or (Image2.Left+Image2.Width>=Image1.Left) and (Image2.Left<=Image1.Left)) Then

Попробуйте, и напишите если правильно (оформлю ответ), а то проверить нету времени. :(
Неизвестный
07.01.2010, 11:44
общий
Супер! Отлично работает!
Оформляйте ответ.
Неизвестный
08.01.2010, 12:06
общий
Тимошенко Дмитрий:
Хотя одна проблемка. При столкновении с боков условие работает хорошо, но когда по диагонали углами сталкиваются то проходят друг через друга.
Тоесть:
Неизвестный
08.01.2010, 16:01
общий
Странно. Должно вроде срабатывать. А с любого угла так происходит, или только с определенного? Можете проверить?
Неизвестный
08.01.2010, 16:11
общий
Только что проверил: Именно так как я показал не работает. В других случаях зачастую срабатывает.
Неизвестный
08.01.2010, 16:37
общий
А где на картинке Image1 и Image2? И дайте еще кусок кода, где у вас столкновение обрабатывается.
И еще одно: столкновение вообще не срабатывает, или срабатывает, но позже?
Неизвестный
09.01.2010, 09:56
общий
Код:
if ((I1.Top+I1.Height>=I2.Top) and (I1.Top<=I2.Top) or (I2.Top+I2.Height>=I1.Top) and (I2.Top<=I1.Top)) and ((I1.Left+I1.Width>=I2.Left) and (I1.Left<=I2.Left) or (I2.Left+I2.Width>=I1.Left) and (I2.Left<=I1.Left)) Then
begin
if i2.Height<100 then begin
if l[i]=1 then begin l[i]:=0; l[j]:=1; r[i]:=1; r[j]:=0;end;
if l[i]=0 then begin l[i]:=1; l[j]:=0; r[i]:=0; r[j]:=1;end;
end;

Это функция. В нее передаю две картинки - I1, I2.
Элемент массива u[1] отвечает за то что картинка по таймеру двигается вверх,
d[1]-вниз,l[1]-влево,l[1]-вправо. u[2],d[2],l[2],r[2] отвечает за движение второй картинки таким же образом.
Вроде бы как бы там не было при том случае, что я показал всегда проходят.
I1 через I2.
Неизвестный
09.01.2010, 09:57
общий
Это условие выполняется всегда. Так как я его размер увеличивать могу самостоятельо только.
Вначале он 41.
Неизвестный
09.01.2010, 12:50
общий
У вас проблема где-то в остальном коде. Только что проверил условие и смоделировал вашу ситуацию - условие отлично срабатывает.
По приведенному куску можно сказать, что проблема может быть во втором условии if i2.Height<100 then begin, либо в индексах i, j, либо ваша функция проверки не всегда вызывается. Но это все гадание на кофейной гуще - подробнее сказать сложно не видя вашего кода.
Неизвестный
09.01.2010, 22:45
общий
Тимошенко Дмитрий:
Отлично. Я еще просмотрю код.
Оформляйте ответ. Вы мне здорово помогли.
Неизвестный
10.01.2010, 08:33
общий
это ответ
Здравствуйте, Dimon4ik.

Условие проверки должно быть таким:

if ((Image1.Top+Image1.Height>=Image2.Top) and (Image1.Top<=Image2.Top) or (Image2.Top+Image2.Height>=Image1.Top) and (Image2.Top<=Image1.Top)) and ((Image1.Left+Image1.Width>=Image2.Left) and (Image1.Left<=Image2.Left) or (Image2.Left+Image2.Width>=Image1.Left) and (Image2.Left<=Image1.Left)) Then ...

Первые четыре сравнения проверяют пересечение картинок по вертикали, другие четыре - по горизонтали. (Для срабатывания должны выполняться оба блока). Первые два из четырех учитывают ситуацию, когда Image1 выше/левее Image2, а вторые соответственно, когда Image2 выше/левее Image1. (Должна выполняться хотя бы одна пара условий).

С уважением, Дмитрий
5
Отличное условие, все работает! Спасибо.<br>Отличный ответ!
Форма ответа