Цитата:
Задание: Даны два шарика диаметром M. Промоделировать движение шариков по всей плоскости экрана. Шарики могут двигаться по прямым линиям. Изменение угла движения после столкновения с границей экрана или друг с другом может быть случайной величиной. Шарик не может вылететь за пределы квадрата. Пользователь может варьировать скорости движения шариков с помощью стрелок управления курсором.
Технические требования: Значение M (50<M<100) хранятся в файле Input.txt. Квадрат располагается в центре экрана. В левой или правой части экрана отображается количество столкновений шариков друг с другом и их скорости. Управление игрой осуществляется с помощью клавиатуры. Предусмотреть запись количества столкновений в файл Output.txt.
|
Создание шаров:
Код:
procedure TForm1.FormCreate(Sender: TObject);
Var i:Integer;
S:Tstrings;
begin
k:=0;
S:=TStringlist.Create;
S.LoadFromFile('input.txt');
M:=StrToInt(S.Strings[0]);
for i:=0 to MaxBalls-1 do
begin
balls[i].Sh:=TShape.Create(self);
balls[i].Sh.Shape:=stCircle;
balls[i].Sh.Left:=3*i*100+110;
balls[i].Sh.Top:=100+random(100);
balls[i].Sh.Parent:=self;
balls[i].Sh.Width:=M;
balls[i].Sh.Height:=M;
randomize;
balls[i].StepX:=RandomRange(-3,3);
balls[i].Stepy:=RandomRange(-6,0);
balls[i].Sh.Brush.Color:=clWhite;
end;
end;
Движение шаров:
Код:
Function Rasst(x1,x2,y1,y2 :real):real;
begin
Result:=Sqrt(Sqr((x1)-(x2)) + Sqr((y1)-(y2)));
end;
procedure TForm1.Timer1Timer(Sender: TObject);
Var i,j:Integer;
g,sk1,sk2:Real;
begin
g:=M/2;
For i:=0 to MaxBalls-1 do
begin
For j:=0 to MaxBalls-1 do
begin
if (i<>j)and (Rasst(balls[i].Sh.Left,balls[j].Sh.Left,balls[i].Sh.Top,balls[j].Sh.Top)<=M)
then
BEGIN
k:=k+1;
balls[i].StepX:=-balls[i].StepX;
balls[i].Stepy:=-balls[i].StepY;
balls[j].StepX:=-balls[j].StepX;
balls[j].Stepy:=-balls[j].StepY;
Label4.Caption:=IntToStr(k);
END;
end;
if ((balls[i].Sh.Left+M)>(Shape1.width+23))or
(balls[i].Sh.Left<26) then balls[i].StepX:=-balls[i].StepX;
if ((balls[i].Sh.Top+M)>(Shape1.Height+23))or
(balls[i].Sh.Top<26) then balls[i].StepY:=-balls[i].StepY;
balls[i].Sh.Left:=balls[i].Sh.Left+balls[i].StepX;
balls[i].Sh.Top:=balls[i].Sh.Top+balls[i].StepY;
balls[i].Sh.Update;
end;
sk1:=Rasst(balls[0].Sh.Left,balls[0].Sh.Left+balls[0].StepX,balls[0].Sh.Top,balls[0].Sh.Top+balls[0].StepY);
Label2.Caption:=floattostrf(sk1+1,ffFixed,0,0);
sk2:=Rasst(balls[1].Sh.Left,balls[1].Sh.Left+balls[1].StepX,balls[1].Sh.Top,balls[1].Sh.Top+balls[1].StepY);
Label6.Caption:=floattostrf(sk2+1,ffFixed,0,0);
end;
Изменение скорости по нажатию клавиш:
Код:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var n,i:Integer;
begin
n:=3;
case key of
38:
for i:=0 to MaxBalls-1 do
begin
if balls[i].StepX >=0
then balls[i].StepX:=balls[i].StepX+n
else balls[i].StepX:=balls[i].StepX-n;
if balls[i].StepY >=0
then balls[i].StepY:=balls[i].StepY+n
else balls[i].StepY:=balls[i].StepY-n;
end;
40:
for i:=0 to MaxBalls-1 do
begin
if balls[i].StepX >=0
then balls[i].StepX:=balls[i].StepX-n
else balls[i].StepX:=balls[i].StepX+n;
if balls[i].StepY >=0
then balls[i].StepY:=balls[i].StepY-n
else balls[i].StepY:=balls[i].StepY+n;
end;
end;
end;
Сохранение количества столкновений шариков в файл:
Код:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var F:TextFile;
s1:string;
begin
s1:='Шарики столкнулись '+IntToStr(k)+' раз(а).';
AssignFile(F,'output.txt');
Rewrite(F);
Writeln(F,s1);
CloseFile(F);
end;
Проблемы:
1. Шарики время от времени вылетают за границы квадрата.
2. При столкновении шарики отклоняются не на случайный угол.
3. При столкновении происходит как бы зацикливание и шарики сталкиваются ~100 раз подрят, хотя должны просто отскачить друг от друга.