Программа
program Imitator(input,output);
{ Имитатор стрельбы по
горизонтальнолетящим целям }
Uses Crt,Graph; { Подключение модулей обработки консоли и графики }
Const
{ Параметры для начальной установки: }
mConst=1.5; { масса снаряда }
V0Const=1300; { начальная скорость снаряда }
dnConst=300; { радиус действия снаряда }
VtargetConst=1000; { скорость цели }
YtargetConst=8000; { высота цели }
LengthTarget=20; { длина цели (в точках монитора) }
HeightTarget=6; { высота цели (в точках монитора) }
kConst=0.0003; { сопротивление воздуха }
g=10; { ускорение свободного падения }
dtConst=0.01; { дискретность расчетов }
AngleConst=0.775; { угол наклона ствола }
LengthOfBarrel=1500; { длина ствола }
ScaleXDisplay=3;ScaleYDisplay=4;{ Соотношение сторон монитора }
DriverPath=''; { Путь к графическому драйверу }
Var
AngleOfBarrel,NewAngleOfBarrel:real; { Угол наклона ствола }
X,Y,NewX,NewY:real;{ Текущие и следующие координаты снаряда }
Vx,Vy,NewVx,NewVy:real;{ Текущие и следующие скорости снаряда
по координатам }
V0:real;{ Начальная скорость снаряда }
m,k:real; { Масса снаряда и коэффициент сопротивления воздуха }
dn:real; { Радиус действия снаряда }
Xtarget,NewXTarget:real; { Положение цели }
Ytarget:real; { Высота цели }
Vtarget:real; { Скорость цели }
dt:real; { Дискретность расчетов }
ScaleX,ScaleY:real; { Масштабы по осям }
Ch:char;{ Переменная для обработки клавиатуры }
F:text; { Файловая переменная }
Exit:boolean; { Логическая переменная для реализации выхода из цикла }
GraphDriver,GraphMode:integer;{ Графический драйвер и режим }
Page:boolean; { Логическая переменная для переключения видеостраниц }
Projectile:boolean;{ Флаг - "Снаряд в полете" }
i,j:integer; { Счетчики }
Procedure AutoSetParam; { Автоматическая установка параметров }
Begin
m:=mConst;
V0:=V0Const;
dn:=dnConst;
Vtarget:=VtargetConst;
Ytarget:=YtargetConst;
k:=kConst;
dt:=dtConst;
ScaleX:=0.000025;
ScaleY:=0.000025
End;
Procedure SwitchingPage;{ Переключение отображаемой и активной видеостраниц }
Begin
if Page then begin
SetActivePage(1);
SetVisualPage(0)
end
else begin
SetActivePage(0);
SetVisualPage(1)
end;
Page:=not Page { Переустановка флага }
End;
Procedure MoveBarrel; { Перемещение ствола }
var i:integer; { Счетчик }
Begin
SetLineStyle(SolidLn,0,ThickWidth); { Установка сплошной толстой линии }
for i:=1 to 2 do { Обработка двух страниц }
begin
SetColor(Black);{ Установка черного цвета }
Line(0,GetMaxY, { Закрашивание предыдущего положения ствола }
Round(LengthOfBarrel*cos(AngleOfBarrel)*
ScaleX*ScaleXDisplay*GetMaxX),
Round(GetMaxY-LengthOfBarrel*sin(AngleOfBarrel)*
ScaleY*ScaleYDisplay*GetMaxY));
SetColor(White); { Установка белого цвета }
Line(0,GetMaxY, { Прорисовка нового положения ствола }
Round(LengthOfBarrel*cos(NewAngleOfBarrel)*
ScaleX*ScaleXDisplay*GetMaxX),
Round(GetMaxY-LengthOfBarrel*sin(NewAngleOfBarrel)*
ScaleY*ScaleYDisplay*GetMaxY));
SwitchingPage { Переключение видеостраниц }
end;
AngleOfBarrel:=NewAngleOfBarrel { Переопределение угла наклона ствола }
End;
Procedure MoveTarget; { Перенос цели }
var i:integer; { Счетчик }
Begin
if Xtarget*ScaleX*ScaleXDisplay*GetMaxX>LengthTarget/2
{ Если цель не достигла левого края экрана, }
then NewXtarget:=Xtarget-Vtarget*dt { то вычисление нового положения }
else NewXtarget:=GetMaxX/ScaleX/ScaleXDisplay/GetMaxX-LengthTarget/2;
{ иначе перенос в начальное положение }
for i:=1 to 2 do { Обработка двух видеостраниц }
begin
SetFillStyle(SolidFill,Black);
{ Установка однородного заполнения черным цветом }
Bar(Round(Xtarget*ScaleX*ScaleXDisplay*GetMaxX-LengthTarget/2),
GetMaxY-Round(Ytarget*ScaleY*ScaleYDisplay*GetMaxY-HeightTarget/2),
Round(Xtarget*ScaleX*ScaleXDisplay*GetMaxX+LengthTarget/2),
GetMaxY-
Round(Ytarget*ScaleY*ScaleYDisplay*GetMaxY+HeightTarget/2));
{ Закрашивание предыдущего изображения цели }
SetFillStyle(SolidFill,White);
{ Установка одноподного заполнения белым цветом }
Bar(Round(NewXtarget*ScaleX*ScaleXDisplay*GetMaxX-LengthTarget/2),
GetMaxY-
Round(Ytarget*ScaleY*ScaleYDisplay*GetMaxY-HeightTarget/2),
Round(NewXtarget*ScaleX*ScaleXDisplay*GetMaxX+LengthTarget/2),
GetMaxY-
Round(Ytarget*ScaleY*ScaleYDisplay*GetMaxY+HeightTarget/2));
{ Прорисовка нового положения цели }
SwitchingPage { Переключение видеостраниц }
end;
Xtarget:=NewXtarget { Переопределение координаты цели }
End;
Procedure MoveProjectile; { Перенос снаряда }
var i:integer; { Счетчик }
Begin
NewX:=X+Vx*dt; { Вычисление новых координат снаряда }
NewY:=Y+Vy*dt;
NewVx:=Vx-dt*k*Vx*abs(Vx)/m; { Вычисление новых скоростей снаряда }
NewVy:=Vy+dt*(-k*Vy*abs(Vy)/m-g);
for i:=1 to 2 do { Обработка двух видеостраниц }
begin
SetFillStyle(SolidFill,Black);
{ Установка однородного заполнения черным цветом }
Bar(Round(X*ScaleX*ScaleXDisplay*GetMaxX)-1,
GetMaxY-Round(Y*ScaleY*ScaleYDisplay*GetMaxY)-1,
Round(X*ScaleX*ScaleXDisplay*GetMaxX)+1,
GetMaxY-Round(Y*ScaleY*ScaleYDisplay*GetMaxY)+1);
{ Закрашивание предыдущего положения снаряда }
SetFillStyle(SolidFill,White);
Bar(Round(NewX*ScaleX*ScaleXDisplay*GetMaxX)-1,
GetMaxY-Round(NewY*ScaleY*ScaleYDisplay*GetMaxY)-1,
Round(NewX*ScaleX*ScaleXDisplay*GetMaxX)+1,
GetMaxY-Round(NewY*ScaleY*ScaleYDisplay*GetMaxY)+1);
{ Прорисовка нового положения снаряда }
SwitchingPage { Переключение видеостраниц }
end;
Projectile:=(Y>=0)and(X*ScaleX*ScaleXDisplay<=1);
{ Определение положения снаряда в пределах монитора }
X:=NewX; { Переопределение координат и скоростей снаряда }
Y:=NewY;
Vx:=NewVx;
Vy:=NewVy
End;
BEGIN
{$I-} { Выключение проверки ошибок ввода-вывода }
Assign(F,'imitator.cfg');{ Связь фаиловой переменной с файлом }
Reset(F); { Открытие файла для чтения }
{$I+} { Включение проверки ошибок ввода-вывода }
if IOResult=0 { Если нет ошибки при открытии файла, }
then { то чтение параметров имитатора из файла }
Begin
Readln(F,m);
Readln(F,V0);
Readln(F,dn);
Readln(F,Vtarget);
Readln(F,Ytarget);
Readln(F,k);
Readln(F,dt);
Readln(F,ScaleX);
Readln(F,ScaleY);
Close(F)
End
else AutoSetParam; { иначе установка параметров по умолчанию }
AngleOfBarrel:=AngleConst; { Определение начального положения ствола }
NewAngleOfBarrel:=AngleOfBarrel;
Exit:=False; { Сброс флага выхода из цикла }
repeat { Вывод меню, установка параметров имитатора, запуск имитатора }
ClrScr; { Очистка экрана }
Writeln('Главное меню');
Writeln;
Writeln('1.Установка параметров имитатора');
Writeln('2.Автоматическая установка параметров');
Writeln('3.Сохранение параметров в файле');
Writeln('4.Запуск имитатора');
Writeln;
Writeln('0.Выход');
case ReadKey of { Чтение клавиатуры и выбор пункта меню }
'1': Begin
repeat { Вывод подменю установки параметров }
ClrScr;
Writeln('Параметры имитатора');
Writeln;
Writeln('1.Масса снаряда ',m);
Writeln('2.Начальная скорость снаряда ',V0);
Writeln('3.Радиус действия снаряда ',dn);
Writeln('4.Скорость цели ',Vtarget);
Writeln('5.Высота цели ',Ytarget);
Writeln('6.Коэффициент сопротивления воздуха ',k);
Writeln('7.Дискретность расчетов ',dt);
Writeln('8.Масштаб по оси X ',ScaleX);
Writeln('9.Масштаб по оси Y ',ScaleY);
Writeln;
Writeln('0.Выход');
case ReadKey of { Чтение клавиатуры и ввод соответствующего }
'1':begin { параметра }
ClrScr;
Write('Масса снаряда ');
Readln(m)
end;
'2':begin
ClrScr;
Write('Начальная скорость ');
Readln(V0)
end;
'3':begin
ClrScr;
Write('Радиус действия ');
Readln(dn)
end;
'4':begin
ClrScr;
Write('Скорость цели ');
Readln(Vtarget)
end;
'5':begin
ClrScr;
Write('Высота цели ');
Readln(Ytarget)
end;
'6':begin
ClrScr;
Write('Коэффициент сопротивления воздуха ');
Readln(k)
end;
'7':begin
ClrScr;
Write('Дискретность расчетов ');
Readln(dt)
end;
'8':begin
ClrScr;
Write('Масштаб по оси X ');
Readln(ScaleX);
end;
'9':begin
ClrScr;
Write('Масштаб по оси Y ');
Readln(ScaleY);
end;
'0',#27:Exit:=true
end
until Exit;
Exit:=false
End;
'2': AutoSetParam;
'3': Begin
{$I-} { Выключение проверки ошибок ввода-вывода }
Assign(F,'imitator.cfg');{ Связь фаиловой переменной с файлом }
Rewrite(F); { Открытие файла для записи }
{$I+} { Включение проверки ошибок ввода-вывода }
if IOResult=0 { Если нет ошибки при открытии файла, }
then { то запись параметров имитатора в файл }
Begin
Writeln(F,m);
Writeln(F,V0);
Writeln(F,dn);
Writeln(F,Vtarget);
Writeln(F,Ytarget);
Writeln(F,k);
Writeln(F,dt);
Writeln(F,ScaleX);
Writeln(F,ScaleY);
Close(F) { Закрытие файла }
End
End;
'4': Begin { Запуск имитатора }
GraphDriver:=Detect; { Автоматическое определение драйвера }
InitGraph(GraphDriver,GraphMode,DriverPath);
{ Инициализация графического режима }
SetGraphMode(0); { Наименее емкий режим для любого адаптера }
Xtarget:=1/ScaleX/ScaleXDisplay-LengthTarget/2;
{ Определение начального положения цели }
SetLineStyle(SolidLn,0,ThickWidth);
{ Установка сплошной толстой линии }
Page:=false; { Сброс флага страниц }
for i:=1 to 2 do { Обработка двух видеостраниц }
Begin
SwitchingPage; { Переключение видеостраниц }
Line(0,GetMaxY, { Прорисовка ствола }
Round(LengthOfBarrel*cos(AngleOfBarrel)*
ScaleX*ScaleXDisplay*GetMaxX),
Round(GetMaxY-LengthOfBarrel*sin(AngleOfBarrel)*
ScaleY*ScaleYDisplay*GetMaxY))
End;
Projectile:=false; { Сброс флага снаряда }
repeat { Обработка клавиатуры и определение действия }
if KeyPressed { Если нажата клавиша, }
then Ch:=ReadKey { то определение селектора по клавише }
else Ch:=' ';
case Ch of
#72,#56: { Подъем ствола, если его угол не превзойдет 90° }
if AngleOfBarrel+0.01*Pi<Pi/2
then NewAngleOfBarrel:=AngleOfBarrel+0.01*Pi;
#80,#50: { Опускание ствола, если его угол не опустится
ниже 0° }
if AngleOfBarrel-0.01*Pi>0
then NewAngleOfBarrel:=AngleOfBarrel-0.01*Pi;
#13 : { Если снаряд не летит, то выстрел }
if not Projectile then
begin
{ Определение начальных координат и скоростей
снаряда }
X:=LengthOfBarrel*cos(AngleOfBarrel);
Y:=LengthOfBarrel*sin(AngleOfBarrel);
Vx:=V0*cos(AngleOfBarrel);
Vy:=V0*sin(AngleOfBarrel);
Projectile:=true { Подъем флага снаряда }
end;
#27 :Exit:=True { Подъем флага выхода }
end; { case }
MoveTarget; { Перерисовка цели }
MoveBarrel; { Перерисовка ствола }
if Projectile then { Если снаряд в полелете, }
begin { то обработка полета снаряда }
MoveProjectile; { Перерисовка снаряда }
if Sqrt(Sqr(X-Xtarget)+Sqr(Y-Ytarget))<=dn
{ Если снаряд рядом с целью, }
then begin { то взрыв }
Projectile:=false; { Сброс флага снаряда }
Xtarget:=1/ScaleX/ScaleXDisplay-LengthTarget/2;
{ Перенос цели в начальное положение }
SetColor(White); { Установка белого цвета }
SetFillStyle(SolidFill,White);
{ Установка однородного заполнения белым цветом }
for j:=1 to 4 do
{ Прорисовка взрыва в четыре кадра }
begin
PieSlice(Round(X*ScaleX*ScaleXDisplay*
GetMaxX),
GetMaxY-Round(Y*ScaleY*ScaleYDisplay*GetMaxY),
0,360,18*j);
SwitchingPage { Переключение видеостраниц }
end;
SetColor(Black);{ Установка черного цвета }
SetFillStyle(SolidFill,Black);
{ Установка однородного заполнения черным цветом }
for i:=1 to 2 do { Закрашивание взрыва, цели
и снаряда на двух видеостраницах }
begin
PieSlice(Round(X*ScaleX*ScaleXDisplay*
GetMaxX),
GetMaxY-Round(Y*ScaleY*ScaleYDisplay*GetMaxY),
0,360,18*j);
SwitchingPage { Переключение видеостраниц }
end
end { Конец обработки "попадание" }
end { Конец обработки "полет снаряда" }
until Exit; { Выход из имитатора }
CloseGraph; { Закрытие графического режима }
Exit:=False { Сброс флага выхода }
End; { Конец обработки пункта меню "Запуск имитатора" }
'0',#27: Exit:=True { Подьем флага выхода }
end; { конец case главного меню }
until Exit { Выход из внешнего цикла программы }
END.
Бесплатные примеры программ
Примеры написанных программ
Помощь студентам по программированию