Паскаль создание игр. Создание компьютерной игры на языке Pascal

Textual {Игра сапер} uses GraphABC,ABCObjects,ABCButtons; Const N = 10; //Поле N х N sz = 40; //Размер клетки d0 = 10; //Отступ от левого и верхнего края zz = 2; //Растояние между ячейками NMines = 10; //Количество мин Type OneSellField = record mine: boolean; //Есть ли мина fl: boolean; //Есть ли флажок neighbours: integer; //полож.-Сколько соседей; отриц - нужны для алгоритма трассировки - открытия пустых клеток click: boolean; //Была ли открыта end; Var BtNewGame: ButtonABC; Sell: array of SquareABC; Field: array of OneSellField; c: shortint; //Для подсчета мин в соседних клетках Opened: shortint; //Сколько флажков правильно поставленно Nfl: Integer; //Количество поставленных флажков (для победы должно быть равно кол. мин) Procedure CreateField; begin for var y:= 1 to N do for var x:= 1 to N do begin Sell := new SquareABC(d0+(x-1)*(sz+zz),d0+(y-1)*(sz+zz), sz, clLightSeaGreen); Sell.BorderColor:= clGreen; Sell.BorderWidth:= 2; Sell.TextScale:= 0.7; end; end; Procedure NewGame; var Rx, Ry: integer; begin for var j:=1 to N do for var i:=1 to N do begin Field.mine:= false; Field.click:= false; Field.fl:= false; Field.neighbours:= 0; Sell.BorderColor:= clGreen; Sell.Text:= ""; Sell.Color:= clLightSeaGreen; end; //Размещаем мины for var i:= 1 to NMines do begin Rx:= Random(N)+1; Ry:= Random(N)+1; //Если в выбранной ячейки есть мины, то генерируем новые координаты мины while Field.mine do begin Rx:= Random(N)+1; Ry:= Random(N)+1; end; Field.mine:= true; end; { //Временная подсказка где мины for var j:=1 to N do for var i:=1 to N do begin if Field.mine then Sell.BorderColor:= clYellow; end; } var ii, jj:shortint; //Считаем мины вокруг for var j:=1 to N do for var i:=1 to N do begin c:= 0; for var dx:= -1 to 1 do begin for var dy:= -1 to 1 do if not ((dx = 0) and (dy = 0)) then begin ii:= i + dx; jj:= j + dy; if ((ii > 0) and (ii <= N) and (jj > 0) and (jj <= N)) then begin c:= c + Integer(Field.mine); end; end; end; Field.neighbours:= c; end; Opened:= 0; //Кол. открытых мин Nfl:= 0; //Кол. установленных флажков end; Procedure OpenZero(fx, fy: integer); var fl:boolean; step, ii, jj: integer; begin Field.neighbours:= -1; step:= -1; repeat fl:= true; for var x:= 1 to N do begin for var y:= 1 to N do begin if Field.neighbours < 0 then begin {*** Проверка соседних клеток ***} for var dx:= -1 to 1 do begin for var dy:= -1 to 1 do if not ((dx = 0) and (dy = 0)) then begin //Центральную клетку не считаем ii:= x + dx; jj:= y + dy; //Если не выходит за границы поля if ((ii > 0) and (ii <= N) and (jj > 0) and (jj <= N)) then begin if Field.neighbours = 0 then begin Sleep(30); //Для анимации открывания клеток Sell.Color:= clLightYellow; Field.click:= true; Field.neighbours:= step; fl:= false; //Была открыта клетка - ищем др. end; if Field.neighbours > 0 then begin Sell.Color:= clLightGreen; Sell.Text:= IntToStr(Field.neighbours); Field.click:= true; end; end; end; end; {********************} end; end; end; step:= step - 1; until fl; end; Procedure MouseDown(x, y, mb: integer); begin if ObjectUnderPoint(x,y)=nil then // Eсли мы щелкнули не на объекте, то не реагировать на мышь exit; var fx:= (x-d0) div (sz+zz) + 1; // Вычислить координаты на доске для ячейки, на которой мы щелкнули мышью var fy:= (y-d0) div (sz+zz) + 1; Field.click:= true; if mb = 1 then begin //Если щелкнули по мине if Field.mine then begin Sell.Text:= "M"; Sell.Color:= clRed; //writeln("Проиграл!"); end else begin //Если щелкнули по пустой клетке if (Field.neighbours = 0) then begin Sell.Color:= clLightYellow; if Field.fl then Sell.Text:= ""; //Вызов процедуры раскрытия пустых полей OpenZero(fx, fy); end else if Field.neighbours > 0 then begin Sell.Color:= clLightGreen; Sell.Text:= IntToStr(Field.neighbours); end; end; end; //Ставим и снимаем флажок if mb = 2 then begin if Field.fl then begin //Снимаем флажок Field.fl:= False; Sell.Text:= ""; Sell.Color:= clLightSeaGreen; Nfl -= 1; if (Opened = NMines) and (Nfl = NMines) then writeln("Победа!"); //Window.Title:= IntToStr(Nfl)+" M "+IntToStr(Opened); end else begin //Ставим флажок Field.fl:= true; Sell.Text:= "F"; Sell.Color:= clBlue; Nfl += 1; //Window.Title:= IntToStr(Nfl)+" M "+IntToStr(Opened); end; if Field.mine then begin if Field.fl then Opened += 1 else Opened -= 1; //Window.Title:= IntToStr(Nfl)+" M "+IntToStr(Opened); if (Opened = NMines) and (Nfl = NMines) then writeln("Победа!"); end; end; end; Procedure MouseMove(x, y, mb: integer); begin if ObjectUnderPoint(x,y)=nil then // Eсли мы щелкнули не на объекте, то не реагировать на мышь exit; var fx:= (x-d0) div (sz+zz) + 1; // Вычислить координаты на доске для ячейки, на которой мы щелкнули мышью var fy:= (y-d0) div (sz+zz) + 1; {Все клетки зеленые} for var j:= 1 to N do for var i:= 1 to N do begin if not Field.click then Sell.Color:= clLightSeaGreen; end; {Все клетки зеленые, а над которой мышка - ярко зеленая} if not Field.click then Sell.Color:= clLightGreen; end; BEGIN SetSmoothingOff; //Отключаем сглаживание Window.Title:= "Сапёр"; Window.IsFixedSize:= True; CreateField;//Создаем поле btNewGame:= ButtonABC.Create(535, d0, 100, "Новая игра", clSkyBlue); btNewGame.OnClick:= NewGame; NewGame; OnMouseDown:= MouseDown; OnMouseMove:= MouseMove; END.

Сейчас среди начинающих игроделов царит мнение, что для написания типичной 2D аркады на PC необходимо обзавестись крутым движком или конструктором, а также нехило знать столь престижный C++, оттого найти стоящую статью по Pascal практически невозможно. Но сегодня я решил попробовать сломать застоявшиеся стереотипы, написав небольшой урок по разработке простенького платформера. Итак, усаживайтесь удобнее, курс «просвещения» начинается…

1. Что необходимо?
Различных сред, использующих в качестве языка программирования Pascal, превеликое множество. Но из всей этой кучи для урока я решил использовать именно PascalABC.net. Почему? Ответ прост: во-первых данная среда программирования использует не чистый Паскаль, а его современный и более удобный потомок – Object Pascal; во-вторых Паскаль.Нет абсолютно бесплатна, а значит вам не придется парится с кряками или тратить деньги на лицензию.

2. Алгоритм.
Итак, у нас есть площадь 640x480, которая по моей задумке будет делиться на клеточки размером 8x8, представляющие из себя звенья массива s. Таким образом, меняя значение клеточки, мы можем сделать ее «свободной», либо «занятой» (к примеру, использовать как стену).

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

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

Листинг 1:

200?"200px":""+(this.scrollHeight+5)+"px");">uses GraphABC;

Var
s: array [,] of integer;
i,x,y,vspeed: integer;
game_end: boolean;

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

Листинг 2:

200?"200px":""+(this.scrollHeight+5)+"px");">//Обработка нажатий клавиш
procedure KeyPress(key: char); begin

If (key="d") and (s[(x div 8)+1,(y div 8)]=0) then //Если нажата клавиша D…
x:=x+8; //... А также есть свободное место, то передвигаемся на…
//… клеточку вперед (значение x увеличивается на 8)

If (key="a") and (s[(x div 8)-1,(y div 8)]=0) then //см. комментарий выше
x:=x-8;

If (key="w") and (vspeed=0) and (s[(x div 8),(y div 8)+1]=1) then //Если есть «занятая клеточка»…
vspeed:=-16; //… под ногами, то совершаем прыжок.

Procedure KeyDown(key: integer); begin
if (key=vk_enter) then game_end:=true; //При нажатии ENTER…
//значение переменной game_end равно true
end;

5. Гравитация.
Неотъемлемой частью платформера является какая никакая, а сила тяжести. Поэтому сейчас мы должны написать отдельную процедуру, которая в дальнейшем поможет игроку встать на ноги в буквальном смысле.

Листинг 3:

200?"200px":""+(this.scrollHeight+5)+"px");">//Гравитация
procedure Gravity(); begin

If vspeed=0 then begin //Если скорость прыжка равна нулю…
if s[(x div 8),(y div 8)+1]=0 then y+=8; //… перемещаемся на «клеточку» вниз (падаем)
end;

If s[(x div 8),(y div 8)+vspeed]=0 then y+=vspeed; //Если сверху есть свободная клеточка, то…
//… перемещаемся на vspeed вверх.

If vspeed<>0 then //Если скорость прыжка не равна нулю (в нашем случае: меньше нуля)…
vspeed+=2; //… то помаленьку ее сбавляем.

6. Рисование.
Думаю тут понятно без лишних слов, но для галочки отмечу, что игра делится на «визуальную» и «невизуальную» части. «Невизуальная» отвечает за все происходящее в самой игре, а «визуальная», собственно, за отображение происходящего на экране. Так вот, данная ниже процедура отвечает за «визуальную» часть и только.

Листинг 4:

200?"200px":""+(this.scrollHeight+5)+"px");">procedure Draw(); begin

Redraw;
LockDrawing;

//Рисуем белый прямоугольник…
setbrushcolor(clwhite); //… размером 640 на 480
fillrectangle(0,0,640,480);

Setbrushcolor(clblack);//Рисуем черные стены…
fillrectangle(0,192,640,224);//… по координатам…
//… 0 – 640 по X; 192 – 224 по Y
//(ВНИМАНИЕ! Данные манипуляции не делают стены осязаемыми, а всего лишь…
//… создают их графический образ.

Setbrushcolor(clred); //Рисуем игрока по координатам…
fillrectangle(x,y,x+8,y+8);//… x и y

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

Листинг 5:

200?"200px":""+(this.scrollHeight+5)+"px");">Begin //начало программы

//Указания значений для переменных
game_end:=false;
x:=0; //Стартовая позиция игрока по X
y:=0; //Стартовая позиция игрока по Y

//Создание массива
s:= new integer;

//Создание платформы, нарисованной в процедуре Draw
for i:=0 to 79 do
s := 1;

While game_end=false do begin //Создаем цикл…
//… который прервется, если game_end = false

//Рисование экрана
Draw();

//Гравитация для игрока
Gravity();

OnKeyPress:=KeyPress; //Обработка нажатий…
OnKeyDown:=KeyDown; //… клавиш

Sleep(30); //Ждем примерно полсекунды, чтобы игра…
//… работала с нормальной скоростью

End;//конец цикла.

End. //конец программы

8. Заключение.
Итого у нас получился незамысловатый платформер с точкой в главной роли. Мы можем передвигаться по горизонтали и прыгать:

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

Сегодня несложные игры, где нет ни графических, ни звуковых эффектов, переживают второе рождение. Играя в них, пользователь сосредотачивается на сюжете, а не на художественных приемах. Для создания таких игр хорошо подходит язык Паскаль.

Инструкция

  • Скачайте компилятор языка Паскаль со следующей страницы - http://edn.embarcadero.com/article/20803. Ознакомьтесь с условиями использования данного программного пакета, после чего установите его.
  • Попробуйте создать игру, в которой от игрока требуется угадать число в интервале от 0 до 100. Вначале введите название программы:program ugadayka;
  • Подключите модуль CRT:uses crt;
  • Обозначьте переменные следующим образом:var
  • zagadka,mnenie,popytki:integer;

  • Начните программу с очистки экрана и переменных, а также присвоения загаданному числу псевдослучайного значения:begin
  • zagadka:=int(rnd*100);

  • Заставьте компьютер спрашивать у пользователя, каким, по его мнению, является загаданное число, до тех пор, пока он его не угадает:while not mnenie=zagadka do
  • popytki:=popytki+1;

    writeln("Попытка номер ",popytki,".");

    write("Как ты думаешь, какое число загадано? ");

    if zagadka>mnenie then writeln("Нет, загаданное число больше!")

    else writeln("Нет, загаданное число меньше!")

  • После того как число будет угадано, автоматическое повторение указанных выше событий прекратится. Начнется выполнение следующих строк программы. В них заставьте машину вывести информацию о том, что пользователь угадал число:writeln("Поздравляю! Ты угадал число с попытки номер ",popytki,". Оно действительно равно ",zagadka,".");
  • knopochka:=readkey

  • Введите оператор для завершения работы программы:end.
  • Сохраните программу под любым желаемым именем, используя пункты меню file -> Save as. В дальнейшем после каждого редактирования сохраняйте ее нажатием клавиши F2.
  • Для запуска программы на исполнения нажмите одновременно клавиши Control и F9.
  • После завершения работы программы для того, чтобы увидеть, что она вывела на экран непосредственно перед этим, нажмите одновременно клавиши Alt и F5. Для возврата к редактору нажмите это же сочетание клавиш еще раз.
  • Начинающему программисту не стоит сразу браться за написание на языке Паскаль сложной, многоуровневой игровой программы. Начать следует с логической или математической игры с текстовым интерфейсом. Постепенно набираясь опыта, можно переходить к работе над более крупными проектами.

    Инструкция

  • Начните работу над программой с заголовка и указания перечня используемых подключаемых модулей:program reshiprimer;uses crt;
  • Укажите компилятору, какие в состав программы будут входить переменные:vara,b,c:integer;d:string;Здесь a и b - слагаемые, c - сумма, d - ответ на вопрос о том, желает ли пользователь играть дальше.
  • Обозначьте начало программы и бесконечного цикла, а также инициализируйте генератор случайных чисел:beginrandomize;while 0=0 dobegin
  • Запрограммируйте генерацию двух случайных чисел в диапазоне от 0 до 1000:a:=round(random(1000));b:=round(random(1000));
  • Покажите пользователю пример, который он должен решить, а затем запросите результат:writeln("Сколько будет"),a,("+"),b,("?");readln(c);
  • Сообщите пользователю, правильно ли он решил пример:if a+b=c then writeln("Правильно!") else writeln("Неправильно!);
  • Спросите у пользователя, желает ли он играть еще:writeln("Будем играть дальше?");readln(d);
  • При отрицательном ответе завершите работу программы:if upcase(d)"Y" then halt(0);
  • Завершите сначала цикл, а затем и саму программу:endend.Обратите внимание на точку после второго оператора end.
  • Запустите программу, нажав Ctrl+F9. На экран будет выведен первый пример. Сосчитайте в уме и введите ответ на него. Машина тут же сообщит вам, правильно ли он решен. Затем будет задан вопрос о том, желаете ли вы играть дальше. Ответ Y или y приведет к выводу следующего примера, а ввод любой другой буквы - к завершению работы программы.
  • Добившись правильной работы игры, приступите к ее усовершенствованию. Например, добавьте очистку экрана перед показом каждого нового примера командой cls. Используя процедуру textcolor, сделайте, чтобы надписи выводились различными цветами. Подумайте, как можно заставить программу автоматически менять сложность примеров: при правильных ответах усложнять их, а при неправильных - упрощать. Чтобы разнообразить игру, добавьте функцию генерации примеров на различные математические действия.