Разработка компьютерной игры "Змейка"

Введение

Ни для кого не секрет, что видео игры прочно заняли свою позицию в современной индустрии развлечений. Существуют попытки выделить компьютерные игры как отдельную область искусства, наряду с театром, кино и т.п. Разработка игр может оказаться не только увлекательным, но и прибыльным делом, примеров этому предостаточно в истории. Первые примитивные компьютерные и видео игры были разработаны в 1950-х и 1960-х годах. Они работали на таких платформах, как осциллографы, университетские мейнфреймы и компьютеры EDSAC. Самой первой компьютерной игрой стал симулятор ракеты, созданный в 1942 году Томасом Голдсмитом Младшим (англ. Thomas T. Goldsmith Jr.) и Истл Рей Менном (англ. Estle Ray Mann). Позже, в 1952 году, появилась программа "OXO", имитирующая игру "крестики-нолики", созданная А.С. Дугласом как часть его докторской диссертации в Кембриджском Университете. Игра работала на большом университетском компьютере, известном как EDSAC (Electronic Delay Storage Automatic Calculator). В настоящее время, разработка игры - это многомиллионный процесс, в котором задействована целая команда разработчиков, сложные современные технологии и даже маркетинговые ходы.

Целью же моей курсовой работы будет разработка развивающей ловкость игры - "Змейка".

компьютерная игра pascal программа

1. Постановка задачи

В данной курсовой работе я ставлю перед собой следующие задачи:

1. В программе должно присутствовать меню, в котором можно просматривать данные о разработчике и игре, рекорды и непосредственно переход к самой игре.

2. Должно быть несколько уровней сложности (чем больше сложность, тем больше скорость змейки и ее первоначальная длина).

3. Змейка должна собирать пищу (символы на экране, которые появляются случайно); при этом змейка должна "разбиваться" при столкновении с границей игрового поля и со своим "хвостом".

4. Должна присутствовать возможность сохранения результата в типизированный файл. И вывод результатов на экран при последующем запуске программы.

2. Выбор метода реализации задачи

Для реализации игры будет использован язык программирования Pascal. Данный язык является наиболее распространённым языком программирования среди студентов. Основное назначение этого языка - обучение программированию. Это было заложено в языке Паскаль создателем Никлаусом Виртом. Также благодаря американской корпорации Borland, вложившей в язык Паскаль новые идеи и принципы, язык стал мощным средством для создания программ, которые могут решить широкий круг проблем: от простых вычислительных задач до сложных исследовательских, использующих огромные объемы данных.

Во многих случаях стандартных возможностей ввода-вывода данных с помощью процедуры Read, Readln, Write, Writeln оказывается явно недостаточно для разработки диалоговых программ. Поэтому при написании своей программы я буду использовать модуль CRT. С помощью этой библиотеки можно определить факт нажатия какой-либо спец. клавиши.

3. Составление общего алгоритма

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

Рис.3.1 - Общий алгоритм программы

После выбора уровня сложности мы переходим к игровому полю. Управление змейкой осуществляется при помощи клавиш управления курсором. После того как игра закончилась, на экран выводится сообщение об этом и, если игрок набрал результат выше чем 10 место в списке рейтинга, предлагается ввести свое имя для сохранения результата. Далее осуществляется переход в главное меню. Это продолжается до тех пор, пока не буде нажата кнопка "Выход".

4. Выделение функциональных частей

Программа будет состоять из следующих функциональных частей:

    Подпрограмма, которая рисует кнопки всех меню.

    Подпрограмма, которая обеспечивает вывод и работу меню 2-го уровня.

    Подпрограмма, отвечающая за изменение положения змейки.

    Подпрограмма, которая обеспечивает работу с меню "Справка"

    Подпрограмма, отвечающая за столкновение змейки.

    Подпрограмма, которая отвечает за сохранение результатов.

5. Обоснование алгоритмов отдельных функциональных частей

    Подпрограмма Ramka

Цель этой подпрограммы заключается в том, чтобы рисовать кнопки меню, осуществляется это следующим образом: При вызове процедуры надо указывать ее фактические параметры, именно они указывают подпрограмме, в каком месте стоит нарисовать кнопку меню и каким цветом нужно рисовать. Само рисование организуется при помощи счетного цикла (For.: =. to. do) и процедуры GotoXY (x,y), которая переводит курсор в место на экране с координатами x и y.

    Процедура Menu2

Цель этой подпрограммы заключается в том, чтобы нарисовать и организовать работу меню 2-го уровня. Сначала рисуются рамка потом, при помощи процедуры Ramka, рисуются вкладки, а затем в этих вкладках вписываются названия кнопок. Работа с меню организуется при помощи цикла с постпроверкой условия (repeat … until), условного оператора if. then. else и

функции Readkey. Работает это по следующему принципу: функция readkey указывает какая клавиша была нажата, далее при помощи условного оператора

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

    Процедура Izm

Эта процедура переформировывает массив, в котором содержатся координаты "частей" змейки, это осуществляется следующим образом: первому элементу массива присваиваются новые координаты, а всем остальным - координаты предыдущего элемента (x [3] получит значение x [2], а x [2] - x [1]).

    Процедура Spravka

Эта процедура обеспечивает работу с меню "Справка". В основе этой процедуры лежит считывание и вывод на экран типизированного файла.

    Процедура Stolknovenie

Через эту процедуру программа проверяет, не столкнулась ли змейка с границей поля или сама с собой. Это осуществляется при помощи условного оператора if. then. else, который сверяет координаты головы змейки с координатами границ игрового поля и "хвоста змейки".

    Процедура Resultat

Эта процедура считывает с файлов данные о рекордах, составляет из них массив, элементами которого являются записи с 2 полями (Имя и Результат), если был набран результат выше 10 места в списке рейтинга, присваивает 10 элементу массива данные содержащие имя игрока и набранный результат. Далее сортирует этот массив методом прямого обмена и записывает отсортированный массив в файл.

6. Разработка тестовых примеров

На основе разработанных решаемых задач можно выделить тестовые примеры необходимые для проверки работоспособности игры. Если по прохождении всех пунктов тестирования будут получены удовлетворительные результаты, значит можно будет заявить о том, что программа работает верно.

1. После запуска игры на экране должно появиться главное меню со вкладками "Играть", "Рекорды", "Справка", "Выход".

2. Выбрав меню "Рекорды", на экране должна появиться таблица результатов такого формата: <занимаемое место>: <набранный результат> <имя игрока>

3. Выбрав меню "Справка", на экране появится меню справки со вкладками

"Правила игры", "Разработчик" и "Назад". выбирая каждую вкладку, на экране должна будет появиться соответствующая информация.

4. Выбрав меню "Играть", на экране появится меню выбора уровня сложности с 3 вариантами сложности "Глист", "Змея", "Анаконда". После выбора уровня сложности появится игровое поле и начнется игра. Справа от игрового поля будет находиться информация, отображающая набранный счет, длину змейки в знаках и тройка лидеров.

5. После столкновения на экране появится надпись об окончании игры и, в случае если был набран результат выше 10 места в списке рейтинга, вам предложат ввести свое имя для сохранения результата, в противном случае вам тоже предложат ввести ваше имя, но результат сохранен не будет.

6. После того как пользователь введет имя и нажмет ENTER появится снова главное меню. Программа будет работать до тех пор, пока не будет выбрана вкладка меню "Выход".

7. Разработка программы

При написании программы я использовал модули Паскаля Crt.

Crt содержит константы, переменные и подпрограммы, предназначенные для работы с консолью. В отличие от стандартного ввода-вывода, когда он осуществляется через операционную систему, подпрограммы модуля работают с BIOS, и даже непосредственно с видеопамятью. При работе с этим модулем экран разбивается на отдельные строки, а каждая строка - на отдельные позиции, в каждую из которых можно поместить один символ. Таким образом, весь экран разбивается на отдельные неделимые прямоугольные элементы. Для каждого элемента можно задать цвет фона и цвет символа. Этот модуль применяется тогда, когда нужно задать определенные цвета фона и символов, размещать данные на экране при помощи перемещения курсора на определенные заданные позиции, удалять символы с экрана, создавать окна для помощи, узнавать текущие координаты курсора, задерживать выполнение программы.

Именно этими принципами я руководствовался при разработке меню и самого процесса игры.

Также в моей программе я использовал типизированные файлы. Так информация о разработчике хранится в файле под названием Avtor. pas, правила игры хранятся в файле Pravila. pas. Таблица рекордов хранится в файле Itog. txt. Для того чтобы работать с рекордами (сравнивать результаты и сортировать таблицу результатов) мне потребовалось отдельный файл в котором хранятся только рекорды (Rec. dat), и файл в котором хранятся имена пользователей (Imena. txt).

В программе широко использовались такие функции как Readkey (), GotoXY, а также циклы и оператор условия.

8. Тестирование и анализ результатов

При тестировании программы был произведен подробный анализ каждой подпрограммы.

При запуске программы появилось главное меню со вкладками "Играть", "Рекорды", "Справка", "Выход" (Рис.8.1).

Рис. 8.1 - Главное меню

Выбираем меню "Рекорды". Перед нами появляется 10 лучших игроков с набранным ими результатом (Рис.8.2).

Рис. 8.2 - Вкладка "Рекорды"

После нажатия любой кнопки мы возвращаемся в главное меню. Выбираем меню "Справка". Перед нами появляется Меню 2-го уровня - "Справка" со вкладками "Правила игры", "Разработчик" и "Назад" (Рис.8.3).

Рис. 8.3 - Меню "Справка"

При выборе вкладки "Правила игры" на экране появляется соответствующая информация (Рис. 8.4).

Рис. 8.4 - Правила игры

После нажатия любой клавиши мы вернулись обратно в меню "Справка". При выборе вкладки "Разработчик", выводится соответствующая информация построчно с некоторой задержкой (Рис. 8.5).

Рис. 8.5 - Информация о разработчике

После нажатия любой клавиши мы вернулись опять же в меню "Справка". После выбора вкладки "Назад" мы возвращаемся в главное меню. Выбираем вкладку "Играть". Появляется меню выбора уровня сложности (Рис.8.6).

Рис. 8.6 - Выбор уровня сложности

После того, как мы выберем уровень, появится игровое поле и после нажатия клавиш управления начнется сам игровой процесс (Рис. 8.7).

Рис.8.7 - Игровой процесс

После того как игрок проиграет (столкнется со границей игрового поля или с "собственным хвостом") появится соответствующее сообщение (Рис.8.8).

Рис.8.8 - Конец игры

Далее, в случае того, если был набран результат выше результата, который занимал 10 место в списке рейтинга, вам предложат ввести своё имя (Рис.8.9).

Рис.8.9 - Ввод имени для сохранения результатов

Ваше имя можно будет увидеть в списке рейтинга при переходе по вкладке "Рекорды" главного меню. Ваше имя будет стоять на соответствующей, занятой вами, позиции (Рис. 8.10).

Рис. 8.10 - Вкладка "Рекорды" (После сохранения нового результата)

Выход из программы осуществляется кнопкой главного меню "Выход".

Заключение

В ходе выполнения курсовой работы были изучены основы программирования на языке Pascal. Написание программы способствовало закреплению теоретического материала на практике.

Игра "Змейка" является логически завершенной игрой. Также возможны изменения и добавления некоторых моментов в геймплей, такие как мультиплеер и добавление на игровом поле препятствий.

Текст программы

Program Sme;

uses crt;

type

reca=record

name:string[10];

resultat:integer;

end;

var

aa:reca;

Xz,Yz:array [1..40] of byte;

us:array [1..11] of reca;

i,j,a,k,k2,kk,och,z:integer;

H,W,hl,hr,Ww,Wn,PlayE,Play:ShortInt;

X1,Y1,x,y,d:byte;

Kno,onk:Char;

SL,Schot:Word;

Ax,Ay,Bx,By,Ex,Ey,as,sa:Byte;

f1:text;

f2:file of integer;

f3:text;

f4:text;

namen:string[10];

resul:string[20];

prav:string;

q,wq,qq,qw:string[15];

Procedure stolknovenie;

begin

for i:=2 to d-2 do

begin

if (Xz[i]=Xz[i+2]) and (Yz[i]=Yz[i+2]) then

as:=0 else as:=1;

sa:=sa*as;

end;

for i:=1 to d-3 do

begin

if (sa<>0) and (xz[1]=xz[i+3]) and (yz[1]=yz[i+3]) then Play:=0;

end;

if (Xz[1]=3) or (Xz[1]=57) or (Yz[1]=3) or (Yz[1]=22) Then Play:=0;

end;

Procedure Ramka(Xr,Yr:Byte; tt: string; c:byte);

begin

TextColor(c);

GotoXY (Xr,Yr+1);

write (tt);

For i:=Xr to Xr+20 do

begin

GotoXY (i,Yr);

write ('*');

GotoXY (i,Yr+2);

write ('*');

end;

For i:=Yr to Yr+2 do

begin

GotoXY (Xr,i);

write ('*');

GotoXY (Xr+20,i);

write ('*');

end;

end;

Procedure Izm(vv:byte);

Begin

Ax:=Bx; Ay:=By;

Bx:=Xz[vv]; By:=Yz[vv];

Xz[vv]:=Ax; Yz[vv]:=Ay;

End;

Procedure menu2 (q,qq,wq,qw:string);

begin

Clrscr;

TextBackground (0);

TextColor (15);

For X1:=25 to 55 do

Begin

GotoXY (X1,4);

Write ('*');

GotoXY (X1,22);

Write ('*');

end;

For Y1:=4 to 22 do

begin

GotoXY (25,Y1);

Write ('*');

GotoXY (55,Y1);

Write ('*');

end;

GotoXY (31,7);

Write (q);

K2:=0;

repeat

K2:=k2+kk;

kk:=0;

If k2=0 Then Ramka (30,10,qq,128) else

Ramka (30,10,qq,15);

If k2=1 then Ramka (30,14,wq,128) else

Ramka (30,14,wq,15);

IF K2=2 Then Ramka (30,18,qw,128) else

Ramka (30,18,qw,15);

Kno:=ReadKey;

If Kno=#80 then Begin if k2<2 then kk:=1 else kk:=0; end else

if Kno=#72 then Begin if k2>0 then kk:=-1 else kk:=0; end;

until Kno=chr(13);

end;

Procedure Spravka;

begin

menu2(' СПРАВКА',' ПРАВИЛА ИГРЫ ',' РАЗРАБОТЧИК ',' НАЗАД ');

if k2=0 then

begin

clrscr;

assign(f4,'d:\kkk\pravila.pas');

reset(f4);

i:=3;

While not EOF(f4) do

begin

GotoXY(3,i);

i:=i+2;

readln(f4,prav);

writeln(prav);

end;

readln;

end;

if k2=1 then

begin

clrscr;

TextBackground(0);

TextColor (4);

For X1:=3 to 77 do

Begin

GotoXY (x1,2);

Write ('*');

GotoXY (X1,23);

write ('*');

end;

For Y1:=2 to 23 do

Begin

GotoXY (3,Y1);

Write ('*');

GotoXY (77,y1);

Write ('*');

end;

assign(f4,'d:\kkk\avtor.pas');

reset(f4);

d:=7;

While not EOF (f4) do

begin

textcolor(10);

readln(f4,prav);

GotoXY (19,d);

Write (prav);

d:=d+2;

for i:=1 to 4 do

Delay (59000);

end;

close(f4);

readln;

end;

if k2=2 then

TextBackground (0);

textcolor(15);

end;

Procedure Resultat;

begin

clrscr;

reset(f1);

for i:=1 to 10 do

begin

readln(f1,us[i].name);

end;

close(f1);

reset(f2);

for i:=1 to 10 do

read(f2,us[i].resultat);

close(f2);

gotoXy(25,12);

If schot>us[10].resultat then

begin

writeln('Ваш результат составил: ', schot);

gotoxy(30,13);

writeln('Введите ваше имя...');

gotoxy(36,14);

read(namen);

end

else

begin

GotoXY(23,13);

writeln('Вы не побили самый худший результат!!! :(');

GotoXY(13,14);

writeln('Но не огорчайтесь!!! Вы можете просто написать ваше имя!!!)))');

GotoXY(36,15);

readln(namen);

end;

us[11].name:=namen;

us[11].resultat:=schot;

for i:=1 to 11 do

for j:=2 to 11 do

begin

if us[j].resultat>us[j-1].resultat then

begin

aa:=us[j-1];

us[j-1]:=us[j];

us[j]:=aa;

end;

end;

rewrite(f1);

for i:=1 to 10 do

begin

write(f1,us[i].name);

writeln(f1,' ');

end;

close(f1);

rewrite(f2);

for i:=1 to 10 do

write(f2,us[i].resultat);

close(f2);

rewrite(f3);

for i:=1 to 10 do

writeln(f3,i,': ',us[i].resultat,' ',us[i].name);

close(f3);

end;

begin

assign (f3,'d:\kkk\itog.txt');

assign (f1,'d:\kkk\imena.txt');

assign (f2,'d:\kkk\rec.dat');

repeat

repeat

Clrscr;

TextBackground (0);

TextColor (15);

For X1:=25 to 55 do

Begin

GotoXY (X1,4);

Write ('*');

GotoXY (X1,22);

Write ('*');

end;

For Y1:=4 to 22 do

begin

GotoXY (25,Y1);

Write ('*');

GotoXY (55,Y1);

Write ('*');

end;

K:=0;

Repeat

k:=k+kk;

kk:=0;

If k=0 Then Ramka (30,6,' ИГРАТЬ ',128) else

Ramka (30,6,' ИГРАТЬ ',15);

If k=1 Then Ramka (30,10,' РЕКОРДЫ ',128) else

Ramka (30,10,' РЕКОРДЫ ',15);

If k=2 then Ramka (30,14,' СПРАВКА ',128) else

Ramka (30,14,' СПРАВКА ',15);

If k=3 then Ramka (30,18,' ВЫХОД ',128) else

Ramka (30,18,' ВЫХОД ',15);

Kno:=ReadKey;

If Kno=#80 then Begin if k<3 then kk:=1 else kk:=0; end else

if Kno=#72 then Begin if k>0 then kk:=-1 else kk:=0; end;

until Kno=chr(13);

If k=1 then

begin

Clrscr;

GotoXy(36,5);

writeln('РЕКОРДЫ');

reset (f3);

for i:=1 to 10 do

begin

readln(f3,resul);

GotoXY (32,7+i);

Write(resul);

end;

close(f3);

Readln;

end;

If k=2 then

repeat

spravka;

until k2=2;

If k=3 then

exit;

until (k=3) or (k=0);

If k=0 then begin

menu2 (' УРОВЕНЬ СЛОЖНОСТИ',' ГЛИСТ ',' ЗМЕЯ ',' АНАКОНДА ');

end;

If K2=0 then begin Sl:=40000; och:=25; d:=5 end else if k2=1 then begin

Sl:=30000; och:=50; d:=10 end else begin Sl:=20000; och:=100; d:=15 end;

TextBackground (1);

Textcolor (5);

clrscr;

schot:=0; playE:=1;

Xz[1]:=30;

Yz[1]:=13;

For i:=2 to 40 do

begin

Xz[i]:=Xz[1];

Yz[i]:=Yz[1];

end;

For X1:=3 to 57 do

Begin

GotoXY (x1,2);

Write ('*');

GotoXY (X1,23);

write ('*');

end;

For Y1:=2 to 23 do

Begin

GotoXY (3,Y1);

Write ('*');

GotoXY (57,y1);

Write ('*');

end;

Play:=1;

GotoXY(60,4);

write('СЧЕТ: ');

GotoXY(60,6);

write('Рост змеи: ');

gotoXY(60,8);

write('Лучшие результаты:');

reset(f3);

for i:=1 to 3 do

begin

readln(f3,resul);

GotoXY (60,9+i);

Write(resul);

end;

close(f3);

Repeat

If play=1 then begin

TextColor (4);

Ax:=xz[1]; Ay:=Yz[1];

Xz[1]:=Xz[1]+H; Yz[1]:=Yz[1]+W;

Bx:=Xz[2]; By:=Yz[2];

Xz[2]:=Ax; Yz[2]:=Ay;

For i:=3 to 40 do

izm(i);

GotoXY (Xz[1],Yz[1]);

write(chr(1));

For i:=2 to d do

begin

GotoXY (Xz[i],Yz[i]);

Write(chr(4));

end;

Delay(SL);

Textcolor (1);

GotoXY (Xz[1],Yz[1]);

write(chr(1));

For i:=2 to 40 do

begin

GotoXY (Xz[i],Yz[i]);

Write(chr(4));

end;

randomize;

if PlayE=1 then

begin

Ex:=Random(54)+4;

Ey:=random(18)+4;

If (K2=0) and (schot<>0) and ((schot mod 75)=0) then

d:=d+1;

if (k2=0) and (schot<>0) and ((schot mod 150)=0) then

Sl:=Sl-500;

If (K2=1) and (schot<>0) and ((schot mod 150)=0) then

d:=d+1;

if (k2=1) and (schot<>0) and ((schot mod 500)=0) then

Sl:=Sl-500;

If (K2=2) and (schot<>0) and ((schot mod 500)=0) then

d:=d+1;

if (k2=2) and (schot<>0) and ((schot mod 1000)=0) then

Sl:=Sl-500;

PlayE:=0; end;

Textcolor (6);

GotoXY(Ex,Ey);

write(chr(6));

if (Xz[1]=Ex) and (Yz[1]=Ey) then

begin

schot:=schot+och;

PlayE:=1;

Textcolor (1);

GotoXy(Ex,Ey);

write (' ');

end;

Case Kno of

#72: Begin W:=-1; H:=0; end;

#80: Begin W:=1; H:=0; end;

#77: Begin W:=0; H:=1; end;

#75: Begin W:=0; h:=-1; end;

end;

If Keypressed=true then begin onk:=readkey;Kno:=Readkey; end;

end;

GotoXY(66,4);

write(Schot);

GotoXY(70,6);

write(d);

sa:=10;

stolknovenie;

until Play=0;

If play=0 then begin

TextBackground (0);

Textcolor (15);

clrscr;

GotoXY(6,8);

write(' ***** ***** * * ******* ***** ** ** ******* ****** ');

GotoXY(6,9);

write('******* ******* ** ** ******* ******* ** ** ******* *******');

GotoXY(6,10);

write('** ** ** *** *** ** ** ** ** ** ** ** **');

GotoXY(6,11);

write('** ** ** **** **** ** ** ** ** ** ** ** **');

GotoXY(6,12);

write('** ** ** ** *** ** **** ** ** ** ** **** ** **');

GotoXY(6,13);

write('** ** ******* ** * ** **** ** ** ** ** **** ****** ');

GotoXY(6,14);

write('** *** ******* ** ** ** ** ** ** ** ** **** ');

GotoXY(6,15);

write('** ** ** ** ** ** ** ** ** ** ** ** ** ** ');

GotoXY(6,16);

write('******* ** ** ** ** ******* ******* *** ******* ** ** ');

GotoXY(6,17);

write(' ***** ** ** ** ** ******* ***** * ******* ** **');

GotoXY(25,23);

Write('Для продолжения нажмите ENTER');

repeat

kno:=readkey;

until Kno=chr(13);

end;

resultat;

H:=0; w:=0; k:=0; kk:=0;

until k=3; end.