unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls; type { TForm1 } TForm1 = class(TForm) StartStopBtn: TButton; Screen: TPaintBox; procedure ScreenPaint(Sender: TObject); procedure StartStopBtnClick(Sender: TObject); private const R: Integer = 10; { Радиус шара } Vx0: Integer = 3; { Горизонтальная скорость шара } a: Real = 1; { Ускорение } K: Real = 0.8; { Коэффицент потери } var X, Y: Integer; { Координаты шара } public end; var Form1: TForm1; IsRunning: Boolean = false; implementation {$R *.lfm} { TForm1 } procedure TForm1.StartStopBtnClick(Sender: TObject); var Vx, Vy: Real; { Состовляющие скорости } begin if IsRunning then begin IsRunning := false; StartStopBtn.Caption := 'Пуск'; Exit; end; StartStopBtn.Caption := 'Стоп'; IsRunning := true; Vy := 0; { Вертикальная состовляющая скорости изначально равна нулю } Vx := Vx0; X := R + 5; { Начальное } Y := Screen.Height div 2; { положение шара } Screen.Invalidate; Application.ProcessMessages; Sleep(500); { Пауза, чтобы увидеть начальное положение на экране } while IsRunning do { Основной цикл } begin { Screen.Canvas.Pen.Color := ClBtnFace; Screen.Canvas.Ellipse(X - R, Y - R, X + R, Y + R); } X := X + Round(Vx); { Сдвигаем на новую позицию } Y := Y + Round(Vy); if X > Screen.Width - R then { Если шар вышел за экран, "нажимаем" } Form1.StartStopBtnClick(nil); { кнопку StartStopBtn (1) } if Y > Screen.Height - R then { Если шар стокнулся с землей } begin { "Отражаем" - как в предыдущих моделях но скорость уменьшается в K раз если скорость стала по модулю (2) меньше единицы , "нажимаем" StartStopBtn } Y := Screen.Height - R; Vy := -Vy * K; if abs(Vy) < 1 then Form1.StartStopBtnClick(nil); end; Vy := Vy + a; { Изменяем скорость в соответствии с ускорением } Screen.Invalidate; Sleep(3); Application.ProcessMessages; end; end; procedure TForm1.ScreenPaint(Sender: TObject); var T, U: Integer; Vt, Vu: Real; begin if not IsRunning then Exit; Vu := 0; { Вертикальная состовляющая скорости изначально равна нулю } Vt := Vx0; T := R + 5; { Начальное } U := Screen.Height div 2; { положение шара } Screen.Canvas.Pen.Color := clBlack; { Рисуем "подставку" } Screen.Canvas.MoveTo(R + 5, Screen.Height div 2 + R); { на которой } Screen.Canvas.LineTo(R + 5, Screen.Height); { лежит шар } Screen.Canvas.Brush.Color := clBlue; Screen.Canvas.Brush.Style := bsSolid; Screen.Canvas.Pen.Color := clBlue; Screen.Canvas.Ellipse(T - R, U - R, T + R, U + R); { рисуем шар } while (T < X) or (U < Y) do begin T := T + Round(Vt); { Сдвигаем на новую позицию } U := U + Round(Vu); if T > Screen.Width - R then { Если шар вышел за экран, "нажимаем" } Form1.StartStopBtnClick(nil); { кнопку StartStopBtn (1) } if U > Screen.Height - R then { Если шар стокнулся с землей } begin { "Отражаем" - как в предыдущих моделях но скорость уменьшается в K раз если скорость стала по модулю (2) меньше единицы , "нажимаем" StartStopBtn } U := Screen.Height - R; Vu := -Vu * K; if abs(Vu) < 1 then Form1.StartStopBtnClick(nil); end; Vu := Vu + a; { Изменяем скорость в соответствии с ускорением } Screen.Canvas.Brush.Color := clBlue; Screen.Canvas.Brush.Style := bsSolid; Screen.Canvas.Pen.Color := clBlue; { рисуем шар на } Screen.Canvas.Pen.Style := psSolid;; Screen.Canvas.Ellipse(T - R, U - R, T + R, U + R); { новой позиции } end; end; end.