| 
| 
 | Вопрос # 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
 
 |  
 Мини-форум вопросаМини-форум пуст. Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |