Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 2 522

/ вопрос открыт /

Здравствуйте, эксперты! Помогите пожалуйста! У меня есть два шарика и они движутся по форме, а как мне сделать что бы они сталкивались и отлетали друг от друга?

К вопросу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки вопроса)

Приложение:
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7. Dialogs, ExtCtrls, StdCtrls;
  8.  
  9. type
  10. TForm1 = class(TForm)
  11. Timer1: TTimer;
  12. procedure FormPaint(Sender: TObject);
  13. procedure Timer1Timer(Sender: TObject);
  14. procedure FormDragOver(Sender, Source: TObject; X, Y: Integer;
  15. State: TDragState; var Accept: Boolean);
  16. private
  17. { Private declarations }
  18. public
  19. { Public declarations }
  20. end;
  21. DvigX=(L,R);
  22. DvigY=(U,D);
  23. DvigV=(Ld,Rd);
  24. DvigB=(Ud,Dd);
  25. var
  26. Form1: TForm1;
  27. XDvig:DvigX;
  28. YDvig:Dvigy;
  29. VDvig:DvigV;
  30. BDvig:Dvigb;
  31. x,y,v,b:integer;
  32. h,k:integer;
  33. implementation
  34.  
  35. {$R *.dfm}
  36.  
  37. procedure TForm1.FormPaint(Sender: TObject);
  38. begin
  39.  
  40. with Canvas do
  41. begin
  42. Pen.Color:=clGreen;
  43. Brush.Color:=clYellow;
  44. Ellipse(v-20,b-20,v+20,b+20);
  45. end;
  46.  
  47.  
  48. with Canvas do
  49. begin
  50. Pen.Color:=clblack;
  51. Brush.Color:=clfuchsia;
  52. Ellipse(x-20,y-20,x+20,y+20);
  53. end;
  54.  
  55.  
  56.  
  57.  
  58. end;
  59.  
  60. procedure TForm1.Timer1Timer(Sender: TObject);
  61. begin
  62. h:=10; k:=20;
  63. case xDvig of
  64. R: x:=x+h;
  65. L: x:=x-h;
  66. end;
  67. case yDvig of
  68. U: y:=y-h;
  69. D: y:=y+h;
  70. end;
  71.  
  72. case vDvig of
  73. Rd: v:=v+k;
  74. Ld: v:=v-k;
  75. end;
  76. case bDvig of
  77. Ud: b:=b-k;
  78. Dd: b:=b+k;
  79. end;
  80.  
  81. if v-25<0 then
  82. vDvig:=Rd;
  83. if v+25>form1.ClientWidth then
  84. vDvig:=Ld;
  85. if b-25<0 then
  86. bDvig:=Dd;
  87. if b+25>form1.ClientHeight then
  88. bDvig:=Ud;
  89.  
  90.  
  91. if x-25<0 then
  92. xDvig:=R;
  93. if X+25>form1.ClientWidth then
  94. xDvig:=L;
  95. if y-25<0 then
  96. yDvig:=D;
  97. if y+25>form1.ClientHeight then
  98. yDvig:=U;
  99.  
  100. repaint;
  101. end;
  102.  
  103. procedure TForm1.FormDragOver(Sender, Source: TObject; X, Y: Integer;
  104. State: TDragState; var Accept: Boolean);
  105. begin
  106. Accept:=true;
  107. end;
  108.  
  109. end.
  110.  


Kraken Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Kraken (статус: Посетитель)
Вопрос отправлен: 14 марта 2009, 19:49
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, Kraken!
Всё достаточно просто. надо в начало процедуры рисования вставить кусочек кода, который проверяет их на столкновение.

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  h:=10;  k:=20;
 
  if (sqrt(sqr(x - v) + sqr (y - b)) <= 40) then
  begin
    if xDvig = R then xDvig := L else xDvig := R;
    if yDvig = U then yDvig := D else yDvig := U;
    if vDvig = Rd then vDvig := Ld else vDvig := Rd;
    if bDvig = Ud then bDvig := Dd else bDvig := Ud;
  end;  
// дальше Ваш код
проверка - это банальная школьная формула для определения расстояния между двумя точками. Геометрия 7-8 класс.
число 40 - это сумма радиусов двух шариков.
Вторая часто кода - это уже чистая физика - при соударении одинаковых упругих тел они просто меняют вектор движения на противоположный - то есть просто нужно поменять знак:)
Правда если запустить код и понаблюдать, то иногда наблюдается эффект, что шарики либо накладываются друг на дружку, либо отталкиваются слишком рано. Это всё по причине большого шага h и k. Достаточно их уменьшить до 1 и 2, как всё стает красиво.
Можно конечно пойти более красивее - расчитывать, не соударились ли шарики и не соударяться ли они на следующем шаге. И если это так, то просчитать точку соударения и новые координаты.
Но во первых это надо посидеть с карандашом и посчитать.
А во вторых, в таком стиле, как вы пишете код, это будет сложно вписать. Я бы к примеру не вводил понятия движения вверх/вниз, а просто бы играл знаком шага. код бы упростился на половину. Следующее, что бы я сделал - это класс "шарик".
И! выкладывать исходники в ворде - ужасно!

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 14 марта 2009, 20:34


Мини-форум вопроса

Мини-форум пуст.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:28
Выполнено за 0.03 сек.