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



бет5/6
Дата31.03.2022
өлшемі4,56 Mb.
#137333
1   2   3   4   5   6
Байланысты:
Змейка

2.2 Разработка модели


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

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


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


Были использованы следующие процедуры:

Процедура создана для отрисовки змеи на экране.


procedure TMainForm.CopySnake;
var
i,j: Integer;
begin
{очистка экрана}
for i := 0 to AREAWIDTHCELLCOUNT - 1 do
for j := 0 to AREAHEIGHTCELLCOUNT - 1 do
if AREA[i,j] <> Point then AREA[i,j] := Empty;

{наносим змею}


for i := 0 to Length(Snake) - 1 do
AREA[Snake[i].X,Snake[i].Y] := Tail;
end;

procedure TMainForm.SetPoint;


var
x,y: Integer;
begin
Timer.Enabled := False;

x := Random(AREAWIDTHCELLCOUNT);


y := Random(AREAHEIGHTCELLCOUNT);

{если точка попала не на пустое место, ещем новое место для нее до тех пор пока


не найдем пустое}
if(AREA[x,y] <> Empty) then begin
SetPoint;
Exit;
end;

AREA[x,y] := Point;


Timer.Enabled := True;
end;

Данная процедура осуществляет движение нашей змейки.


procedure TMainForm.PullSnake(X,Y: Integer);
begin
SetLength(Snake, Length(Snake)+1);
Snake[Length(Snake)-1].X := X;
Snake[Length(Snake)-1].Y := Y;

Inc(SCORE);


StatusBar.Panels[3].Text := IntToStr(SCORE);
end;

Процедура отвечает за старт игры и создание первоначальных корординат


procedure TMainForm.GameStart;
var
i,j: Integer;
begin
{чистим поле}
for i := 0 to AREAWIDTHCELLCOUNT - 1 do
for j := 0 to AREAHEIGHTCELLCOUNT - 1 do
AREA[i,j] := Empty;

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


{status bar}
StatusBar.Panels[4].Text := ''; {состояние игры [пауза, конец]}
StatusBar.Panels[3].Text := '0'; {очки}
StatusBar.Panels[1].Text := '1'; {уровень}
LEVEL := 1;
SCORE := 0;
{змея}
SetLength(Snake,2);
Snake[0].X := 1; Snake[0].Y := 0; {путь [0,0] будет ведущей головой змеи}
Snake[1].X := 0; Snake[1].Y := 0;
CopySnake;
SetPoint;
{в очереди всегда должно быть одно направление}
DirectQueue[0] := ddRight;
DirectCount := 1;

CurINTERVAL := 1000;


Timer.Interval := CurINTERVAL;
Timer.Enabled := True;
NewGame := True;
end;

Процедура создания игрового поля.


procedure TMainForm.FormCreate(Sender: TObject);
begin
Randomize;
MainPanel.DoubleBuffered := True;
PaintBox.Width := AREAWIDTHCELLCOUNT * CELLSIZEPX;
PaintBox.Height := AREAHEIGHTCELLCOUNT * CELLSIZEPX;
end;

procedure TMainForm.FormResize(Sender: TObject);


begin
PaintBox.Left := (MainForm.ClientWidth div 2) - (PaintBox.Width div 2);
PaintBox.Top := (MainForm.ClientHeight div 2) - (PaintBox.Height div 2);
end;

procedure TMainForm.PaintBoxPaint(Sender: TObject);


var
i,j: Integer;
begin
{визуализация матрицы}
for i := 0 to AREAWIDTHCELLCOUNT - 1 do begin
for j := 0 to AREAHEIGHTCELLCOUNT - 1 do begin
if AREA[i,j] = Empty then
begin
PaintBox.Canvas.Brush.Color := AREABACKGROUNDCOLOR;
PaintBox.Canvas.Pen.Color := AREABACKGROUNDCOLOR;
PaintBox.Canvas.Rectangle(i*CELLSIZEPX,j*CELLSIZEPX,i*CELLSIZEPX+CELLSIZEPX,
j*CELLSIZEPX+CELLSIZEPX);
end;
if AREA[i,j] = Tail then
begin
PaintBox.Canvas.Brush.Color := TAILCOLOR;
PaintBox.Canvas.Pen.Color := clYellow;
PaintBox.Canvas.Rectangle(i*CELLSIZEPX,j*CELLSIZEPX,i*CELLSIZEPX+CELLSIZEPX,
j*CELLSIZEPX+CELLSIZEPX);
end;
if AREA[i,j] = Point then
begin
PaintBox.Canvas.Brush.Color := POINTCOLOR;
PaintBox.Canvas.Pen.Color := clYellow;
PaintBox.Canvas.Rectangle(i*CELLSIZEPX,j*CELLSIZEPX,i*CELLSIZEPX+CELLSIZEPX,
j*CELLSIZEPX+CELLSIZEPX);
end;
end;
end;
{черная рамка}
PaintBox.Canvas.Pen.Color := clBlack;

PaintBox.Canvas.MoveTo(0,0);


PaintBox.Canvas.LineTo(PaintBox.Width,0);

PaintBox.Canvas.MoveTo(PaintBox.Width-1,0);


PaintBox.Canvas.LineTo(PaintBox.Width-1, PaintBox.Height);

PaintBox.Canvas.MoveTo(PaintBox.Width,PaintBox.Height-1);


PaintBox.Canvas.LineTo(0, PaintBox.Height-1);

PaintBox.Canvas.MoveTo(0,PaintBox.Height);


PaintBox.Canvas.LineTo(0,0);
end;

Процедура осуществляет движение хвоста змейки в направлении выбранном пользователем.


procedure TMainForm.ShiftSnake;
var
i: Integer;
eX,eY: Integer;
begin
Timer.Enabled := False;
eX := Snake[Length(Snake)-1].X;
eY := Snake[Length(Snake)-1].Y;
{подтянули на 1 хвост, залезли на голову}
for i := Length(Snake) - 1 downto 1 do
begin
Snake[i].X := Snake[i-1].X;
Snake[i].Y := Snake[i-1].Y;
end;

{сместили очередь}


if(DirectCount > 1) then begin
for i := 0 to DirectCount-2 do
DirectQueue[i] := DirectQueue[i+1];
Dec(DirectCount);
end;

{высунули голову, повернули}


case DirectQueue[0] of
ddRight: Snake[0].X := Snake[0].X + 1;
ddLeft: Snake[0].X := Snake[0].X - 1;
ddUp: Snake[0].Y := Snake[0].Y - 1;
ddDown: Snake[0].Y := Snake[0].Y + 1;
end;

{налет на точку}


if(AREA[Snake[0].X,Snake[0].Y] = Point) then begin
{добавить в конец}
PullSnake(eX,eY);
{поставить новую точку}
SetPoint;
end;

{врезались в стену}


if ((Snake[0].X+1) > AREAWIDTHCELLCOUNT) then begin {правая стена}
GameOver;
Exit;
end;

if ((Snake[0].X) < 0) then begin {левая стена}


GameOver;
Exit;
end;

if ((Snake[0].Y+1) > AREAHEIGHTCELLCOUNT) then begin {низняя стена}


GameOver;
Exit;
end;

if ((Snake[0].Y) < 0) then begin {верхняя стена}


GameOver;
Exit;
end;
{end врезались в стену}

{врезались сами в себя (можно убрать этот цикл, тогда змея


сможет лазить через себя)}
for i := 1 to Length(Snake) - 1 do
if(Snake[0].X = Snake[i].X) and (Snake[0].Y = Snake[i].Y) then begin
GameOver;
Exit;
end;

{нанесли новое положения змеи если никуда не врезались}


CopySnake;
Timer.Enabled := True;
end;

procedure TMainForm.TimerTimer(Sender: TObject);


begin
ShiftSnake;
PaintBox.Repaint;

{переход на следующий уровень, на каждом новом уровне интервал таймера


уменьшается на 50мс}
if(MAXSnakeLEN < Length(Snake)) then begin
SetLength(Snake,2);
Inc(LEVEL);
StatusBar.Panels[1].Text := IntToStr(LEVEL);
{на 20ом уровне интервал будет равен 50мс}
if(LEVEL <= 20) then begin
CurINTERVAL := CurINTERVAL - 50;
Timer.Interval := CurINTERVAL
end else
Timer.Interval := 15; {удачи}
end;

end;

procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
Direction: TDirection;
begin
{последнее напраление перед последующим нажатием}
Direction := DirectQueue[DirectCount-1];
{ускорение}
if (Key = 38) and (Direction = ddUp) then Timer.Interval := 50;
if (Key = 40) and (Direction = ddDown) then Timer.Interval := 50;
if (Key = 39) and (Direction = ddRight) then Timer.Interval := 50;
if (Key = 37) and (Direction = ddLeft) then Timer.Interval := 50;

{при быстром последовательном нажатии клавиш (к примеру 38->37), змея не успеет


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

{добавляем нажатые клавиши в очередь направлений, если очередь привышает


границы массива, то просто меняем последний елемент}
if Key = 38 then
begin
if(Direction <> ddDown) and (Direction <> ddUp) then begin
Direction := ddUp;
DirectQueue[DirectCount] := Direction;
if(DirectCount < (QueueLEN-1)) then Inc(DirectCount);
end;
end;

if Key = 40 then


begin
if(Direction <> ddUp) and (Direction <> ddDown) then begin
Direction := ddDown;
DirectQueue[DirectCount] := Direction;
if(DirectCount < (QueueLEN-1)) then Inc(DirectCount);
end;
end;

if Key = 39 then


begin
if(Direction <> ddLeft) and (Direction <> ddRight) then begin
Direction := ddRight;
DirectQueue[DirectCount] := Direction;
if(DirectCount < (QueueLEN-1)) then Inc(DirectCount);
end;
end;

if Key = 37 then


begin
if(Direction <> ddRight) and (Direction <> ddLeft) then begin
Direction := ddLeft;
DirectQueue[DirectCount] := Direction;
if(DirectCount < (QueueLEN-1)) then Inc(DirectCount);
end;
end;

end;

procedure TMainForm.FormKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
{вернуть скорость после ускорения}
Timer.Interval := CurINTERVAL;
end;
{MAIN MENU}
procedure TMainForm.INewClick(Sender: TObject);
begin
GameStart;
end;

В каждой игре должна быть предусмотрена пауза. Отображение остановки игры отображается на СтатусБаре.


procedure TMainForm.IPauseClick(Sender: TObject);
begin
if NewGame then begin
if Timer.Enabled then begin
Timer.Enabled := False;
StatusBar.Panels[4].Text := 'PAUSE';
end else begin
Timer.Enabled := True;
StatusBar.Panels[4].Text := '';
end;
end;
end;

Процедура осуществляет выход с программы.


procedure TMainForm.IExitClick(Sender: TObject);
begin
Application.Terminate;
end;
Данная процедура показывает форму, об авторе.
procedure TMainForm.IAboutClick(Sender: TObject);
begin
AboutBox.ShowModal;
end;



Рисунок 3.1 – главное окно игры

На экране вы можете видеть главное окно игры. Где пользователь может ознакомиться с интерфейсом программы.





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

Рисунок 3.4 – Об авторе
На экране отображена информация об разработчике курсового проекта.


Достарыңызбен бөлісу:
1   2   3   4   5   6




©engime.org 2024
әкімшілігінің қараңыз

    Басты бет