код для игры в паскале
Приведите пример игры которая написана на Pascal ABC.
uses GraphABC, crt;
label metka,metka2;
var x,y: array [1..100] of integer;
n,i,x0,y0,dx,dy,r:integer;
ch,cp:char;
b,p:boolean;
procedure setting;
begin
SetFontColor(clBlue);
SetFontSize(32);
SetFontStyle(fsItalic);
SetBrushColor(ClWhite);
TextOut(WindowWidth-180,260,’Snake’);
SetFontColor(clBlack);
SetFontSize(10);
//SetPenColor(clBlack);
Line(WindowWidth-195,0,WindowWidth-195,WindowHeight);
TextOut(WindowWidth-180,20,’N=’);
TextOut(WindowWidth-180,40,’Клавиши управления: ‘);
TextOut(WindowWidth-180,60,’w,s,a,d’);
TextOut(WindowWidth-180,80,’p-пауза’);
end;
begin
metka2:
n:=3;
hidecursor;
SetWindowCaption(‘Snake’);
for i:=n downto 1 do
x[i]:=60+(n-i)*10;
for i:=1 to n do
y[i]:=110;
r:=5;
randomize;
x0:=(Random(WindowWidth-210) div 10)*10+10;
y0:=(Random(WindowHeight-10) div 10)*10+10;
dx:=10;
dy:=0;
SetBrushColor(clGreen);
for i:=1 to n do
Circle(x[i],y[i],r);
SetBrushColor(clYellow);
Circle(x0,y0,r);
metka:
repeat
sleep(150);
for i:=n downto 2 do
begin
x[i]:=x[i-1];
y[i]:=y[i-1];
end;
x[1]:=x[1]+dx;
y[1]:=y[1]+dy;
ClearWindow;
setting;
TextOut(WindowWidth-160,20,IntToStr(n-3));
SetBrushColor(clYellow);
Circle(x[1],y[1],r);
SetBrushColor(clGreen);
for i:=2 to n do
Circle(x[i],y[i],r);
SetBrushColor(clYellow);
Circle(x0,y0,r);
if (x[1]=x0)and(y[1]=y0) then
begin
n:=n+1;
x0:=(Random(WindowWidth-210) div 10)*10+10;
y0:=(Random(WindowHeight-10) div 10)*10+10;
end;
for i:=2 to n do
if (x[i]=x0)and(y[i]=y0) then
begin
x0:=(Random(WindowWidth-210) div 10)*10+10;
y0:=(Random(WindowHeight-10) div 10)*10+10;
end;
b:=false;
for i:=2 to n do
if (x[1]=x[i])and(y[1]=y[i]) then b:=true;
until (keypressed)or(x[1] WindowWidth-210)
or(y[1] WindowHeight-10)or(b);
SetBrushColor(clWhite);
if (n>=33) then
begin
ClearWindow;
TextOut(300,150,’Победа! ‘);
end;
if (x[1] WindowWidth-210)
or(y[1] WindowHeight-10)or(b) then
begin
TextOut(300,150,’Поражение’);
TextOut(280,170,’n-начать заново’);
ch:=readkey;
while (ch<>‘n’)and(ch<>‘т’) do ch:=readkey;
goto metka2;
end
else
ch:=readkey;
if ch = #0 then ch := ReadKey;
case ch of
‘s’,’ы’,#80: begin dx:=0; dy:=10; end;
‘w’,’ц’,#72: begin dx:=0; dy:=-10; end;
‘d’,’в’,#75: begin dx:=10; dy:=0; end;
‘a’,’ф’,#77: begin dx:=-10; dy:=0; end;
‘p’,’з’: begin
TextOut(300,150,’Pause’);
p:=true;
while (p) do
begin
cp:=readkey;
if (cp=’p’)or(cp=’з’) then p:=false;
end;
end;
end;
if (n 7 лет назад
uses GraphABC,Events,Utils; //необходимые библиотеки подключены
var pr,px,py,kx,ky,ku,pc,s: integer; //переменные: положение ракетки, координаты мяча, коэффициенты отражения, положение ракетки компьютера
begin //иначе
showmessage(‘Вы упустили мячик!’); //выводим сообщение
inc(ku); //увеличиваем счетчик упущенных мячей
px:=15; //возвращаем мяч в исходную позицию у противоположной стенки
py:=250;
end;
px:=px+kx; //смещаем координаты на коэффициенты смещения
py:=py+ky;
end;
const
clPlayer = Color.BurlyWood;
var
kLeftKey,kRightKey: boolean;
kSpaceKey: integer;
/// Игрок
Player: RectangleABC;
/// Таймер движения врагов
t: Timer;
/// Флаг конца игры
EndOfGame: boolean;
/// Количество неигровых объектов
StaticObjectsCount: integer;
/// Счетчик выигрышей
Wins: integer;
/// Счетчик проигрышей
Falls: integer;
/// Информационная строка
InfoString: RectangleABC;
/// Сообщение в начале игры
NewGame: RoundRectABC;
type
KeysType = (kLeft,kRight);
/// Класс пули
Pulya = class(CircleABC)
public
constructor Create(x,y: integer);
procedure Move; override;
end;
/// Класс врага
Enemy = class(RectangleABC)
public
constructor Create(x,y,w: integer);
procedure Move;
program test;
uses crt;
var
A,B,C,D,E,F,T,W,L,Q:real;
begin
write(‘Угадай число (0-100) : ‘);
readln(C);
textcolor(red);
if C>100 then begin writeln(‘СЛИШКОМ БОЛЬШОЕ ЧИСЛО! ИНТЕРВАЛ: от 0 до 100’); T:=T+1; end;
if C C then writeln(‘нет, я загадала число побольше. ‘) else T:=T-1;
if B C then writeln(‘-1 жизнь’);
if B Похожие вопросы
Код для игры в паскале
1. Что необходимо?
Различных сред, использующих в качестве языка программирования Pascal, превеликое множество. Но из всей этой кучи для урока я решил использовать именно PascalABC.net. Почему? Ответ прост: во-первых данная среда программирования использует не чистый Паскаль, а его современный и более удобный потомок – Object Pascal; во-вторых Паскаль.Нет абсолютно бесплатна, а значит вам не придется парится с кряками или тратить деньги на лицензию.
2. Алгоритм.
Итак, у нас есть площадь 640×480, которая по моей задумке будет делиться на клеточки размером 8×8, представляющие из себя звенья массива 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. Нажатия клавиш.
Итак, чтобы далее вам не пришлось лазать по своей писанине, чтобы модифицировать код, создадим две отдельные процедуры, отвечающие за манипуляции с положением игрока.
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. Гравитация.
Неотъемлемой частью платформера является какая никакая, а сила тяжести. Поэтому сейчас мы должны написать отдельную процедуру, которая в дальнейшем поможет игроку встать на ноги в буквальном смысле.
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. Рисование.
Думаю тут понятно без лишних слов, но для галочки отмечу, что игра делится на «визуальную» и «невизуальную» части. «Невизуальная» отвечает за все происходящее в самой игре, а «визуальная», собственно, за отображение происходящего на экране. Так вот, данная ниже процедура отвечает за «визуальную» часть и только.
200?’200px’:»+(this.scrollHeight+5)+’px’);»> procedure Draw(); begin
//Рисуем белый прямоугольник…
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. Тело программы.
Вот мы и добрались, собственно, до самой программы. Тут нам необходимо заполнить массив нужными нам значениями, а также задействовать ранее написанные процедуры.
200?’200px’:»+(this.scrollHeight+5)+’px’);»> Begin //начало программы
//Указания значений для переменных
game_end:=false;
x:=0; //Стартовая позиция игрока по X
y:=0; //Стартовая позиция игрока по Y
//Создание массива
s := new integer[200,200];
//Создание платформы, нарисованной в процедуре Draw
for i:=0 to 79 do
s[i,24] := 1;
while game_end=false do begin //Создаем цикл…
//… который прервется, если game_end = false
//Рисование экрана
Draw();
//Гравитация для игрока
Gravity();
OnKeyPress:=KeyPress; //Обработка нажатий…
OnKeyDown:=KeyDown; //… клавиш
sleep(30); //Ждем примерно полсекунды, чтобы игра…
//… работала с нормальной скоростью
end. //конец программы
8. Заключение.
Итого у нас получился незамысловатый платформер с точкой в главной роли. Мы можем передвигаться по горизонтали и прыгать:
Код для игры в паскале
Эта программа на подобие PAINT.
procedure keydown(key: integer);
begin
if key=Vk_up then S:=S+1;
if key=Vk_down then S:=S-1;
if key=Vk_left then A:=A-1;
if key=Vk_right then A:=A+1;
if A=0 then A:=A+1;
if A=11 then A:=A-1;
if S=0 then S:=S+1;
if S=10 then S:=S-1;
end;
procedure MouseDown(x,y,mb: integer);
begin
MoveTo(x,y);
end;
procedure MouseMove(x,y,mb: integer);
begin
if S=1 then begin setbrushcolor(clwhite); circle(7,7,12); setpencolor(clblack); setbrushcolor(clblack); circle(7,7,A); end;
if S=2 then begin setbrushcolor(clwhite); circle(7,7,12); setpencolor(clgreen); setbrushcolor(clgreen); circle(7,7,A); end;
if S=3 then begin setbrushcolor(clwhite); circle(7,7,12); setpencolor(clred); setbrushcolor(clred); circle(7,7,A); end;
if S=4 then begin setbrushcolor(clwhite); circle(7,7,12); setpencolor(clblue); setbrushcolor(clblue); circle(7,7,A); end;
if S=5 then begin setbrushcolor(clwhite); circle(7,7,12); setpencolor(clyellow); setbrushcolor(clyellow); circle(7,7,A); end;
if S=6 then begin setbrushcolor(clwhite); circle(7,7,12); setpencolor(clbrown); setbrushcolor(clbrown); circle(7,7,A); end;
if S=7 then begin setbrushcolor(clwhite); circle(7,7,12); setpencolor(clsilver); setbrushcolor(clsilver); circle(7,7,A); end;
if S=8 then begin setbrushcolor(clwhite); circle(7,7,12); setpencolor(clpurple); setbrushcolor(clpurple); circle(7,7,A); end;
if S=9 then begin setbrushcolor(clwhite); circle(7,7,12); setpencolor(cllime); setbrushcolor(cllime); circle(7,7,A); end;
if mb=1 then circle(X,Y,A);
setbrushcolor(clwhite);
setpencolor(clwhite);
if mb=2 then circle(X,Y,A);
end;
begin
gotoxy(1,2);
write(‘меняйте цвет стрелками на клавиатуре вверх и вниз. стирать пкм, рисовать лкм.’);
gotoxy(5,1);
write(‘менять размер кисти стрелками влево и вправо.’);
Onkeydown:=keyDown;
OnMouseDown:=MouseDown;
OnMouseMove:=MouseMove
end.
Проектная работа по информатике по теме «Создание игры на языке Pascal»
Новые аудиокурсы повышения квалификации для педагогов
Слушайте учебный материал в удобное для Вас время в любом месте
откроется в новом окне
Выдаем Удостоверение установленного образца:
Муниципальное образовательное автономное учреждение
средняя общеобразовательная школа № 12 им. П.Ф.Дерунова
Создание игры на языке PASCAL
Выполнил: Ялычев Тимофей,
Научный руководитель: Говорова Е. А.
2019-2020 учебный год
— Почему я выбрал этот проект?
5 . Информационные ресурсы.
«Почему я выбрал именно эту тему?»
Я выбрал данную тему, потому что в будущем хочу стать программистом и разрабатывать разные программы и игры. Я решил начать с разработки простой игры, на знакомом всем школьникам языке PASCAL.
Цель: создать игру «Крестики-нолики» на языке программирования Pascal.
— Изучить материалы о языке Pascal
— Изучить алфавит языка Pascal
— Изучить особенности алгоритмического языка Pascal
Я предполагаю, что на языке программирования Pascal вполне возможно создать простейшую игру.
Язык был создан Никлаусом Виртом ( см. приложение 1.1) в 1968—1969 годах после его участия в работе комитета разработки стандарта языка Алгол-68. Язык назван в честь французского математика, физика, литератора и философа Блеза Паскаля, который создал одну из первых в мире механических машин, складывающую два числа. Первая публикация Вирта о языка датирована 1970 годом; представляя язык, автор в качестве цели его создания указывал построение небольшого и эффективного языка, способствующего хорошему стилю программирования, использующему структурное программирование и структурированные данные.
Язык Pascal является традиционным алгоритмическим языком. Правильная программа представляет собой формальную запись средствами языка некого алгоритма. Любая программа состоит из двух основных частей: описание последовательных действий и описание данных, которыми оперируют эти действия. Кроме того программа снабжена заголовком, который задает имя программы и завершается программа символом точки. Описание данных в программе предшествует описанию действий и должно содержать упоминание о всех объектах используемых в программе. Таким образом, общая структура программы выглядит следующим образом:
раздел описания переменных;
Особенности языка Pascal
Особенностями языка являются строгая типизация и наличие средств структурного (процедурного) программирования. Паскаль был одним из первых таких языков. По мнению Вирта, язык должен способствовать дисциплинированному программированию, поэтому, наряду со строгой типизацией, в Паскале сведены к минимуму возможные синтаксические неоднозначности, а сам синтаксис автор постарался сделать интуитивно понятным даже при первом знакомстве с языком.
Тем не менее, первоначально язык имел ряд ограничений: невозможность передачи функциям массивов переменной длины, отсутствие нормальных средств работы с динамической памятью, ограниченная библиотека ввода-вывода, отсутствие средств для подключения функций, написанных на других языках, отсутствие средств раздельной компиляции и т. п. Подробный разбор недостатков языка Паскаль того времени был выполнен Брайаном Керниганом в статье «Почему Паскаль не является моим любимым языком программирования»(эта статья вышла в начале 1980-х, когда уже существовал язык Модула-2, потомок Паскаля, избавленный от большинства его пороков, а также более развитые диалекты Паскаля). Некоторые недостатки Паскаля были исправлены в ISO-стандарте 1982 года, в частности, в языке появились открытые массивы, давшие возможность использовать одни и те же процедуры для обработки одномерных массивов различных размеров.
В данный момент, компьютер стал неотъемлемой частью жизни каждого из нас, а так же необходимостью во многих видах профессий. Именно поэтому изучение информатики приобретает такое большое значение. Сегодня в школах начинают изучение программирования с Паскаля, языка программирования, позволяющего писать самые простые программки, но которые идеально подходят для стартового обучения. Выпускники школ должны обладать высоким уровнем использования современных технологий для исполнения будущих начинаний. Язык Pascal относительно прост в изучении, довольно ясен и логичен и, будучи первым изучаемым языком программирования, приучает к хорошему стилю, воспитывает дисциплину структурного программирования.
Алфавит и словарь языка Паскаль
Язык – совокупность символов, соглашений и правил, используемых для общения. При записи алгоритма решения задачи на языке программирования необходимо четко знать правила написания и использования языковых единиц. Основой любого языка является алфавит (набор знаков, состоящий из букв, десятичных и шестнадцатеричных цифр, специальных символов).
Алфавит Паскаля составляют:
прописные и строчные буквы латинского алфавита:
Первая игра, которую я просто написал для себя
Пост ностальгии по игрушкам, которые мы сами для себя писали в детстве.
Лазая по просторам App Store ища очередную игрушку для своего айпада, наткнулся на старинную игрушку “Братья Пилоты”. Сразу купил, поставил и прошёл на одном дыхании (уже наверное в 3 раз). Но более всего задержался на эпизоде с холодильником. Уж больно меня прёт эта головоломка.
И внезапно вспомнил, что ещё в школьные годы, после прохождения холодильника, головоломка меня так накрыла, что я написал на паскале свою собственную игрушку — эмулятор головоломки. Но не просто повторяла исходную игру, а позволяла выбирать размер поля, имела хелп, возможность сохранения и продолжения игры с прошлого места после выхода.
Подняв старые бекапы я нашёл исходную игру. Запустил её в dosbox и пропал для внешнего мира на пару часов.
Исходная головоломка, обратите внимание на открытый левый столбец и положение вентилей
В чём же суть?
Суть головоломки достаточно проста. Имеется поле вентилей 4 на 4 штуки, необходимо все вентили на холодильнике поставить в горизонтальное положение. “Но есть нюанс”(с): когда вы поворачиваете вентиль, то вместе с ним поворачиваются все вентили в столбце и строке, в которой находится данный вентиль. И тут начинается самое интересное!
Когда я впервые сел за эту головоломку в исходном квесте, играя ещё в школе, то проходил её, наверное минут 40, не меньше. Но она до того мне понравилась, что я играл в неё играл и играл, и играл…
Но хотелось большего: возможность сохранять игровой процесс, генерировать разные уровни и менять размер поля, чтобы понять алгоритм игры.
Тогда я понял, что если мне головоломка нравится, и хочется попробовать разные масштабы игрового поля, то не стоит ждать у моря погоды. Есть только один выход — реализовать эту игру самостоятельно.
Ну’c, приступим!
Я не смогу точно определить дату создания игры, но это точно конец школы, начало института. В те годы я прекрасно владел паскалем. В институте решал на нём задачки за деньги, помогал писать курсачи и вообще — это был прекрасный логичный язык. Поэтому игрушку было решено писать на нём.
Не смотря на то, что я знал как реализовывать графику в ДОСе, я решил не делать графическое приложение. Это связанно с тем это бы страшно глючило и тормозило что, во первых, мне хотелось как можно быстрее реализовать данное приложение, а реализация графики отняла бы много времени; а во вторых, текстовый вид мне нравится больше. Хотя оглядываясь назад, мне кажется лучше бы я сделал графику и ещё добавил поддержку мыши.
Задача была простая: сделать простую изящную игру, которую не стыдно было бы показать. Из возможностей: помощь, возможность сохранения и после запуска продолжение игры с момента остановки, возможность изменять размер игрового поля. Плюс немного красок и изящества.
Реализация
Я не буду целиком разбирать исходники и логику работы всей программы, ибо они очевидны, а что не очевидно ясно из кода. Но более подробно остановлюсь на паре моментов.
Основу игры составляет текстовый массив NxN элементов, где N может быть равно 2, 4, 8 и 16. Массив заполнен всего двумя символами X и Y. Позиция курсора, это позиция текущего элемента массива i и j. При инвертировании элемента массива происходит замена X на Y и Y на X с столбце и строке массива. Ну и плюс есть горячие клавиши (F1-F4, F10), которые позволяют вызвать Помощь, Сохранить/загрузить, создать и выйти. Здесь всё ясно, и как реализовать просто и останавливаться мы на этом подробно не будем.
Наибольший интерес, с познавательной точки зрения, представляет процедура WRIFT.*
Программа была очень красивой и изящной для своего времени. И мне тогда весьма доставляла. Самое интересное, что там реализован полный шрифт, для 208 символов! Но я предполагаю, что автор взял реализацию программы типа нашего “русификатора”, только для иероглифов и переделал её под себя.
Правда, сейчас чтобы заставить программу нормально работать, даже в dosbox, надо уменьшить все задержки раз в 10 (delay), иначе конца работы дождутся ваши внуки. Поскольку переделывать программу мне лень, то она представляет чисто академический интерес. Или быть может кто её переделает и покажет миру, софтинка-то красивая (тем более я даю ссылку на сорцы). А если вдруг её автор читает сей пост, то передаю ему мои слова благодарности.
Самое главное, в той программе, для “кракозябр” реализован свой шрифт! И производится его загрузка. Вот эту процедуру загрузки я и позаимствовал, разумеется немного изменив её.
Пара слов о работе со шрифтами.
В MS-DOS средствами BIOS поддерживается работа с растровыми шрифтами. Функции BIOS позволяют получать и устанавливать пользовательские шрифты, а также получать шрифты из знакогенератора видеоадаптера. Все устанавливаемые шрифты имеют одинаковую ширину 8 точек, а высота может иметь три фиксированных значения — 8, 14 или 16 точек. Конкретное значение высоты шрифта определяется видеорежимом, для которого загружается шрифт. Высота шрифта 8 точек соответствует видеорежиму с 50/43 строками, высота 14 точек — видеорежиму с 25 строками для EGA, а высота 16 точек — видеорежиму VGA с 25 строками.
Мы будем использовать видеорежим 16 цветов 40х25 символов. В таком видеорежиме, каждый символ представляет собой массив точек 8х16. Говоря просто, каждый символ представляет собой 16 байт, где в байте бит выставленный в единицу означает то, что он окрашивается в чёрный цвет. Если у вас сейчас каша в голове, не пугайтесь — дальше станет понятнее.
Для обозначения закрытого (вертикального) вентиля была выбрана буква “X” (латинская заглавная буква “Икс”) и для открытого горизонтального, буква “Y” (латинская заглавная буква “Игрек”). Выбор был сделан на эти буквы по нескольким причинам. Во первых они знакомы из школьной программы и на слуху. Во вторых, и это важнее, они в таблице ASCII символов стоят подряд (88d и 89d позиция соответственно), что упрощает их замену. А латинские выбраны для того, чтобы можно было сделать меню на русском, без перезалива шрифта.
Итак, с символами мы определились, теперь перейдём к их одежде, ака шрифту. Берём лист бумаги в клетку, и делаем на нём поле 8х16 и приступаем к рисованию символа горизонтального, а затем вертикального вентиля. Поскольку вентиль должен быть одинаковым, как в вертикальном, так и горизонтальном состоянии, то мы будем использовать только первые 8 строк, чтобы получить квадрат. И далее рисуем в этом поле два вентиля, вертикально и горизонтально. Должно получится как-то так
Шрифт двух вентилей
Далее, чёрный квадратик обозначаем единичкой, белый нулём. И формируем 8 байт. После чего их переводим в десятичный формат и формируем массив. Сначала 8 байт символа, потом 8 байт нулей (подвал же мы оставили пустым), повторяем эту процедуру для второго символа.
Таблица двоичных кодов, и переведённые в десятичный формат
В результате получаем такую шапку процедуры:
Font — это массив двух символов вентилей (каждый символ на своей строчке). Самая интересная переменная — это массив screen1 — массив, который располагается по абсолютному адресу переменной Font (директива absolute). Далее наступает самое интересное.
Как понятно из строк выше мы загружаем в регистр ES — сегмент, а в регистр BP — смещение адреса расположение нашего шрифта. Командой mov bx,1000h мы говорим, что в шрифте у нас 16 строк (число 10h=16d загружаем в BH, а BL=0).Далее в регистр DX мы загружаем номер символа, с которого мы начинаем менять шрифт. А в CX — количество заменяемых символов. Загружаем в регистр AX — номер функции BIOS для смены шрифта, и вызываем прерывание BIOS. Далее восстанавливаем регистр BP и аналогичным образом выставляем режим видеоадаптера. Подробнее описано тут: shackmaster.narod.ru/fonts.htm. Для лучшего понимания о структуре шрифтов, лучше будет почитать этот сайт.
Таким вот нехитрым образом, можно сменить весь шрифт в ДОСе на свой собственный. Для того, чтобы выгрузить шрифт, используется процедура Restore:
Которая выполняется при выводе меню и выходе из программы.
Кстати, для справки, аналогичным образом в ДОСе работали, так называемые “русификаторы”. Они просто заменяли текущий шрифт, на шрифт с русскими буквами.
Модификации сегодня
На самом деле, игру я даю не в том виде, в котором она была написана много лет назад. В ней обнаружились весьма неприятные косяки:
1. Программа просто вылетала, если не был обнаружен файл GAME.SAV;
2. Генератор случайных чисел не был инициализирован, поэтому генерировал постоянно один и тот же уровень.
Плюс, из-за проблем с кодировками, я создал вторую версию игры, полностью на английском языке. И если вы будете читать исходный код не в ДОС-совместимом редакторе, рекомендую использовать её исходники — там не будет проблем с кодировкой.
Так отрадно, что ДОСбокс есть везде, лично я редактировал большую часть программы на iPAD в метро. Представляете, как забавно выглядит перец с айпадом, и открытым на нём Борланд Паскалем?
Старый добрый Borland Pascal на iPAD
Так что косяки оперативно исправлены.
Несколько скриншотов программы, с кратким описанием
Для тех у кого нет возможности или желания поиграть в игру, приведу несколько ключевых скриншотов игры.
После запуска, у нас открывается игровое поле с последней сохранённой игрой
Старт
Курсор подсвечен, и мигает.
Если нажать F1, то можно получить вот такой нехитрый хелп
Хелп
Для генерации уровня жмём F4 и попадаем вот в такое меню
Меню генерации уровней
Ну и после победы игра вас поздравит
Поздравление с победой
И будет ждать нажатия любой клавиши. В этом случае прогресс игры не сохраняется.
Как установить и играть
В Ubuntu я просто щёлкаю правой кнопкой мыши по программе и выбираю запустить её в dosbox, как в винде я не знаю, ибо её нет ни на одной из машин. Ну в крайнем случае монтируется путь до игры, командой mount путь.
На выбор вам русская и английская версия. Можно не морочиться с русификацией и геморроем с конфигами, а просто пулять в английскую. Разницы между ними практически нет. Хотя, лично я, как автор, предпочитаю русскую версию.
Управление производится стрелками клавиатуры, выбор и инвертация клавишей insert или двойным нажатием на пробел (да, тут косяк). Если вдруг заест позиция, нажмите один раз на пробел.
Помните, что каждый раз загружается последняя сохранённая игра. Для генерации новой, нажмите F4. Рекомендую начать с поля 4х4. Я сейчас играю 8х8, и пока боюсь переходить на 16х16. Ибо 4х4 я прохожу менее, чем за минуту, 8х8 минут за 7-10, а 16х16 боюсь даже представить.
Помните, что загрузочное поле с надписью HABR и моим ником (картинка в заходнике статьи), пропадёт после сохранения или легального выхода. Она хранится в файле GAME.SAV. Если хочется восстановить, то замените этот файл, на файл из архива.
Мне не хотелось просто так пускать игру, пусть и доделанную и допиленную для хабра. Хотелось какую-то фишечку. И я решил сделать надпись в самом большом поле 16х16.
Формат файла сохранения прост: начала идёт размер поля, например цифра 16, перевод каретки, потом 256 (для поля 16х16) символов X и Y, составляющие рисунок поля, а в конце количество Y в поле (этакая контрольная сумма).
Для этого в OF Calc я сформировал такое поле, цветом сделал надпись в клетках. А затем проставил соотсветственно буквы X и Y.
Заготовка для поля.
После чего сохранил его в CSV. Удалил все разделители. Посчитал количество Y (очень просто, делаешь во OF Writer поиск, заменить на и заменяешь Y на что-нить, он говорит количество замен — вот искомое число). Поставил сначала число 16, перевод каретки и в конце количество игреков. Результат вы можете оценить сами :).
Недостатки текущей версии программы.
Я написал текущей версии… Маловероятно, что я буду переписывать программу и совершенствовать её, ибо она уже страшно устарела. Но с другой стороны, сейчас dosbox можно поставить чуть ли не на фонарик, по этому она может обрести новую жизнь, и быть может имеет смысл переписать и исправить основные недостатки.
1. Первый, и самый неприятный недостаток — это убогое управление. Во первых инвертация идёт клавишей Insert, или двойным пробелом. При чём, если пробел нажать нечётное количество раз, то программа “заедает”, пока не сделаешь чётное количество нажатий. Это раздражает.
2. Второй существенный недостаток — это отрисовка всей игры с помощью функций write/writeln. При каждом событии экран перерисовывается заново. При игре на поле 16х16 уже заметны тормоза и вспышки отрисовки. Плюс такой подход усложнил логику программы, и теперь её поправить громадная проблема.
Надо было реализовывать отрисовку с помощью функции goto(x;y); Тогда можно было бы менять отдельный символ, не перерисовывая весь экран.
3. Игра просто просит поддержку мыши. Опять же поддержку мыши нужно реализовывать на пару с п. 2, чтобы можно было точно “ловить” координаты.
4. Мелкий баг, который следует из п.2 — когда спускаешься в правый нижний угол, за рамку убегает один символ. Пытался исправить, и понял что проще вообще переписать это место отрисовки, чем разобраться как оно работает.
Что хотелось бы сделать
Конечно, хотелось бы такое приложение под ведройд или iPad. Чтобы можно было в него играть пальцем. Или уж, если не приложение, то браузерную игрушку (но такую, чтобы работала под Android и iOS). Чтобы там было красивое меню и удобная навигация. Была таблица рекордов. Был счётчик времени, которым можно было бравировать с друзьями. Так же была статистика, чтобы можно было оценить среднее время и скорость навыка.
В общем громадный полёт для творчества, при полном отсутствии свободного времени на изучение программирования под эти устройства. С другой стороны, dosbox есть везде, и наверное более универсальной переносимости добиться будет сложно, и может имеет смысл допилить таки эту программу? Как вы думаете?
Итоги.
Цель статьи, не показать какой я молодец, а просто вспомнить как было. Наверняка практически каждый из нас писал что-то такое в детстве. Это не ах какая сложная программа, и её может написать каждый школьник, при достаточной усидчивости. Здесь скорее пост воспоминание.
Раньше я в программах много использовал ассемблер. Мне нравилось “говорить” с железом напрямую, без посредников. Я лучше чувствовал машину. И даже потом, для AVR я писал исключительно на ассемблере. А сейчас я не понимаю, как функционирует ЭВМ. Конечно, я представляю базовые блоки и т.п., но детальную картину я не знаю, и самое забавное, что её не знает никто!
А сейчас… Языки высокого и сверх высокого уровня абстракции вообще заставляют нас не думать, как и где исполняется код. Это без сомнения хорошо, ибо позволяют сосредоточиться непосредственно на задаче, но с другой стороны уходит тот тёплый ламповый шарм работы с железом…