unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, Math; type Molecule = record X, Y: Integer; Vx, Vy: Integer; end; { TForm1 } TForm1 = class(TForm) StartStopBtn: TButton; Screen: TPaintBox; procedure StartStopBtnClick(Sender: TObject); procedure ScreenPaint(Sender: TObject); private const R: Integer = 10; { Радиус молекулы } V: Integer = 7; { Максимальная скорость молекулы } N = 30; { Количество молекул } var Mol: array[1..N] of Molecule; { Массив молекул } public end; var Form1: TForm1; IsRunning: Boolean = false; implementation {$R *.lfm} { TForm1 } procedure TForm1.ScreenPaint(Sender: TObject); var i: Integer; begin if not IsRunning then Exit; for i := 1 to N do { Цикл по всем молекулам } begin Screen.Canvas.Pen.Color := clBtnFace; { Стираем молекулу } Screen.Canvas.Ellipse(Mol[i].X - R, Mol[i].Y - R, Mol[i].X + R, Mol[i].Y + R); Mol[i].X := Mol[i].X + Mol[i].Vx; { Сдвигаем на новую позицию } Mol[i].Y := Mol[i].Y + Mol[i]. Vy; { Определяем, не вышла ли молекула за границы аквариума } if Mol[i].X > Screen.Width - R then begin Mol[i].X := Screen.Width - R; Mol[i].Vx := -Mol[i].Vx; end; if Mol[i].X < R then begin Mol[i].X := R; Mol[i].Vx := -Mol[i].Vx; end; if Mol[i].Y > Screen.Height - R then begin Mol[i].Y := Screen.Height - R; Mol[i].Vy := -Mol[i].Vy; end; if Mol[i].Y < R then begin Mol[i].Y := R; Mol[i].Vy := -Mol[i].Vy; end; Screen.Canvas.Pen.Color := clBlue; { Рисуем молекулу на новой } Screen.Canvas.Ellipse(Mol[i].X - R, Mol[i].Y - R, { позиции } Mol[i].X + R, Mol[i].Y + R); end; end; procedure TForm1.StartStopBtnClick(Sender: TObject); var angle: Real; { Угол, задающий изначальное направление полета } i: Integer; { Счетчик цикла } CurV: Integer; { Выбранная случайная скорость молекулы } begin if IsRunning then begin IsRunning := false; StartStopBtn.Caption := 'Пуск'; Exit; end; StartStopBtn.Caption := 'Стоп'; IsRunning := true; Randomize; for i := 1 to N do { Цикл по всем молекулам } begin Mol[i].X := RandomRange(R, Screen.Width - R); { Выбор начального } Mol[i].Y := RandomRange(R, Screen.Height - R); { положения молекулы } angle := Random(360) * Pi / 180; { и ее направления } CurV := RandomRange(1, V); { Выбор скорости молекулы (1 - V) } Mol[i].Vx := Round(CurV * Sin(angle)); { Получение составляющих } Mol[i].Vy := Round(CurV * Cos(angle)); { скорости молекулы } end; while IsRunning do { Основной цикл } begin Screen.Invalidate; Sleep(10); { Пауза на 10 миллисекунд } Application.ProcessMessages; if Application.Terminated then Break; end; end; end.