К оглавлению | Назад | Вперёд
Все программы, код которых выложен здесь, являются работоспособными. Ниже приведены возможные варианты реализации игр «Крестики-нолики» и «Змейка» на PascalABC.Net 3.0.
Крестики-нолики[править]
Описание алгоритма |
---|
|
Управление:
- Левая кнопка мыши — установить крестик/нолик.
uses GraphABC; const N = 2; Z = '0'; K = 'X'; Size = 200; Border = 1; Sx = 1200; Sy = 70; var Matrix: array [0..N, 0..N] of char; Player1: boolean; procedure Draw(); procedure DrawZ(i, j: integer); begin SetPenColor(clCyan); SetPenWidth(4); var size2 := Size div 2; DrawCircle((i + 1) * Size - size2, (j + 1) * Size - size2, Round(size2 * 0.7)); end; procedure DrawK(i, j: integer); procedure RLine(x, y, x1, y1: real):=Line(Round(x), Round(y), Round(x1), Round(y1)); begin SetPenColor(clPink); SetPenWidth(4); var size2 := Size div 2 * 0.3; var cx1 := i * Size + size2; var cy1 := j * Size + size2; var cx2 := (i + 1) * Size - size2; var cy2 := (j + 1) * Size - size2; RLine(cx1, cy1, cx2, cy2); RLine(cx1, cy2, cx2, cy1); end; begin ClearWindow(clBlack); if Player1 then SetWindowCaption('Ходит первый игрок') else SetWindowCaption('Ходит второй игрок'); for var i := 0 to N do for var j := 0 to N do begin SetPenColor(clLightBlue); SetPenWidth(1); DrawRectangle(i * Size + Border, j * Size + Border, (i + 1) * Size - Border, (j + 1) * Size - Border); if Matrix[i, j] = Z then DrawZ(i, j) else if Matrix[i, j] = K then DrawK(i, j); end; Redraw(); end; function Won(c: char): boolean; var count: byte; begin Result := false; for var i := 0 to N do begin count := 0; for var j := 0 to N do if Matrix[i, j] = c then Inc(count); if count = 3 then Result := true; end; if not Result then begin for var i := 0 to N do begin count := 0; for var j := 0 to N do if Matrix[j, i] = c then Inc(count); if count = 3 then Result := true; end; if not Result then begin count := 0; for var i := 0 to N do if Matrix[i, i] = c then Inc(count); if count = 3 then Result := true; if not Result then begin count := 0; for var i := 0 to N do if Matrix[N - i, i] = c then Inc(count); if count = 3 then Result := true; end; end; end; end; function IsFull(): boolean; begin Result := true; for var i := 0 to N do for var j := 0 to N do if (Matrix[i, j] <> Z) and (Matrix[i, j] <> K) then begin Result := false; break; end; end; procedure MouseDown(x, y, mb: integer); procedure ShowWinner(s: string; c: Color); begin SetWindowCaption('Результат игры'); Sleep(2000); SetWindowSize(Sx, Sy); CenterWindow(); ClearWindow(clBlack); SetFontSize(16); SetFontStyle(fsBold); SetFontColor(c); DrawTextCentered(0, 0, Sx, Sy, s); Redraw(); Sleep(2000); Halt(); end; begin var i := x div Size; var j := y div Size; if (Matrix[i, j] <> Z) and (Matrix[i, j] <> K) then begin if Player1 then Matrix[i, j] := Z else Matrix[i, j] := K; Draw(); var winnerExists := Won(Z) or Won(K); if winnerExists then if Player1 then ShowWinner('Игрок первый победил!', clLightBlue) else ShowWinner('Игрок второй победил!', clLightBlue); if IsFull() and not winnerExists then ShowWinner('Ничья!', clOrange); Player1 := not Player1; end; end; begin var Size2 := Size * 3; SetWindowIsFixedSize(true); SetWindowSize(Size2, Size2); CenterWindow(); LockDrawing(); Player1 := true; Draw(); OnMouseDown := MouseDown; end.
Змейка[править]
==Упрощенный вариант== (просто змейка которой можно управлять)
Описание алгоритма |
---|
|
Управление:
- W — вверх.
- S — вниз.
- A — влево.
- D — вправо.
uses GraphABC; const Size = 20; var Snake: List<Point>; procedure Draw(); begin ClearWindow(); Polyline(Snake.ToArray()); var c := Snake.Count - 1; Circle(Snake[c].X, Snake[c].Y, 5); Redraw(); end; procedure KeyDown(Key: integer); begin var c := Snake.Count - 2; case Key of VK_Left: begin Snake.RemoveAt(0); Snake.Add(new Point(Snake[c].X - Size, Snake[c].Y)); end; VK_Right: begin Snake.RemoveAt(0); Snake.Add(new Point(Snake[c].X + Size, Snake[c].Y)); end; VK_Up: begin Snake.RemoveAt(0); Snake.Add(new Point(Snake[c].X, Snake[c].Y - Size)); end; VK_Down: begin Snake.RemoveAt(0); Snake.Add(new Point(Snake[c].X, Snake[c].Y + Size)); end; end; Draw(); end; begin LockDrawing(); SetSmoothingOff(); Snake := new List<Point>(); for var x := 1 to 30 do Snake.Add(new Point(x * Size, Size)); Draw(); OnKeyDown := KeyDown; end.
Возрастающая последовательность[править]
uses GraphABC, ABCObjects; const Border = 100; var Obj: CircleABC; DX, DY: integer; Move: boolean; Numbers: TCircles; function IsEqual(L2: TCircles): boolean; begin Result := true; for var i := 0 to L2.Count - 1 do if Numbers[i].Number <> L2[i].Number then begin Result := false; break; end; end; procedure MouseUp(x, y, mb: integer); procedure MouseMove(x, y, mb: integer); begin if mb = 1 then if not Move then begin for var i := 0 to Numbers.Count - 1 do if Numbers[i].PtInside(x, y) then begin DX := x - Numbers[i].Position.X; DY := y - Numbers[i].Position.Y; Obj := Numbers[i]; Move := true; break; end; end else Obj.Position := new Point(x - Dx, y - Dy); end; begin var W := Window.Width - 2 * Border; var H := Window.Height - 2 * Border; Numbers := new TCircles(); for var i := 0 to 6 do end Numbers.Add(new CircleABC(Border + Random(W), Border + Random(H), 30, clRandom())); Numbers.Last().Number := i; Move := false; OnMouseMove := MouseMove; OnMouseUp := MouseUp; end.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
uses crt,GraphABC; const speed=1; var i,pic,pik,j,h,w,t,d: integer; a:char; begin LockDrawing; i:=200; d:=1; while((i>50) and (i<800)) do begin i:=i+d; setwindowsize(1280,1024); ClearWindow; line(0,300,1600,300); FloodFill(0,200,clMoneyGreen); FloodFill(400,500,clSilver); line(i+380,200,i+410,200); line(i+380,200,i+390,210); line(i+400,210,i+410,200); line(i+100,270,i+120,270); line(i+300,270,i+320,270); line(i+200,270,i+220,270); SetBrushColor(clred); Rectangle(i+20,230,i+100,280); Rectangle(i+120,230,i+200,280); Rectangle(i+220,230,i+300,280); SetBrushColor(clyellow); RoundRect(i+320,200,i+365,280,30,20); SetBrushColor(clSkyBlue); RoundRect(i+320,230,i+420,280,30,20); Rectangle(i+390,230,i+400,210); Rectangle(i+390,230,i+400,210); Rectangle(i+390,230,i+400,210); Rectangle(i+390,230,i+400,210); SetBrushColor(clyellow); circle(i+30,290,10); circle(i+90,290,10); circle(i+130,290,10); circle(i+190,290,10); circle(i+230,290,10); circle(i+230,290,10); circle(i+230,290,10); circle(i+230,290,10); circle(i+290,290,10); circle(i+345,278,22); circle(i+377,288,12); circle(i+400,288,12); if keypressed then begin a:=readkey; d:=-d; if a=chr(32) then d:=d*2; end; Redraw; end; end. |
§19. Клавиатурный тренажёр. Игра «Гонки».
Клавиатурный тренажёр.
Думаю, что каждому, кто дочитал эту книгу до этого места, не терпится написать настоящую программу. Предлагаю написать клавиатурный тренажёр, т.к. если вы собираетесь стать программистом, то вам просто необходимо научиться набирать текст, не глядя в клавиатуру. С помощью такой программы вы сможете этому тренироваться.
Вначале разберём, каким должен быть наш клавиатурный тренажёр, затем можно будет писать код программы.
Клавиатурный тренажёр должен предлагать нажать какую либо клавишу и ждать её нажатия. Если клавиша нажата верно, то он должен предложить нажать следующую, если не верно, то это должно считаться ошибкой, а тренажёр должен ждать нажатия верной клавиши. Количество ошибок должно считаться.
Вначале, в первом уровне, должны предлагаться для нажатия клавиши «J» и «F», т.к. в любой компьютерной клавиатуре на этих клавишах есть небольшие бугорки. Эти бугорки являются ориентиром, относительно которых можно найти все другие клавиши. При наборе текста не глядя в клавиатуру, эти бугорки находятся на ощупь, затем на них устанавливаются указательные пальцы обеих рук. Соответственно эти клавиши «J» и «F» нажимаются указательными пальцами правой и левой рук.
Затем, во втором уровне, необходимо добавить ещё две клавиши, например «D» и «K», т.к. они находятся радом с предыдущими.
Далее, в третьем уровне, должны добавиться ещё две клавиши. В четвёртом – ещё две. И так далее, пока не начнут предлагаться все клавиши.
Клавиши должны каждый раз предлагаться в различных последовательностях.
Для того, что бы не подсматривать в клавиатуру, её необходимо нарисовать на экране, при этом предлагаемые клавиши можно подсвечивать каким либо цветом.
Так же необходимо вывести палец, которым рекомендуется нажимать данную клавишу. Названия пальцев можно обозначить следующим образом:
Далее в таблице приведены клавиши и соответствующие им пальцы:
Q–Л5 |
W–Л4 |
E–Л3 |
R–Л2 |
T–Л2 |
Y–П2 |
U–П2 |
I–П3 |
O–П4 |
P–П5 |
|
A–Л5 |
S–Л4 |
D–Л3 |
F–Л2 |
G–Л2 |
H–П2 |
J–П2 |
K–П3 |
L–П4 |
;–П5 |
‘–П5 |
Z–Л5 |
X–Л4 |
C–Л3 |
V–Л2 |
B–Л1 |
N–П2 |
M–П2 |
,–П3 |
.–П4 |
||
Пробел – П1 |
Внимательно изучите, какую клавишу, каким пальцем необходимо нажимать. Думаю, что логика такого расклада будет вам понятна.
Теперь перейдём непосредственно к программированию.
Клавиатуру можно нарисовать с помощью символов следующим образом:
— — — — — — — — — —
| Q | W | E | R | T | Y | U | I | O | P |
— — — — — — — — — —
— — — — — — — — — — —
| A | S | D | F | G | H | J | K | L | ; | ‘ |
— — — — — — — — — — —
— — — — — — — — —
| Z | X | C | V | B | N | M | , | . |
— — — — — — — — —
Разную последовательность предлагаемых клавиш можно реализовать с помощью функции Random. Для этого можно создать массив клавиш, в котором первые две клавиши «J» и «F» будут иметь индексы 1 и 2, вторые две клавиши «D» и «K» – 3 и 4, и т.д. Для получения случайной клавиши из первых двух, вызовем функцию Random(1,2). Для получения клавиши из четырёх – Random(1,4). Так же в этом же массиве мы можем сохранить координаты X и Y этих клавиш на экранной клавиатуре для того, что бы подсвечивать их, а так же палец, которым нужно их нажимать. Реализовать это можно с помощью типа запись. Т.е. у нас получится массив данных типа запись.
У меня получился следующий код такого клавиатурного тренажёра:
Unit MKlavTren;
uses CRT;
type symbols = record//Тип для хранения клавиш в массиве
number:byte;//Порядковый номер символа клавиши
x:byte;//Координата Х на экранной клавиатуре
y:byte;//Координата У на экранной клавиатуре
p:string[2]//Палец, которым нужно нажимать клавишу
end;
Var LatMassiv: array [1..30] of symbols;//Массив для хранения клавиш
Oshibki:integer;//Счётчик ошибок
//Процедура выводит экранную клавиатуру
Procedure WriteLatKlav;
begin
gotoxy(18,16);
writeln(‘ — — — — — — — — — — ‘);
gotoxy(18,17);
writeln(‘| Q | W | E | R | T | Y | U | I | O | P |’);
gotoxy(18,18);
writeln(‘ — — — — — — — — — — ‘);
gotoxy(19,19);
writeln(‘ — — — — — — — — — — — ‘);
gotoxy(19,20);
writeln(‘| A | S | D | F | G | H | J | K | L | ; | » |’);
gotoxy(19,21);
writeln(‘ — — — — — — — — — — — ‘);
gotoxy(20,22);
writeln(‘ — — — — — — — — — ‘);
gotoxy(20,23);
writeln(‘| Z | X | C | V | B | N | M | , | . |’);
gotoxy(20,24);
writeln(‘ — — — — — — — — — ‘);
end;
//Процедура заполняет массив латинских клавиш
Procedure ZapolnenieLatMassiv;
begin
//Для примера заполнено только 4 клавиши
with LatMassiv[1] do begin number:=106; x:=45; y:=20; p:=‘П2’; end;//j
with LatMassiv[2] do begin number:=102; x:=33; y:=20; p:=‘Л1’; end;//f
with LatMassiv[3] do begin number:=107; x:=49; y:=20; p:=‘П3’; end;//k
with LatMassiv[4] do begin number:=100; x:=29; y:=20; p:=‘Л3’; end;//d
end;
//Непосредственно сам уровень тренировки набора латинских клавиш
//Параметр slojnost — количество клавиш
Procedure LatLevel(slojnost:byte);
var f:boolean;//Если клавиши правильная, то false и выходим из цикла
c:char;//Для хранения нажатой клавиши
n:byte;//Индекс клавиши в массиве
begin
//Каждый уровень предлагет 10 клавиш для нажатия
for var i:=1 to 10 do
begin
//Выводим предлагаемую клавишу и рекомендуемый палец
gotoxy(40,9);
n:=random(1,slojnost);
write(chr(LatMassiv[n].number));
GotoXY(39,14);
write(LatMassiv[n].p);
//Подсвечиваем клавишу на экранной клавиатуре
gotoxy(LatMassiv[n].x-1,latmassiv[n].y);
TextBackground(red);
Textcolor(15);
write(‘ ‘,chr(LatMassiv[n].number-32),‘ ‘);
Textcolor(black);
TextBackground(7);
//Входим в цикл считывания нажатой клавиши
f:=true;
while f do
begin
if keypressed then
begin
c:=readkey;
if ord(c)=LatMassiv[n].number then
f:=false//Если клавиша нажате верно
else
begin //Если не верно, то считаем и выводим ошибку
inc(Oshibki);
Gotoxy(1,2);
Write(‘Ошибки — ‘,Oshibki);
end;
end;
end;
//Стираем предлагаемую клавишу, палец и убираем подсветку с экранной клавиатуры
gotoxy(LatMassiv[n].x-1,LatMassiv[n].y);
write(‘ ‘,chr(LatMassiv[n].number-32),‘ ‘);
gotoxy(40,9);
ClearLine;
GotoXY(1,14);
ClearLine;
sleep(200);//Делаем небольшуюу паузу
end;
end;
begin
//Инициализация программы
CRT.SetWindowTitle(‘Клавиатурный тренажёр’);
HideCursor;
ZapolnenieLatMassiv;
Oshibki:=0;
TextBackground(7);
clrscr;
TextColor(black);
end.
=========================================================================
Program KlavTren;
Uses CRT,MKlavTren;
begin
//Для примера два уровня
for var i:=1 to 2 do
begin
clrScr;
gotoxy(35,12);
write(‘Уровень ‘,i,‘.’);
sleep(2000);
clrScr;
Gotoxy(1,2);
Write(‘Ошибки — ‘,Oshibki);
WriteLatKlav;
gotoxy(36,1);
write(‘Уровень ‘,i);
TextBackground(7);
LatLevel(i*2);
end;
ClrScr;
GoToXY(33,11);
Write(‘Поздравляем!!!’);
GoToXY(15,13);
Write(‘Вы прошли клавиатурный тренажёр, совершив ‘,Oshibki,‘ ошибок.’);
readln;
end.
_________________________________________________________________________
Для экономии бумаги я не стал приводить заполнение всего массива латинских клавиш. А так же не стал прописывать уровень тренировки русских букв. Процедура будет точно такая же, как и для латинских букв, только в ней необходимо будет использовать массив русских клавиш.
В конце параграфа в задачах будет предложено дописать этот клавиатурный тренажёр с учётом некоторых аспектов, которые так же будут приведены. Настоятельно рекомендую сделать это, и с помощью данного тренажёра научиться набирать текст не глядя в клавиатуру. Так же можете использовать и другой тренажёр. Думаю, их немало можно найти в просторах Интернета.
По началу будет не привычно не смотреть в клавиатуру, тем не менее, постепенно вы привыкните и потом вам будет не непривычно уже смотреть в неё. Уверяю вас, помимо того, что не глядя набирать быстрее это ещё и гораздо менее утомительно.
Игра «Гонки».
Плюс к тому, что мы написали клавиатурный тренажёр. Предлагаю написать игру под названием «Гонки». Это даст нам хороший опыт по программированию. Разберём весь процесс работы над такой программой поэтапно.
Для игры нам понадобятся следующие элементы:
- трасса, которая должна двигаться относительно экрана;
- машина, которая должна оставаться на месте относительно экрана и перемещаться влево, вправо относительно трассы;
- препятствия, которые должны двигаться вместе с трассой, и которые необходимо будет объезжать.
Движущаяся трасса. Трассу обозначим с помощью левой и правой границы. Границы будут состоять из символов «|», примерно следующим образом:
| |
| |
| |
| |
| |
Эффект движения трассы создадим за счёт движения символов вниз. Для того, что бы было ощущение реального движения, сделаем на одну строчку с символами две пустых строчки. Через определённый промежуток времени будем стирать весь экран и перерисовывать трассу, при этом символы должны опуститься на одну строчку вниз.
Так как размер консольного окна при разворачивании на весь экран имеет размеры 80х50 символов, то зададим изначальный размер окна с помощью процедуры:
SetWindowSize(80,50);
Так как символы будут находиться в каждой четвёртой строчке, то координату у для прорисовки нужно увеличивать каждый раз на 3. Когда координата станет больше 50, то из неё необходимо будет вычесть 50. Для того, что бы каждый раз начинать прорисовку не с первой строчки, а со второй или с третьей необходима переменная, которая будет хранить позицию, с которой начиналась прорисовка в предыдущий раз. Назовём её yTrassa. Тогда в первом случае yTrassa будет равна 0. Во втором случае yTrassa=1, в третьем yTrassa=2.
Всего у нас получилось 3 повторяющиеся строчки. Следовательно, для прорисовки всей трассы необходимо проходов. При этом если y станет больше 50, то проход необходимо пропустить.
После всего вышесказанного можно написать следующий код:
program Trassa;
uses CRT;
var yTrassa:byte;
procedure DrowTrassa;
var y:byte;
begin
y:=1+yTrassa;
for var i:=1 to 17 do
begin
GotoXY(20,y);
write(‘|’);
GotoXY(60,y);
write(‘|’);
y:=y+3;
if y>50 then break;
end;
end;
begin
SetWindowSize(80,50);
yTrassa:=0;
while true do
begin
if yTrassa=3 then yTrassa:=0;
DrowTrassa;
Sleep(600);
ClrScr;
Inc(yTrassa);
end;
end.
___________________________________________
Препятствие. Препятствие может состоять из строчки 10 дефисов: «———-». Препятствие должно появляться между границами трассы в разных местах случайным образом. Для этого создадим переменную xTr, значение которой будем получать с помощью процедуры random(20,40). Двадцать и сорок числа не случайные. 20 – позиция левого края трассы. 40 – правая позиция трассы за вычетом 10 символов препятствия.
Для движения препятствия вместе с трассой создадим переменную yTr. Когда данная переменная станет больше 50, делаем её равной единице и присваиваем новое значение переменной xTr. Для прорисовки трассы напишем следующую процедуру:
procedure DrowPr;//Рисуем препятствие
begin
if yPr>50 then
begin
yPr:=1;
xPr:=Random(20,40);
end;
GotoXY(xPr,yPr);
write(‘———————‘);
Inc(yPr);
end;
Машина. С помощью символов Машину можем нарисовать следующим образом:
___
0|___|0
| |
|___|
0|___|0
Она должна находиться внизу трассы и перемещаться влево и вправо относительно трассы, не выходя за её пределы. Для прорисовки машины создадим процедуру DrowCar и глобальную переменную xCar, которая будет хранить позицию, в которой находится машина.
Код процедуры DrowCar будет выглядеть следующим образом:
procedure DrowCar;
begin
GotoXY(xCar,45); write(‘ ___ ‘);
GotoXY(xCar,46); write(‘ |___| ‘);
GotoXY(xCar,47); write(‘0| |0’);
GotoXY(xCar,48); write(‘ |___| ‘);
GotoXY(xCar,49); write(‘0|___|0’);
end;
Перемещение машины. Для перемещения машины нам необходима процедура, которая будет менять координату xCar в зависимости от того, какую клавишу нажал пользователь. Назовём эту процедуру Smena_xCar. Так как машина не должна выезжать за пределы трассы, то в конце процедуры необходимо проверить координату xCar, и если она выходит за границы трассы, то изменить её значение. Получим следующий код:
procedure Smena_xCar;
var cTemp:char;
begin
if KeyPressed then
begin
cTemp:=ReadKey;
if Ord(cTemp)=0 then
begin
cTemp:=ReadKey;
case Ord(cTemp) of
37: dec(xCar);
39: inc(xCar);
end;
end;
if xCar<=21 then xCar:=21;
if xCar>=53 then xCar:=53;
end;
end;
Суть игры. Используя все приведённые выше процедуры, мы уже можем написать игру, где будет двигаться трасса, появляться препятствия и где можно с помощью клавиатуры перемещать машину относительно трассы.
Осталось сделать игру интересной и захватывающей. Для этого необходимо при объезде каждого препятствия считать очки. Трасса должна двигаться с каждым разом всё быстрее и быстрее. Для этого создадим две переменные Ochki, для счёта очков и SleepTime, для ускорения движения трассы. А так же процедуру DrowOchki для вывода количества очков. Изменение этих переменных, а так же вызов этой процедуры необходимо произвести тогда, когда препятствие исчезает из вида, т.е. в первых строчках процедуры DrowPr, где проверяется переменная yPr, не стала ли она больше 50. С учётом вышесказанного процедуры DrowOchki и DrowPr будут выглядеть следующим образом:
procedure DrowOchki;
begin
GotoXY(1,1);
Write(‘Счёт ‘,Ochki);
end;
procedure DrowPr;//Рисуем препятствие
begin
if yPr>50 then
begin
if SleepTime > 20 then SleepTime:=SleepTime-10;
Inc(Ochki);
yPr:=1;
xPr:=Random(20,40);
end;
GotoXY(xPr,yPr);
write(‘———————‘);
Inc(yPr);
end;
Так же необходимо прописать остановку игры в том случае если машина наезжает на препятствие. Это событие может наступить тогда, когда переменная yPr будет равна 46, 47, 48 и 49, т.к. именно в этих координатах по y и находится машина. Хотя на самом деле машина начинается с координаты y=45, но визуально столкновение будет выглядеть реальнее если мы будем считать, что машина начинается с 46 координаты. Если машину воспринимать, как прямоугольник 7х4 символов, то условие наезда машины на препятствие будет выглядеть так:
(yPr>=46) and (yPr<=49) and ((xCar>(xPr-7)) and (xCar<=(xPr+19)))
Код основной программы. Далее необходимо написать код основной программы. Здесь необходимо произвести инициализацию всех переменных, затем войти в цикл, в котором будет происходить прорисовка всех элементов игры и изменение переменных. Для выхода из цикла необходимо проверять условие наезда машины на препятствие. При выходе из цикла необходимо вывести сообщение о том, что игра окончена. Для нашей игры код программы будет выглядеть следующим образом:
program Game_Gonka;
uses CRT;
var yTrassa,xCar,yPr,xPr:byte;
SleepTime,Ochki:integer;
…………………………..
begin
SetWindowCaption(‘Игра гонки’);
SetWindowSize(80,50);
yTrassa:=0;
xCar:=36;
yPr:=1;
xPr:=Random(21,39);
SleepTime:=200;
Ochki:=0;
while true do
begin
DrowTrassa;
DrowCar;
DrowPr;
DrowOchki;
if (yPr>=46) and (yPr<=49) and ((xCar>(xPr-7)) and (xCar<=(xPr+19))) then
break;
Sleep(SleepTime);
Smena_xCar;
Inc(yTrassa);
if yTrassa=3 then yTrassa:=0;
ClrScr;
end;
GotoXY(30,24);
Write(‘Конец игры.’);
readln;
end.
На месте строки с точками должны находиться процедуры, код которых был уже приведён.
В данном мы на аписали клавиатурный тренажёр и игру «Гонки». Тем самым мы научились применять все полученные ранее знания для написания полноценных программ.
Задачи.
1. Дописать клавиатурный тренажёр, учитывая следующие аспекты:
- дописать массив латинских клавиш, причём необходимо ввести заглавные буквы;
- ввести в экранную клавиатуру левую клавишу «Shift», которая должна подсвечиваться вместе с нужной клавишей, в случае если предлагается ввести заглавную букву. Левый «Shift» нажимается пятым пальцем левой руки, при этом те клавиши, которые нужно было нажимать пятым пальцем левой руки необходимо нажимать четвёртым пальцем левой руки. Можете поэкспериментировать и определить для себя оптимальное сочетание клавиш для нажатия заглавных букв;
- перед началом тренировки необходимо предложить выбрать латинскую или русскую клавиатуру, соответственно написать процедуру RusLevel, процедуру рисования русской клавиатуры, и процедуру заполнения массива русских клавиш. В русской клавиатуре добавить клавишу с буквой «Ё», она нажимается пятым пальцем левой руки;
- в случае если количество ошибок станет более 30% от количества предложенных клавиш, то вывести сообщение и начать тренировку с первого уровня.
2. Рассмотренный нами клавиатурный тренажёр предназначен для изучения расположения клавиш на клавиатуре и для того, что бы приучить пальцы нажимать нужные клавиши. Для того, что бы тренироваться набирать уже тексты, а не отдельные символы, можно написать клавиатурный тренажёр другого типа. Экран разделён на две половины – верхнюю и нижнюю. В верхней части находится какой либо текст. В нижней части этот текст необходимо ввести. При этом в верхнем тексте необходимо подсвечивать символ, который должен в данный момент ввести пользователь. Так же необходимо считать ошибки.
3. Наберите код игры «Гонки» из данного параграфа. Детально его изучите. Допишите комментарии так, что бы можно было понять код, не читая текст данного параграфа.
4. Усовершенствуйте игру «Гонки», исходя из следующих тезисов:
- необходимо создать стартовую страницу, которая будет показана после запуска программы. На этой странице необходимо вывести название игры, правила и предложить игроку ввести своё имя.
- при наезжании машины на препятствии вывести сообщение о том, что игра закончена, и вывести список игроков с их результатами. Список должен быть отсортирован по результату. Имя игрока, который только, что играл должен быть выделен другим цветом. На этой же странице предложить играть снова или закрыть программу.
- Игра должна быть закончена так же при наезде машины на край трассы.
- При нажатии игроком клавиши «Esc» игра должна входить в режим паузы. При этом должно быть предложено выйти из игры вообще или продолжить игру. Реализовать это можно с помощью специальной процедуры, которая может быть вызвана в том месте кода, где идёт считывание нажатой клавиши, т.е. в процедуре Smena_xCar.
- Изменить цвета у элементов игры: у фона, трассы, машины и препятствия.
- Придумать и реализовать свои усовершенствования.
5.Придумайте и напишите свою игру.
Решение.
1. Решение третьей задачи оставляю на вашу самостоятельную работу, т.к. костяк программы уже есть, необходимо только её дописать.
2.
unit MklavTren_2;
uses CRT;
const ks=9;//Количество строк выводимого текста
var fText:Text;//Файловая переменная
sFile:string;//Текстовый файл
mText:array [1..ks] of string[80];//Массив строк
//содержит текст для вывода
sTek:string;//Текущая строка
final:=0;//Считает строки после окончания текстового файла
//Читаем строку из файла, если файл закончен,то строка равна »
function chteniestroki:string[80];
var sTemp:string;
cTemp:char;
begin
if not Eof(fText) then
begin
for var i:=1 to 80 do
begin
if not Eoln(fText) then
begin
read(fText,cTemp);
sTemp:=sTemp+cTemp;
end
else
begin
if not Eof(fText) then readln(fText,cTemp);
break;
end
end;
chteniestroki:=sTemp;
end
else
begin
chteniestroki:=»;
Inc(final);
end;
end;
//»Прокручиваем» текст вверх в массиве mText
procedure SmenaChlenov;
begin
for var i:=1 to (ks-1) do mText[i]:=mText[i+1];
mText[ks]:=chteniestroki;
end;
//Вывод текста на экран
procedure VivodTexta;
begin
gotoxy(1,1);
for var i:=1 to ks do
begin
writeln(mText[i]);
if Length(mText[i])=80 then GotoXY(1,WhereY-1);
end;
end;
procedure ObnovlenieTexta;
begin
SmenaChlenov;
VivodTexta;
end;
//Подсвечивание нужного символа в тексте
procedure PodsvechSimvola(simvol:byte);
var x,y:byte;
begin
x:=WhereX;
y:=WhereY;
TextBackground(Red);
GotoXY(simvol,5);
Write(sTek[simvol]);
TextBackground(Black);
GotoXY(x,y);
end;
//Убирание подсветки с симолоа в тексте
procedure UbiraniePodsvetki(simvol:byte);
var x,y:byte;
begin
x:=WhereX;
y:=WhereY;
TextBackground(Black);
GotoXY(simvol,5);
Write(sTek[simvol]);
GotoXY(x,y);
end;
procedure VivodOshibok(o:integer);
var x,y:byte;
begin
x:=WhereX;
y:=WhereY;
GotoXY(35,12);
write(‘ ‘);
Sleep(200);
GotoXY(35,12);
Write(‘Ошибок — ‘,o);
GotoXY(x,y);
end;
function ReadSimvol:char;//Читаем нажатый символ
begin
while not KeyPressed do;
ReadSimvol:=ReadKey;
end;
end.
=========================================================================
Program KlavTren_2;
Uses CRT,MKlavTren_2;
var c:char;//Для чтения нажатого символа
simvol,//порядковый номер текущего символа в строке
oshibki:byte;//Для счёта ошибок
procedure VvodSrtoki;
var b:boolean;//нужна для выхода из цикла
//Равна false, когда строка введена
begin
sTek:=mText[5];
GotoXY(1,15);
b:=true;
simvol:=1;
while b do
begin
PodsvechSimvola(simvol);
c:=readSimvol;
if c=sTek[simvol] then
begin
UbiraniePodsvetki(simvol);
Inc(simvol);
write(c);
end
else
begin
Inc(oshibki);
VivodOshibok(oshibki);
end;
if simvol>Length(sTek) then b:=false;
end;
end;
begin
SetWindowCaption(‘Клавиатурный тренажёр 2’);
//Предлагаем пользователю выбрать какой-либо вариант текста
while true do
begin
Writeln(‘Вы открыли клавиатурный тренажёр!’);
Writeln(‘Выберите текст для набора:’);
Writeln(‘1 — «Операционная система MS DOS»‘);
Writeln(‘2 — «Команды MS DOS»‘);
read(c);
case c of
‘1’:sFile:=‘MS DOS.txt’;
‘2’:sFile:=‘Команды DOS.txt’ ;
end;
if (c=‘1’) or (c=‘2’) then break;
ClrScr;
end;
//Собственно сама программа
Assign(fText,sFile);
Reset(fText);
//Заполняем первые строки текста
for var i:=6 to ks do mText[i]:=chteniestroki;
//Входим в цикл набора текста
while final<5 do
begin
ClrScr;
ObnovlenieTexta;
VivodOshibok(oshibki);
GotoXY(1,17);
if mText[5]=» then continue;
VvodSrtoki;
end;
Close(fText);
writeln;
writeln(‘Конец’);
readln;
end.
_________________________________________________________________________
3.4.5. Эти задания сделайте самостоятельно.
uses graphABC, ABCobjects, timers; var f, fn: text; t,check: Timer; base_color, cgr: Color; ug, time_play_sec,take_speed,time: real; login, Str, str2, str3, st1, ch, password, zs, ks: string; chapter, level, n, xgr, ygr, rgr, x_power, y_power,spin, time_play_sec2,chapter_test: integer; xb, yb, xg, yg, power, ww, wh, shot, time_play_min, shot_max,level_test: integer; Basa: RegularPolygonABC; show4, target, target_bad: ObjectABC; show, show2, show3, registr_but, login_but, status_box: RectangleABC; Star, sun: StarABC; show_pos: CircleABC; Average_ugol: array of integer; Average_power: array of integer; mb: array[1..62] of string; ground: array [1..9] of CircleABC; panel: array [1..5] of RectangleABC; lvlup_b, play, Cont, login_next, regist_next, from_0, from_6: boolean; procedure pfile; begin Assign(fn, login + '.txt'); append(fn); writeln(fn, '0'); write(fn, '0'); close(fn); end; procedure prewrite; begin Assign(f, login + '.txt'); Rewrite(f); writeln(f, level); Write(f, chapter); Close(f); end; procedure pread; var level_s, chapter_s: string; begin Assign(f, login + '.txt'); Reset(f); repeat Readln(f, level_s); level := StrToInt(level_s); readln(f, chapter_s); chapter := StrToInt(chapter_s); until Eof(f); Close(f); end; procedure pgenerate; begin var show_login: RectangleABC := new RectangleABC(0, 51, 150, 35, clorangeRed); show_login.Text := 'Ваш логин: ' + Login; st1 := 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789.'; for var it := 1 to st1.length - 1 do begin mb[it] := st1[it]; end; status_box.Text := 'Введите пароль: '; readln(ch); password := ch; status_box.text := 'Вы создали нового пользователя!'; show_login.Destroy; pfile; end; procedure pcreate; begin var show_login: RectangleABC := new RectangleABC(0, 51, 150, 25, clorangeRed); assign(F, 'users.txt'); append(f); close(f); reset(f); show_login.text := 'Введите логин: '; status_box.Text := 'Введите логин: '; readln(login); while not eof(f) do begin if (str <> str2) then eof(f); readln(f, str); if pos(login, str) > 0 then begin str2 := str; readln(f, str); str3 := str; if (str <> str2) then eof(f); end; end; close(f); if login = str2 then begin status_box.Text := 'Это имя уже занято!'; regist_next := false; end else begin Append(F); status_box.text := 'Помощь: Если ввести /gen, то пароль будет сгенерирован автоматически.'; pgenerate; zs := ''; ks := ',.!@?-:;+'; for var i := 1 to password.Length do begin n := pos(password[i], ks); zs := zs + inttostr(n); end; zs := ''; ks := ',.!@?-:;+Zqazwsxedc90rfvtgbhnu7jAmiklop345QWERTYSXDCyFVG1BUHNMJI2OPKL68'; for var i := 1 to password.Length do begin n := pos(password[i], ks); zs := zs + inttostr(n); end; password := zs; writeln(f, login); writeln(f, password); close(f); end; show_login.Destroy; end; procedure plogin; begin Assign(f, 'users.txt'); append(f); Close(f); Assign(f, 'users.txt'); reset(f); var show_login: RectangleABC := new RectangleABC(0, 51, 150, 35, clorangeRed); show_login.Text := 'Ваш логин: '; status_box.Text := 'Введите логин'; readln(Login); show_login.Text += Login; while not eof(f) do begin if (str <> str2) then eof(f); readln(f, str); if pos(login, str) > 0 then begin str2 := str; readln(f, str); str3 := str; if (str <> str2) then eof(f); end; end; status_box.Text := 'введите пароль'; readln(password); zs := ''; ks := ',.!@?-:;+Zqazwsxedc90rfvtgbhnu7jAmiklop345QWERTYSXDCyFVG1BUHNMJI2OPKL68'; for var i := 1 to password.Length do begin n := pos(password[i], ks); zs := zs + inttostr(n); end; password := zs; if (str3 = password) then begin status_box.Text := 'Выполнен вход в учетную запись: ' + Login; end else begin status_box.Text := 'Ошибка входа: Неверный логин или пароль'; login_next := false; end; close(f); show_login.Destroy; end; procedure stats; var x, y, w, h: integer; begin x := 0; y := wh - 30; w := 160; h := 30; for var i := 1 to 5 do //Создаем нижнюю панель begin if i < 5 then panel[i] := new RectangleABC(x, y, w + 1, h, RGB(120 + 15 * i, 50 + level * 5, 100)); if i = 5 then panel[i] := new RectangleABC(x, y, w, h, RGB(120 + 15 * i, 50 + level * 5, 100)); panel[i].BorderWidth := 2; x += w; end; end; procedure Start; begin SetWindowSize(800, 600); ClearWindow(clWhite); wh := WindowHeight; ww := WindowWidth; if level = 0 then level := 0; if chapter = 0 then chapter := 0; Window.IsFixedSize := true; sun := new StarABC(35, 35, 20, 25, 16, clGold); SetLength(Average_power, 0); SetLength(Average_ugol, 0); shot := 0; time_play_min := 0; time_play_sec := 0; end; procedure basegen(xb, yb: integer);//создаем базу begin Line(xb - 50, yb, xb + 50, yb); Line(xb, yb - 50, xb, yb + 50); Line(xb - 50, yb - 1, xb + 50, yb - 1); Line(xb - 1, yb - 50, xb - 1, yb + 50); Line(xb - 50, yb, xb + 50, yb); Line(xb, yb - 50, xb, yb + 50); Line(xb - 50, yb - 1, xb + 50, yb - 1); Line(xb - 1, yb - 50, xb - 1, yb + 50); basa := new RegularPolygonABC(xb, yb, 30, 5, base_color); end; procedure mapgen(level_p: integer);//генерируем карту begin target_bad := new RectangleABC(0, 0, 0, 0, clWhite); shot_max := 5; xb := 100; yb := 300; xgr := 0; ygr := 530; rgr := 100; cgr := clLavender; for var i := 1 to 9 do begin ground[i] := new CircleABC(xgr, ygr, rgr, cgr); ground[i].bordered := false; xgr += 100; end; xgr := 0; for var i := 1 to 9 do begin Arc(xgr, ygr - 1, 100, 60, 120); xgr += 100; end; basegen(xb, yb);//добавляем базу if level_p=-2 then begin target := new rectangleABC(650, 100, 10, 300, clRed); end; if level_p = 0 then begin from_0 := true; show := new RectangleABC(100, 0, ww - 100, 20, clwheat); show.Text := 'Кликните в любом месте мышкой и удерживая перетащите в любое другое место, так вы сможете выбрать силу.'; show2 := new RectangleABC(100, 20, ww - 100, 20, clwheat); show2.Text := 'Внизу на панеле отображается ваши текущие угол и сила, При соприкосновении с поверхностью ядро взрывается'; show3 := new RectangleABC(100, 40, ww - 100, 20, clwheat); show4 := new RectangleABC(0, 60, ww, 20, cllime); show3.Text := 'На каждом уровне есть ограниченное кол-во выстрелов, если вы не успели попасть в цель, вы переходите на уровень назад'; show4.text := 'Чтобы пройти уровень надо попадать по красным мишеням. Сейчас попадите в красную стенку'; show3.TextScale := 0.9; target := new rectangleABC(650, 100, 10, 300, clRed); end; stats;//добавляем нижнюю панель panel[3].Text := 'Глава: ' + IntToStr(chapter); panel[4].Text := 'Уровень: ' + IntToStr(level); if level_p = 1 then begin if (from_0 = true) then begin show.Destroy; show2.Destroy; show3.Destroy; show4.Destroy; end; target := new CircleABC(300, 200, 30, clRed); end; if level > 1 then panel[5].Text := 'Выстрел ' + IntToStr(shot) + ' из ' + IntToStr(shot_max); if (level_p = 2) then target := new CircleABC(400, 400, 30, clRed); if (level_p = 3) then target := new CircleABC(100, 50, 30, clRed); if (level_p = 4) then target := new CircleABC(500, 110, 30, clRed); if (level_p = 5) and (from_6 = false) then target := new CircleABC(700, 330, 20, clRed); if (level_p = 5) and (from_6 = true) then begin show.Destroy; target := new CircleABC(700, 330, 20, clRed); end; if (level_p = 6) then begin from_6 := true; show := new RectangleABC(100, 0, ww - 100, 20, clwheat); show.Text := 'Черные цели перенаправляют вас сразу на уровень назад!'; target := new CircleABC(720, 350, 30, clred); target_bad := new CircleABC(720, 150, 30, clblack); end; time_play_min := 0; time_play_sec := 0; if level > 6 then begin if (from_6 = true) then begin from_6 := false; show.Destroy; end; target := new CircleABC(Random(100, ww - 50), Random(100, wh - 250), 30, clRed); end; end; procedure lvldown; begin target.Destroy; target_bad.Destroy; ClearWindow(clWhite); var stat_box := new RoundRectABC(10, 10, ww - 20, wh - 20, 15, clslateblue); stat_box.BorderWidth := 2; var box: array[1..5] of RoundRectABC; var x_box, y_box: integer; x_box := 20; y_box := 20; for var i := 1 to 5 do begin box[i] := new RoundRectABC(x_box, y_box, ww - 40, 100, 15, RGB(100 + 20 * i, 100, 100)); box[i].BorderWidth := 2; y_box += 105; if i = 1 then begin box[i].Color := clred; box[i].Text := 'Вы не прошли уровень: ' + IntToStr(level); end; if i = 2 then box[i].Text := 'Средняя сила: ' + IntToStr(Round(Average_power.Average)) + 'p'; if i = 3 then box[i].Text := 'Средний угол: ' + IntToStr(Round(Average_ugol.Average)); if i = 4 then box[i].Text := 'Выстрелов: ' + IntToStr(shot); if i = 5 then begin if time_play_min = 0 then box[i].Text := 'Время: ' + time_play_sec.ToString + 'c.' else box[i].Text := 'Время: ' + time_play_min.ToString + 'm. ' + time_play_sec.ToString + 'c.'; end; end; Sleep(5000); for var i := 1 to 5 do box[I].Destroy; stat_box.destroy; level -= 1; SetLength(Average_power, 0); SetLength(Average_ugol, 0); shot := 0; prewrite; mapgen(level); Basa.RedrawNow; for var i := 1 to 5 do panel[i].RedrawNow; sun.RedrawNow; for var i := 1 to 9 do ground[i].RedrawNow; end; procedure lvlup; begin lvlup_b := false; ClearWindow(clWhite); target.Destroy; target_bad.Destroy; var stat_box := new RoundRectABC(10, 10, ww - 20, wh - 20, 15, clslateblue); stat_box.BorderWidth := 2; var box: array[1..5] of RoundRectABC; var x_box, y_box: integer; x_box := 20; y_box := 20; for var i := 1 to 5 do begin box[i] := new RoundRectABC(x_box, y_box, ww - 40, 100, 15, RGB(100, 100 + 20 * i, 170)); box[i].BorderWidth := 2; y_box += 105; if i = 1 then begin box[i].Color := cllime; box[i].Text := 'Вы прошли уровень: ' + IntToStr(level); end; if i = 2 then box[i].Text := 'Средняя сила: ' + IntToStr(Round(Average_power.Average)) + 'p'; if i = 3 then box[i].Text := 'Средний угол: ' + IntToStr(Round(Average_ugol.Average)); if i = 4 then box[i].Text := 'Выстрелов: ' + IntToStr(shot); if i = 5 then begin if time_play_min = 0 then box[i].Text := 'Время: ' + time_play_sec.ToString + 'c.' else box[i].Text := 'Время: ' + time_play_min.ToString + 'm. ' + time_play_sec.ToString + 'c.'; end; end; Sleep(5000); for var i := 1 to 5 do box[I].Destroy; stat_box.destroy; level += 1; if (level = 1) and (chapter = 0) then chapter += 1; if (level mod 6 = 0) and (level > 1) then chapter += 1; SetLength(Average_power, 0); SetLength(Average_ugol, 0); shot := 0; prewrite; mapgen(level); Basa.RedrawNow; for var i := 1 to 5 do panel[i].RedrawNow; sun.RedrawNow; for var i := 1 to 9 do ground[i].RedrawNow; end; function myfunc(xr, yr, p, ug: real): real;//функция полета var t: real; begin play := true; t := 0;//Время xg := 0;//Коориданата Х yg := 0;//Коориданата У Star := new StarABC(Round(xr), Round(yr), 20, 10, 10, clRandom);//Создаем объект-ядро if level < 0 then Check.Start; repeat if level < 0 then TextOut(0,500,'ПРОРИСОВКА: '+time_play_sec2.ToString+' '); xg := Round((xr) + ((p * t * cos(ug)) / 2)); yg := Round((yr) - (p * t * sin(ug) - (9.8 * t * t / 2))); xg -= 2; Star.MoveTo(xg, yg);//перемещения ядра в (xg,yg) Star.Angle += spin;//Вращаем ядро MoveTo(xg, yg); PutPixel(xg, yg, clRed);//рисуем путь t += time;//Прибавляем время sleep(2);//Задержка в 2 милисекунды if (Star.Intersect(target) = true) then lvlup_b := true; if (Star.Intersect(target_bad) = true) then begin lvlup_b := false; shot += shot_max * 2; end; if (Star.Intersect(target) = true) then take_speed := time_play_sec2; until (star.Intersect(ground[1]) = true) or (star.Intersect(ground[2]) = true) or (star.Intersect(ground[3]) = true) or (star.Intersect(ground[4]) = true) or (star.Intersect(ground[5]) = true) or (star.Intersect(ground[6]) = true) or (star.Intersect(ground[8]) = true) or (star.Intersect(ground[8]) = true) or (star.Intersect(ground[9]) = true) or (xg > ww + 10) or (Star.Intersect(target) = true) or (star.Intersect(target_bad) = true); if level < 0 then check.Stop; if level < 0 then time_play_sec2:=0; Star.Destroy;//убираем звезду shot += 1; if level > 1 then panel[5].Text := 'Выстрел ' + IntToStr(shot) + ' из ' + IntToStr(shot_max); //подсчет средних setLength(Average_ugol, shot); Average_ugol[shot - 1] := Round(RadToDeg(ug)); setLength( Average_power, shot); Average_power[shot - 1] := Round(power); if (shot > shot_max - 1) and (lvlup_b = false) and (level > 1) then lvldown; if (level > 0) then if (lvlup_b = true) and (shot < shot_max + 1) then lvlup; if (level < 2) and (lvlup_b = true) then lvlup; myfunc := t; Play := false; end; procedure MouseMove(xm, ym, mb: integer); var a, b, c: real; begin a := Abs(xm - xb); b := Abs(ym - yb); c := Sqrt(Sqr(a) + Sqr(b)); ug := (arcsin(b / c)); panel[1].Text := 'Угол: ' + IntToStr(Round(RadToDeg(ug))); if mb = 1 then panel[2].Text := 'Сила: ' + IntToStr(Round(sqrt(sqr((xm - x_power)) + sqr((ym - y_power))))) + 'p';//Показываем силу end; procedure MouseDown(xm, ym, mb: integer); begin show_pos := new CircleABC(xm, ym, 2, clwheat); x_power := xm; y_power := ym; end; procedure MouseUp(xm, ym, mb: integer); var a, b, c: real; begin a := Abs(xm - xb); b := Abs(ym - yb); c := Sqrt(Sqr(a) + Sqr(b)); ug := (arcsin(b / c)); power := Round(sqrt(sqr((xm - x_power)) + sqr((ym - y_power))));//Высчитывем силу panel[1].FontColor := clWhite; panel[1].text := 'Угол полета: ' + IntToStr(Round(RadToDeg(ug))); panel[2].FontColor := clWhite; panel[2].text := 'Сила полета: ' + IntToStr(Round(power)) + 'p'; if (mb = 1) and (play = false) and (power > 0) then myfunc(xb, yb, power, ug);//запускаем ядро panel[2].FontColor := clBlack; panel[1].FontColor := clBlack; panel[2].Text := ''; show_pos.Destroy; end; procedure rotate; begin sun.Angle += 1; time_play_sec += 0.5; if time_play_sec = 60.0 then begin time_play_min += 1; time_play_sec := 0; end; end; procedure MouseDownS(xm, ym, mb: integer); begin if mb = 1 then base_color := GetPixel(xm, ym); end; procedure Hello; begin SetWindowSize(800, 600); Window.IsFixedSize := true; var start1 := new RoundRectABC(8, 8, windowwidth - 16, WindowHeight - 15, 10, clLavender); start1.BorderWidth := 3; var start1_name := new RoundRectABC(15, 15, windowwidth - 30, 50, 10, clGreenYellow); start1_name.BorderWidth := 2; start1_name.Text := 'Добро пожаловать, ' + Login + '!'; Sleep(200); var start1_color := new RoundRectABC(15, 70, WindowWidth - 30, 50, 10, clFirebrick); start1_color.BorderWidth := 2; start1_color.Text := 'Выберите цвет базы'; for var iy := 1 to 18 do begin Rectangle(50, 105 + iy * 25, 151, 135 + iy * 25); FloodFill(52, 105 + iy * 25 + 2, clRandom); end; for var iy := 1 to 18 do begin Rectangle(50 + 100 * 1, 105 + iy * 25, 151 + 100 * 1, 135 + iy * 25); FloodFill(52 + 100 * 1, 105 + iy * 25 + 2, clRandom); end; for var iy := 1 to 18 do begin Rectangle(50 + 100 * 2, 105 + iy * 25, 151 + 100 * 2, 135 + iy * 25); FloodFill(52 + 100 * 2, 105 + iy * 25 + 2, clRandom); end; for var iy := 1 to 18 do begin Rectangle(50 + 100 * 3, 105 + iy * 25, 151 + 100 * 3, 135 + iy * 25); FloodFill(52 + 100 * 3, 105 + iy * 25 + 2, clRandom); end; for var iy := 1 to 18 do begin Rectangle(50 + 100 * 4, 105 + iy * 25, 151 + 100 * 4, 135 + iy * 25); FloodFill(52 + 100 * 4, 105 + iy * 25 + 2, clRandom); end; for var iy := 1 to 18 do begin Rectangle(50 + 100 * 5, 105 + iy * 25, 151 + 100 * 5, 135 + iy * 25); FloodFill(52 + 100 * 5, 105 + iy * 25 + 2, clRandom); end; for var iy := 1 to 18 do begin Rectangle(50 + 100 * 6, 105 + iy * 25, 151 + 100 * 6, 135 + iy * 25); FloodFill(52 + 100 * 6, 105 + iy * 25 + 2, clRandom); end; OnMouseDown := MouseDownS; var timerShow := new RoundRectABC(WindowWidth - 55, 70, 40, 50, 10, clcyan); timerShow.BorderWidth := 2; timerShow.Text := '3'; Sleep(1000); timerShow.Text := '2'; Sleep(1000); timerShow.Text := '1'; Sleep(1000); timerShow.Destroy; start1.Destroy; start1_color.Destroy; start1_name.Destroy; end; procedure MouseDownBeg(xm, ym, mb: integer); begin if login_but.PtInside(xm, ym) = true then login_next := true; if registr_but.PtInside(xm, ym) = true then regist_next := true; end; procedure timer_check; begin time_play_sec2 += 1; end; begin base_color:=clRandom; SetWindowCaption('TimeKiller v0.2'); target_bad := new RectangleABC(0, 0, 0, 0, clWhite); SetWindowSize(800, 600); cont := false; from_0 := false; from_6 := false; OnMouseDown := MouseDownBeg; var main: RectangleABC := new RectangleABC(0, 0, WindowWidth, windowheight, clLavender); login_but := new RectangleABC(0, 0, 401, 50, clolive); registr_but := new RectangleABC(399, 0, 400, 50, clOliveDrab); login_but.BorderWidth := 2; registr_but.BorderWidth := 2; login_but.FontColor := clwhite; registr_but.FontColor := clgold; login_but.Text := 'Войти'; registr_but.Text := 'Зарегистрироваться'; status_box := new RectangleABC(0, WindowHeight - 30, WindowWidth, 30, clgold); status_box.BorderWidth := 2; status_box.Color := ARGB(120, 255, 215, 0); status_box.Text := 'Вам необходимо войти или зарегистрироваться'; repeat Sleep(1000); if login_next = true then begin plogin; end; if regist_next = true then begin pcreate; end; until (login_next = true) or (regist_next = true); pread; cont := true; if Cont = true then begin main.Destroy; status_box.Destroy; login_but.Destroy; registr_but.Destroy; Hello; start; TextOut(0,0,'Подождите идет загрузка данных. Прорисовка.'); time := 0.02; spin := 1; time_play_sec := 0; level_test:=level; chapter_test:=chapter; chapter:=0; level:=-2; mapgen(level); Check := new Timer(1, timer_check); myfunc(xb, yb, 200, Pi / 10);//Проверка медленной скорости; if take_speed > 100 then begin time := 0.08; spin := 2; end; check.Stop; Check := new Timer(1, timer_check); time_play_sec := 0; target.Destroy; level:=-2; mapgen(level); TextOut(0,0,'Подождите идет загрузка данных. Прорисовка.'); myfunc(xb, yb, 200, Pi / 10);//Проверка быстрой скорости; if take_speed < 50 then begin time := 0.02; spin := 1; end; target.Destroy; level:=level_test; chapter:=chapter_test; mapgen(level); T := new Timer(500, rotate); T.Start; OnMouseMove := MouseMove; OnMouseDown := MouseDown; OnMouseUp := MouseUp; end; end.
uses ABCObjects,Events,GraphABC,Timers,Utils; var kLeftKey,kRightKey: boolean; kSpaceKey: integer; Player: RectangleABC; t: integer; EndOfGame: boolean; Enemies: TextABC; StaticObjectsCount: integer; NewGame: TextABC; Wins,Falls: integer; WinsABC,FallsABC: TextABC; r1: RectangleABC; type KeysType=(kLeft,kRight); Pulya=class(CircleABC) constructor Create(x,y: integer); begin inherited Create(x,y,5,clRed); dx:=0; dy:=-5; end; procedure Move; var j: integer; begin inherited Move; if Top<0 then Visible:=False; for j:=StaticObjectsCount+1 to ObjectsCount do if (Objects[j]<>Self) and Intersect(Objects[j]) then begin Objects[j].Visible:=False; Visible:=False; end; end; end; Enemy=class(RectangleABC) constructor Create(x,y,w: integer); begin inherited Create(x,y,w,20,clRandom); if Random(2)=0 then dx:=5 else dx:=-5; dy:=0; end; procedure Move; begin if Random(2)<>0 then Exit; if Random(10)=0 then dy:=5; if (Left<0) or (Left+Width>WindowWidth) or (Random(30)=0) then dx:=-dx; inherited Move; if dy<>0 then dy:=0; if Top>WindowHeight-50 then EndOfGame:=True; end; end; function NumberOfEnemies: integer; var i: integer; begin Result:=0; for i:=1 to ObjectsCount do if Objects[i] is Enemy then Inc(Result); end; procedure CreateObjects; var i: integer; r1: RectangleABC; begin Player:=RectangleABC.Create(280,WindowHeight-30,100,20,clTeal); for i:=1 to 100 do begin r1:=Enemy.Create(Random(WindowWidth-50),40+Random(10),50); r1.TextVisible:=True; r1.Number:=i; end; end; procedure DestroyObjects; var i: integer; begin for i:=ObjectsCount downto StaticObjectsCount+1 do Objects[i].Destroy; end; procedure MoveObjects; var i: integer; begin for i:=StaticObjectsCount+2 to ObjectsCount do Objects[i].Move; end; procedure DestroyKilledObjects; var i: integer; begin for i:=ObjectsCount downto StaticObjectsCount+2 do if not Objects[i].Visible then Objects[i].Destroy; end; procedure KeyDown(Key: integer); begin case Key of vk_Left: kLeftKey:=True; vk_Right: kRightKey:=True; vk_Space: if kSpaceKey=2 then kSpaceKey:=1; end; end; procedure KeyUp(Key: integer); begin case Key of vk_Left: kLeftKey:=False; vk_Right: kRightKey:=False; vk_Space: kSpaceKey:=2; end; end; procedure Timer1; var i,j,n: integer; p: Pulya; begin if kLeftKey and (Player.Left>0) then Player.MoveOn(-10,0); if kRightKey and (Player.Left+Player.Width<WindowWidth) then Player.MoveOn(10,0); if kSpaceKey=1 then begin p:=Pulya.Create(Player.Left+Player.Width div 2,Player.Top-10); kSpaceKey:=0; end; MoveObjects; DestroyKilledObjects; RedrawObjects; n:=NumberOfEnemies; Enemies.Text:='Врагов: '+IntToStr(n); if n=0 then EndOfGame:=True; if EndOfGame then begin StopTimer(t); if n>0 then begin Inc(Falls); FallsABC.Text:='Поражений: '+IntToStr(Falls); RedrawObjects; ShowMessage('Вы проиграли!'); DestroyObjects; Enemies.Text:='Врагов: '+IntToStr(NumberOfEnemies); RedrawObjects; end else begin Inc(Wins); WinsABC.Text:='Побед: '+IntToStr(Wins); RedrawObjects; ShowMessage('Вы выиграли!'); DestroyObjects; Enemies.Text:='Врагов: '+IntToStr(NumberOfEnemies); RedrawObjects; end; end; end; procedure MouseUp(x,y,mb: integer); begin if NewGame.PTInside(x,y) then StartTimer(t); end; procedure KeyPress(Key: char); begin if ((UpCase(Key)='G') or (UpCase(Key)='П')) and EndOfGame then begin EndOfGame:=False; StartTimer(t); CreateObjects; kSpaceKey:=2; kLeftKey:=False; kRightKey:=False; end; end; begin LockDrawingObjects; EndOfGame:=True; r1:=RectangleABC.Create(0,0,WindowWidth,38,clWhite); NewGame:=TextABC.Create(WindowWidth-180,5,14,clBlack,'G - Новая игра'); Enemies:=TextABC.Create(10,5,14,clRed,'Врагов: '+IntToStr(NumberOfEnemies)); WinsABC:=TextABC.Create(150,5,14,clRed,'Побед: '+IntToStr(Wins)); FallsABC:=TextABC.Create(280,5,14,clRed,'Поражений: '+IntToStr(Falls)); StaticObjectsCount:=ObjectsCount; Enemies.Text:='Врагов: '+IntToStr(NumberOfEnemies); OnKeyDown:=KeyDown; OnKeyPress:=KeyPress; OnKeyUp:=KeyUp; OnMouseUp:=MouseUp; t:=CreateTimer(10,Timer1); StopTimer(t); RedrawObjects; end.