Постановка задачи
Дана квадратная область, из центра которой происходит колебательное движение шариков. Каждый шарик характеризуется цветом, размером, азимутом и скоростью движения. При достижении шариком границы области, он начинает двигаться к центру; при достижении центра – к границам области. Провести отображение движения шариков. Предусмотреть возможность изменения их параметров, а также добавление и удаление шариков без остановки процесса движения.
Выделение перечня наиболее важных структур данных
TBall=record { шар, со всеми своими параметрами }
Azimut:integer;
Razmer:integer;
Koord:TPoint;
Color:TColor;
Scorost:byte;
flag:shortint;
end;
BegTime:TDateTime; { переменная необходима для работы со временем }
Form1: TForm1; { форма }
Cells:array[1..120] of TBall; { массив для хранения информации о шарах}
Count,i:byte; { счётчики, буферные переменные }
Mas:array[0..15] of Tcolor; { массив для задания цвета кривой }
ss:string; { строковая переменная }
ff:file of TBall; { переменная для работы с файлом }
Построение алгоритма реализации
Алгоритм – блок-схема рисования шаров.
Рис1 – блок-схема рисования шаров
Процедура изменения параметров шара
procedure TForm1.BitBtn3Click(Sender: TObject);
var m:integer;
begin
Val(Edit1.Text,m,Err);
if (Err<>0) or (m<1) or (m>Count) then
begin
MessageDlg('Внимательней надо!',mtError,[mbOk],0);
Exit;
end;
Val(Edit2.Text,Cells[m].Azimut,Err);
if Err<>0 then
begin
MessageDlg('Внимательней надо!',mtError,[mbOk],0);
Exit;
end;
Cells[m].Razmer:=SpinEdit1.Value;
Cells[m].Color:=ColorBox2.Selected;
Cells[m].Scorost:=SpinEdit2.Value+1;
end;
Процедура добавления шара
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if Count<120 then
begin
randomize;
inc(Count);
Cells[Count].Azimut:=Random(360);
Cells[Count].Razmer:=9+Random(15);
Cells[Count].Color:=ColorBox1.Selected;
Cells[Count].Koord.X:=Image1.Width div 2;
Cells[Count].Koord.Y:=Image1.Height div 2;
Cells[Count].Scorost:=2+Random(5);
Cells[Count].flag:=1;
end;
end;
Процедура удаления шара
procedure TForm1.BitBtn2Click(Sender: TObject);
var m:integer;
begin
Val(Edit1.Text,m,Err);
if (Err<>0) or (m<1) or (m>Count) then
begin
MessageDlg('Внимательней надо!',mtError,[mbOk],0);
Exit;
end;
Cells[m].flag:=0;
Image1.Canvas.Pen.Color:=clCream;
Image1.Canvas.Brush.Color:=clCream;
Image1.Canvas.Ellipse(Cells[m].Koord.X-Cells[m].Razmer,Cells[m].Koord.Y-Cells[m].Razmer,
Cells[m].Koord.X+Cells[m].Razmer,Cells[m].Koord.Y+Cells[m].Razmer);
Exit;
end;
Начало программы – задание начальной информации о шарах
procedure TForm1.FormCreate(Sender: TObject);
var buf,i:byte;
Mas:array[0..15] of TColor;
begin
Mas[0]:=clMenu;
Mas[1]:=clRed;
Mas[2]:=clGreen;
Mas[3]:=clBlue;
Mas[4]:=clGray;
Mas[5]:=clYellow;
Mas[6]:=clMoneyGreen;
Mas[7]:=clLime;
Mas[8]:=clOlive;
Mas[9]:=clMaroon;
Mas[10]:=clSkyBlue;
Mas[11]:=clAqua;
Mas[12]:=clTeal;
Mas[13]:=clSilver;
Mas[14]:=clPurple;
Mas[15]:=clFuchsia;
randomize;
Count:=0;
for i:=1 to 25 do
begin
buf:=random(2);
if buf=0 then
begin
inc(Count);
Cells[Count].Azimut:=Random(360);
Cells[Count].Razmer:=9+Random(17);
Cells[Count].Color:=Mas[random(16)];
Cells[Count].Koord.X:=Image1.Width div 2;
Cells[Count].Koord.Y:=Image1.Height div 2;
Cells[Count].Scorost:=2+Random(5);
Cells[Count].flag:=1;
end;
end;
BegTime:=Time;
Timer1.Enabled:=True;
end;
Процедура рисования шаров
procedure TForm1.Timer1Timer(Sender: TObject);
var R:integer;
h,m,s,ms:word;
i:byte;
begin
Ris;
DecodeTime(Time-BegTime,h,m,s,ms);
for i:=1 to Count do
if Cells[i].flag<>0 then
begin
R:=round(Cells[i].Scorost*ms) div 18;
Cells[i].Koord.X:=Cells[i].Koord.X+Cells[i].flag*round(cos(Cells[i].azimut*pi/180)*R);
Cells[i].Koord.Y:=Cells[i].Koord.Y+Cells[i].flag*round(sin(Cells[i].azimut*pi/180)*R);
if (Cells[i].Koord.X>=Image1.Width-Cells[i].Razmer) or
(Cells[i].Koord.Y>=Image1.Height-Cells[i].Razmer) or
(Cells[i].Koord.X<=Cells[i].Razmer) or (Cells[i].Koord.Y<=Cells[i].Razmer) then
if Cells[i].flag=1 then Cells[i].flag:=-1 else Cells[i].flag:=1;
Image1.Canvas.Pen.Color:=Cells[i].Color;
Image1.Canvas.Brush.Color:=Cells[i].Color;
Image1.Canvas.Ellipse(Cells[i].Koord.X-Cells[i].Razmer,Cells[i].Koord.Y-Cells[i].Razmer,
Cells[i].Koord.X+Cells[i].Razmer,Cells[i].Koord.Y+Cells[i].Razmer);
ss:=IntToStr(i);
if Cells[i].Color=clBlue then Image1.Canvas.Font.Color:=clWhite
else Image1.Canvas.Font.Color:=clBlack;
Image1.Canvas.TextOut(Cells[i].Koord.X-Image1.Canvas.TextWidth(ss) div 2,
Cells[i].Koord.Y-Image1.Canvas.TextHeight(ss) div 2,ss);
end;
BegTime:=Time;
end;
Процедура выхода из программы
procedure TForm1.N4Click(Sender: TObject);
begin
Halt(1);
end;
Процедура сохранения информации в файле
procedure TForm1.N2Click(Sender: TObject);
begin
if SaveDialog1.Execute then
begin
AssignFile(ff,SaveDialog1.FileName);
Rewrite(ff);
for i:=1 to Count do
write(ff,Cells[i]);
CloseFile(ff);
end;
end;
Процедура открытия файла
procedure TForm1.N3Click(Sender: TObject);
begin
if OpenDialog1.Execute and FileExists(OpenDialog1.FileName) then
begin
AssignFile(ff,OpenDialog1.FileName);
Reset(ff);
Count:=0;
While not Eof(ff) do
begin
inc(Count);
read(ff,Cells[Count]);
end;
CloseFile(ff);
end;
end;
Процедура вывода сообщения «О программе»
procedure TForm1.N6Click(Sender: TObject);
begin
MessageDlg('Программа рисует шарики, которые скачут от стенки к стенке через центр',mtInformation,[mbOk],0);
end;
Описание математического аппарата
Применяем формулу y = k*sin(a*x+t), где: x лежит в пределах 0+-180° с шагом 1°; t – время, прошедшее с начала отображения в секундах; k, a – коэффициенты, изменение которых возможно в процессе отображения.
Обоснование выбора визуальных компонентов
Воспользуемся компонентами следующих классов:
1) TTimer, потому что движение шаров происходит не только на плоскости, но и во времени.
2) TImage, на котором рисуем
3) TEdit, TSpinEdit и TColorBox для ввода данных
4) TLabel, чтобы отображать информацию
5) TButton, чтобы изменять, добавлять и удалять шарики по нажатии определённой кнопки
6) TMainMenu для работы с меню
7) TOpenDialog и TSaveDialog, чтобы можно было открывать и сохранять файлы.
Структура диалогов
Фрагмент листинга программы, где производится обработка ошибок:
Val(Edit1.Text,m,Err);
if (Err<>0) or (m<1) or (m>Count) then
begin
MessageDlg('Внимательней надо!',mtError,[mbOk],0);
Exit;
end;
Т. е., если в качестве параметров введено не число или такого шара нет – выдаём сообщение об ошибке.
Инструкция по использованию программы
При запуске программы сразу же рисуются шарики. Очень красиво.
Добавлять новые шарики, удалять старые, изменять параметры можно прямо во время движения шаров, сколько угодно раз.
При выборе в меню File->Save, можно сохранить файл с текущими параметрами, потом загрузить их можно, выбрав File->Open.
При выборе в меню File->Exit – программа завершит свою работу.
При выборе в меню Help->About Program – выдаётся сообщение о программе.
На рис. 2 показан фрагмент работы программы, окна сохранения и загрузки файлов.
Рис. 2 – работа программы
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.