Программ-игра “Морской бой”, с использованием анимированных графических объектов и возможностью управлять их движением с помощью клавиатуры

Домашняя работа

По программированию

За второй семестр

Игра “Морской Бой”

Выполнил: Макаров В. А.

группа: С-26

Игра “Морской Бой”

Требуется:

Разработать программу-игру “Морской бой”, с использованием анимированных графических объектов и возможностью управлять их движением с помощью клавиатуры.

Эскиз:

Аномалии:

Аномалия

Действие программы

1) Произошла ошибка инициализации графики

Вывод сообщения:

“InitGraph ERROR!”

2) При игре было допущено более пяти промахов. Проигрыш.

Вывод сообщения

“GAME OVER”

Внешняя спецификация:

Вход:

Vipolnil: Makarov Vladimir

Group: C-26

Press <Enter> to start play game!

Выход при проигрыше:

GAME OVER

Метод:

Описание:

Во время игры на экране изображена водная поверхность и две скалы по бокам. Время от времени из-за скал выплывают различные корабли, которые движутся вдоль горизонта к противоположенной скале. Существует три типа кораблей: маленький, средний и большой. Тип корабля всегда выбирается случайным образом. Скорость каждого корабля зависит от размера самого корабля: маленький самый быстрый, остальные соответственно обладают более низкой скоростью. Цель игрока состоит в том, чтобы с помощью пушки и прицела подбить как можно большое количество кораблей и не промахиваться. Количество подбитых кораблей (scope) показывается в нижнем левом углу экрана. Игрок должен нацеливать пушку влево или вправо и стрелять по возможности на опережение, так как снаряд вылетающий из пушки обладает относительно малой скоростью. В случае промаха игрока, корабль разворачивается и уплывает в обратную сторону. Если игрок совершил более пяти промахов, то он проигрывает и выходит из игры.

Прицеливание осуществляется с помощью стрелок (вправо и влево) на клавиатуре, пробел – стрельба и escape – выход.

Основной метод:

В основе работы программы лежит главный зацикленный цикл, выход из которого осуществляется только при выходе или при проигрыше. В цикле выполняются действия, зависящие от состояния флагов, так как каждому событию в программе соответствует свой флаг. Так же в этом цикле отслеживаются нажатия определенных клавиш. Цикл прокручивается с, заранее определенной и постоянной, временной задержкой.

Когда какой-нибудь флаг принимает истинное значение, в цикле проделывается соответствующее ему действие, после чего флаг сразу сбрасывается в положение ложь.

Рисование всех двигающихся объектов производится для удобства в отдельных процедурах. В качестве параметров туда передается координата по оси или x или y, так же туда передается флаг, указывающий на то – рисовать объект или стирать. Под стиранием объекта понимается его рисование цветом фона.

Движение всех графических объектов в программе осуществляется стандартным методом: сначала рисуется объект, а после временной задержки он рисуется на том же месте цветом фона (стирается) и рисуется в новом месте.

Скорости всех двигающихся в программе объектов различны:

Vснаряда > Vкорабля №1 > Vкорабля №2 > Vкорабля №3

Временная задержка во всей программе постоянная и используется один раз за цикл. Если один проход цикла назвать тактом, то разность скоростей объектов реализована за счет того, что каждый объект перемещается на единицу расстояния не за каждый такт, а за каждый n – ный такт, а n определено для каждого объекта по-разному. Чем меньше n, тем быстрее скорость. В данной программе все скорости постоянны.

Алгоритм:

Procedure target (ix: integer; bb: boolean)

Входные данные: ix:цел bb:лог

Внутренние постоянные переменные: iy=200

Начало

Если bb то {Отображение}

Установить цвет(green)

Установить тип заливки(SolidFill, green)

Нарисовать закрашенный эллипс(ix,430,26,100)

Выбрать цвет(lightgreen)

Нарисовать линию(ix-10,iy, ix+10,iy)

Нарисовать линию(ix, iy-10,ix, iy+10)

Иначе {Стирание}

Установить тип заливки(SolidFill, blue)

Установить цвет(blue)

Нарисовать закрашенный эллипс( (ix,430,26,100)

Установить цвет(blue)

Нарисовать линию(ix-10,iy, ix+10,iy)

Нарисовать линию(ix, iy-10,ix, iy+10)

Все

Конец

Часть 2: Поиск в тексте единиц и вставка после них нулей

Входные данные: var st:мас :стр r:цел var one:лог

Выходные данные: rez:масс :стр iz:цел

Внутренние переменные: k, l:цел

Начало

One:=ложь

Цикл для k:=1 до r делать

L:=1

Цикл пока l<=длина(st[k]) делать

Если st[k][l]=’1′ то

Insert(‘0’,st[k],l+1) {Вставить после нуля единицу}

One:=истина {Значит, в тексте есть единицы}

Все

Inc(l) {l:=l+1}

Кцикл

Кцикл

Все

Вспомогательная функция: Определяет, является ли символ цифрой

Входные данные: с:сим

Выходные данные: лог

Внутренние переменные: e:цел fl:лог

Начало

Fl:=ложь

D:=’0123456789′ {все цифровые символы}

Цикл для e:=1 до 10 делать {перебор всех символов цифр}

Если c=d[e] то fl:=истина

Кцикл

{Ели символ является цифрой, то функция возвратит истину,

Иначе возвратит ложь}

Digs:=fl {функция возвращает значение}

Все

Исходный код всей программы:

{Домашнее задание на тему “графика”}

{Выполнил студент: Макаров Владимир, группа С-26}

{Игра “Морской Бой”}

Program SeaWar;

Uses Graph, crt;

Var

GraphDriver:integer;

GraphMode:integer;

ErrorCode:integer; {Переменные для инициализации графики}

S_score:string;

{Все переменные, используемые в программе}

X :integer;

Y :integer; {Переменные для хранения координат}

Xx :integer; {и переменные цикла}

Typ :integer; {Тип текущего корабля}

Xxx :integer; {Координаты}

Tarx :integer; {Координаты прицела и пушки}

Fx :integer; {Координаты}

Fy :integer;

Score :integer; {Кол-во очков}

Old_score :integer; {Прошлое значение кол-ва очков}

Mimo :integer; {Кол-во промахов}

Oldx :integer; {Координаты}

Oldy :integer;

Crx :integer;

Cr_type :integer; {Тип корабля}

Flang :integer; {С какой стороны плывет корабль}

Croldx :integer;

Cr_ind2 :integer;

Cr_ind:longint; {Рабочая переменная}

C:char; {Хранение нажатых клавиш}

{Флаги}

B :boolean; {Флаг нажатия клавиш “стрелок”}

Fire :boolean; {Стрельба}

Swim :boolean; {Перемещение}

Promah :boolean; {Промах}

Vzriv :boolean; {Взрыв}

Const

{Два константных массива точек для хранения координат скал}

Trin1:array[1..4] of PointType=

((x:-70;y:380),(x:60;y:20),(x:150;y:350),(x:-70;y:380));

Trin2:array[1..4] of PointType=

((x:670;y:380),(x:560;y:5),(x:500;y:350),(x:670;y:400));

{Процедура вывода прицела и пушки на экран}

Procedure target(ix:integer;bb:boolean);

Const iy=200;

Begin

If bb then begin {Отображение}

SetColor(green);

SetFillStyle(SolidFill, green);

FillEllipse(ix,430,26,100);

SetColor(lightgreen);

Line(ix-10,iy, ix+10,iy);

Line(ix, iy-10,ix, iy+10);

End else begin {Стирание}

SetFillStyle(SolidFill, blue);

SetColor(blue);

FillEllipse(ix,430,26,100);

SetColor(blue);

Line(ix-10,iy, ix+10,iy);

Line(ix, iy-10,ix, iy+10);

End;

End;

{Процедура вывода на экран различных кораблей}

Procedure sheep(ix:integer;tip:integer;bb:boolean);

Const

Iy=200;

Var

Col, col2:integer;

Sp1,sp2,sp3:array[1..5] of PointType;

Begin

Col:=brown;

Col2:=yellow;

If not bb then begin {Если bb=true, то отображение корабля}

Col:=blue; {Иначе стирание корабля}

Col2:=blue;

End;

{Координаты кораблей, относительно центральной точки ix}

Sp1[1].x:=ix-40;

Sp1[1].y:=190;

Sp1[2].x:=ix+40;

Sp1[2].y:=190;

Sp1[3].x:=ix+20;

Sp1[3].y:=215;

Sp1[4].x:=ix-20;

Sp1[4].y:=215;

Sp1[5].x:=sp1[1].x;

Sp1[5].y:=sp1[1].y;

Sp2[1].x:=ix-30;

Sp2[1].y:=190;

Sp2[2].x:=ix+30;

Sp2[2].y:=190;

Sp2[3].x:=ix+15;

Sp2[3].y:=210;

Sp2[4].x:=ix-15;

Sp2[4].y:=210;

Sp2[5].x:=sp2[1].x;

Sp2[5].y:=sp2[1].y;

Sp3[1].x:=ix-20;

Sp3[1].y:=195;

Sp3[2].x:=ix+20;

Sp3[2].y:=195;

Sp3[3].x:=ix+10;

Sp3[3].y:=205;

Sp3[4].x:=ix-10;

Sp3[4].y:=205;

Sp3[5].x:=sp3[1].x;

Sp3[5].y:=sp3[1].y;

{Отображение одного из трех типов кораблей}

Case tip of

3: begin

SetColor(col);

SetFillStyle(SolidFill, col);

FillPoly(5,sp1);

Rectangle(ix-18,iy-30,ix+18,iy-2);

SetColor(col2);

SetFillStyle(SolidFill, col2);

Rectangle(ix-10,iy-25,ix+10,iy-15);

FillEllipse(ix-18,iy,5,5);

FillEllipse(ix+18,iy,5,5);

FillEllipse(ix, iy,5,5);

End;

2: begin

SetColor(col);

SetFillStyle(SolidFill, col);

FillPoly(5,sp2);

Line(ix,200,ix,170);

Line(ix-5,175,ix+5,175);

Line(ix-10,180,ix+10,180);

End;

1: begin

SetColor(col);

SetFillStyle(SolidFill, col);

FillPoly(5,sp3);

Line(ix,200,ix,185);

Line(ix-5,185,ix+5,185);

Line(ix-10,190,ix+10,190);

End;

End;

End;

{Начало главной процедуры программы}

Begin

X:=100;

Xx:=0;

Xxx:=0;

Oldx:=0;

B:=false;

Tarx:=320;

Fire:=false; {инициализация переменных}

Crx:=0;

Croldx:=800;

Score:=0;

Old_score:=0;

Mimo:=0;

Promah:=false;

Vzriv:=false;

{Переключение в графический режим}

GraphDriver:=Detect;

InitGraph(GraphDriver, GraphMode,”);

If ErrorCode=grok then begin

SetColor(green);

SetBKColor(black);

End else begin

Writeln(‘ERROR!’);

Exit;

End;

SetColor(white);

OutText(‘Vipolnil: Makarov Vladimir’);

OutTextXY(0,10,’Group: C-26′);

SetTextJustify(CenterText, CenterText);

OutTextXY(640 div 2,480 div 2,’Press <Enter> to start play game!’);

C:=ReadKey;

{Подготовка экрана к игре}

ClearDevice;

SetBkColor(blue);

SetColor(lightgray);

SetFillStyle(SolidFill, lightgray);

FillPoly(4,trin1);

FillPoly(4,trin2);

SetColor(black);

Target(320,true);

{Главный цикл обработки различных сообщений и событий}

Repeat

Repeat

{Обработка сообщения “Взрыв корабля”}

If vzriv then begin

if xx=0 then begin

typ:=cr_type;

xxx:=crx;

end;

if xx<150 then begin

{Рисование взрыва}

Sound(Random(100));

swim:=false;

SetColor(red);

SetColor(red);

SetFillStyle(SolidFill, red);

FillEllipse(xxx,200,21*typ,17*typ);

inc(xx);

end else begin

NoSound;

swim:=false;

SetColor(blue);

SetFillStyle(SolidFill, blue);

FillEllipse(xxx,200,21*typ,17*typ);

xx:=0;

vzriv:=false;

end;

End;

{Обработка сообщения “Перемещение”}

If swim then begin

if cr_ind<400 then begin

Sheep(crx, cr_type, false);

if promah then promah:=false;

end else begin

if cr_ind mod cr_type*5=0 then begin

if promah then begin

if flang=0 then flang:=1

else flang:=0;

promah:=false;

end;

if flang=0 then begin

if crx=485 then begin

inc(cr_ind2);

if cr_ind2<3 then Sheep(crx, cr_type, true)

else begin

Sheep(crx, cr_type, false);

swim:=false;

end;

end else begin

crx:=crx+1;

Sheep(croldx, cr_type, false);

Sheep(crx, cr_type, true);

croldx:=crx;

end;

end else begin

if crx=150 then begin

inc(cr_ind2);

if cr_ind2<3 then Sheep(crx, cr_type, true)

else begin

Sheep(crx, cr_type, false);

swim:=false;

end;

end else begin

crx:=crx-1;

Sheep(croldx, cr_type, false);

Sheep(crx, cr_type, true);

croldx:=crx;

end;

end;

end;

end;

inc(cr_ind);

End else begin

{Если корабля нет на экране, то случайным методом

выбирается новый корабль}

Randomize;

croldx:=800;

cr_ind2:=0;

if random(2)=0 then begin

crx:=150;

flang:=0;

end else begin

crx:=485;

flang:=1;

end;

swim:=true;

cr_ind:=0;

Randomize;

cr_type:=random(3)+1;

End;

{Обработка сообщения “Выстрел”}

{и рисование полета снаряда}

If fire then begin

X:=x-10;

Sound(x);

SetColor(blue);

Line(fx+1,fy-2,fx+1,fy+2);

Line(fx-1,fy-2,fx-1,fy+2);

Line(fx, fy-2,fx, fy+2);

Fy:=fy-2;

SetColor(lightred);

Line(fx+1,fy-2,fx+1,fy+2);

Line(fx-1,fy-2,fx-1,fy+2);

Line(fx, fy-2,fx, fy+2);

If fy<200 then begin

If (getpixel(fx-1,fy-3)=brown)or(getpixel(fx+1,fy-3)=brown) then begin

Old_score:=score;

Inc(score);

Vzriv:=true;

End else begin

{Обработка сообщения “Промах”}

Promah:=true;

Inc(mimo);

if mimo>5 then begin

{Выход из игры в случае проигрыша}

ClearDevice;

SetColor(white);

SetBkColor(black);

SetTextJustify(CenterText, CenterText);

OutTextXY(640 div 2,480 div 2,’GAME OVER!’);

Sound(200);

Delay(10000);

NoSound;

c:=ReadKey;

exit;

end;

End;

Fire:=false;

NoSound;

SetColor(blue);

Line(fx+1,fy-2,fx+1,fy+2);

Line(fx-1,fy-2,fx-1,fy+2);

Line(fx, fy-2,fx, fy+2);

End;

End;

If b then begin

{Перерисовка прицела и пушки в случае нажатия клавиш “стрелок”}

Target(oldx, false);

Target(tarx, true);

B:=false;

End else target(tarx, true);

{В случае попадания, производится начисление очков и вывод их на экран}

If old_score<>score then begin

SetColor(blue);

SetTextJustify(LeftText, BottomText);

Str(old_score, s_score);

OutTextXY(70,460,s_score);

old_score:=score;

End;

SetColor(white);

SetTextJustify(LeftText, BottomText);

OutTextXY(20,460,’Score’);

Str(score, s_score);

OutTextXY(70,460,s_score);

Delay(150); {Временная задержка главного цикла}

Until keypressed;

{Обработка нажатия клавиш}

C:=readkey;

Case c of

#75: begin {влево}

If tarx>220 then begin

Oldx:=tarx;

Tarx:=tarx-5;

B:=true;

End;

End;

#77: begin {вправо}

If tarx<420 then begin

Oldx:=tarx;

Tarx:=tarx+5;

B:=true;

End;

End;

#32: begin {пробел “Выстрел”}

If not fire then begin

X:=800;

Fire:=true;

Fx:=tarx;

Fy:=380;

End;

End;

#27: begin {esc “Выход”}

NoSound;

Exit;

End;

End;

Until false; {Зацикливание главного цикла обработки сообщений}

End.


Программ-игра “Морской бой”, с использованием анимированных графических объектов и возможностью управлять их движением с помощью клавиатуры