|
Вопрос # 2 522/ вопрос открыт / |
|
Здравствуйте, эксперты! Помогите пожалуйста! У меня есть два шарика и они движутся по форме, а как мне сделать что бы они сталкивались и отлетали друг от друга?
К вопросу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки вопроса)
Приложение: Переключить в обычный режим- unit Unit1;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, ExtCtrls, StdCtrls;
-
- type
- TForm1 = class(TForm)
- Timer1: TTimer;
- procedure FormPaint(Sender: TObject);
- procedure Timer1Timer(Sender: TObject);
- procedure FormDragOver(Sender, Source: TObject; X, Y: Integer;
- State: TDragState; var Accept: Boolean);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
- DvigX=(L,R);
- DvigY=(U,D);
- DvigV=(Ld,Rd);
- DvigB=(Ud,Dd);
- var
- Form1: TForm1;
- XDvig:DvigX;
- YDvig:Dvigy;
- VDvig:DvigV;
- BDvig:Dvigb;
- x,y,v,b:integer;
- h,k:integer;
- implementation
-
- {$R *.dfm}
-
- procedure TForm1.FormPaint(Sender: TObject);
- begin
-
- with Canvas do
- begin
- Pen.Color:=clGreen;
- Brush.Color:=clYellow;
- Ellipse(v-20,b-20,v+20,b+20);
- end;
-
-
- with Canvas do
- begin
- Pen.Color:=clblack;
- Brush.Color:=clfuchsia;
- Ellipse(x-20,y-20,x+20,y+20);
- end;
-
-
-
-
- end;
-
- procedure TForm1.Timer1Timer(Sender: TObject);
- begin
- h:=10; k:=20;
- case xDvig of
- R: x:=x+h;
- L: x:=x-h;
- end;
- case yDvig of
- U: y:=y-h;
- D: y:=y+h;
- end;
-
- case vDvig of
- Rd: v:=v+k;
- Ld: v:=v-k;
- end;
- case bDvig of
- Ud: b:=b-k;
- Dd: b:=b+k;
- end;
-
- if v-25<0 then
- vDvig:=Rd;
- if v+25>form1.ClientWidth then
- vDvig:=Ld;
- if b-25<0 then
- bDvig:=Dd;
- if b+25>form1.ClientHeight then
- bDvig:=Ud;
-
-
- if x-25<0 then
- xDvig:=R;
- if X+25>form1.ClientWidth then
- xDvig:=L;
- if y-25<0 then
- yDvig:=D;
- if y+25>form1.ClientHeight then
- yDvig:=U;
-
- repaint;
- end;
-
- procedure TForm1.FormDragOver(Sender, Source: TObject; X, Y: Integer;
- State: TDragState; var Accept: Boolean);
- begin
- Accept:=true;
- end;
-
- end.
-
 |
Вопрос задал: 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
|
Мини-форум вопроса
Мини-форум пуст.
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|