Программирование и комп-ры

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



                               Домашняя работа
                             по программированию
                              за второй семестр


                             Игра «Морской Бой»



                                                     Выполнил: Макаров В. А.
                                                   группа: С-26

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

Эскиз:
[pic]

Аномалии:
|Аномалия                         |Действие программы               |
|1) Произошла ошибка инициализации|Вывод сообщения:                 |
|графики                          |«InitGraph ERROR!»               |
|2) При игре было допущено более  |Вывод сообщения                  |
|пяти промахов. Проигрыш.         |«GAME OVER»                      |

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

Вход:
|Vipolnil: Makarov Vladimir                                          |
|Group: C-26                                                         |
|                                                                    |
|                                                                    |
|                                                                    |
|Press  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  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.                                                                     |





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