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

О.Д. Любутов (Ереван)

Редактор спрайтов для БК-0010

Безусловно, хорошая игровая программа - это достаточно сложный программный продукт, удовлетворяющий целому комплексу требований. Прежде всего игровая программа должна быть интересна играющему. Как показывает опыт, современного "игрока" (назовём так потенциального пользователя игровых программ) можно условно разделить на два типа: К первому относятся те "игроки", кто не имеет постоянного доступа к компьютерам и новички. Они любят исключительно "динамические игры", т.е. такие, где "игрок" действует в режиме "реального времени", где много перемещений, много стрельбы, много изменений игровой обстановки и где совершенно некогда думать, а полагаться можно лишь на свою реакцию и интуицию. Это такие игры как: "Пакман", "Ксоникс", "Тетрис", "Спейс комадор", "Хью-кобра" и др.

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

К классическим "диалоговым" играм относятся многочисленные экономические игры ("Монополия", "Президент", "Менеджмент", "Биржа" и др., а также множество программ, реализующих известные "некомпьютерные" игры ("Шахматы", "Шашки", "Рендзю", "Реверси" и. т.д.).

В последнее время появились "смешанные" игры, которые сочетают в себе достоинства как "динамических", так и "диалоговых" игр. Это такие игры как: "Пещера", "Легион" и др.

Первый тип "игроков" наиболее многочисленный, а в условиях нашего "безмашинья” он и определяет спрос на игровые программы. Следовательно, необходимо сначала писать именно "динамические игры". Каким же требованиям должна удовлетворять хорошая "динамическая" игра?

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

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

Для игры очень большое значение имеет внешнее оформление (разнообразные графические объекты, цвета, звук), а также скорость перемещения графических объектов. Здесь, конечно, нужно исходить из возможностей компьютера. В игровых зарубежных компьютерах ("Ямаха", "Атари", "Коммодор", "Синклер" и др.) специально предусмотрена аппаратная поддержка игровых эффектов, это и многоканальные звуковые генераторы, и большое количество режимов экрана, и наконец спрайты.

Отечественные компьютеры этого класса, к сожалению, не могут пока обеспечить ничего подобного. Одним из самых распространённых отечественных бытовых компьютеров является БК-0010.

Недостатки этой модели уже неоднократно отмечались в печати. Это и очень маленькое ОЗУ (а Вильнюсская версия Бейсика съедает его добрую половину), и слабая аппаратная поддержка, о которой уже говорилось (например неудачная организация клавиатуры по образцу ДВК когда нет возможности определить нажатие более одной клавиши, а это очень важно в игре), и многое другое.

Поэтому попробуем использовать то, что есть. А есть у нас 16-разрядный процессор (У большинства игровых зарубежных 8-ми разрядный), т.е. быстродействием мы не обижены, ещё есть хороший драйвер магнитофона (по крайней мере, намного лучше, чем драйвер "Атари"), есть экранное ОЗУ в 16 Кбайт с возможностью окраски любой точки в любой из четырёх цветов ("Ямаха" лишена такой возможности), и, наконец есть 16-разрядный программируемый параллельный интерфейс (проще Порт), который очень удобно использовать для подключения джойстика (верньерного устройства).

Большое значение имеет так же выбор языка программирования. ФОКАЛ не позволяет писать игровые программы из-за своей черепашьей скорости, на АССЕМБЛЕРе написать большую игровую программу под силу только очень опытному программисту, да и времени на это уйдёт не один месяц, значит остаётся БЕЙСИК. Несмотря на все недостатки нельзя не отметить его очень высокое быстродействие (с целыми переменными) и возможность делать вставки в машинных кодах. Именно эти два достоинства и позволяют писать вполне приличные игровые программы.

Одна из самых главных задач при написании игры - задача перемещения графических объектов по экрану. Самое простое решение этой задачи (и конечно далеко не самое удачное) это нарисовать графический объект, дать небольшую задержку, стереть его и тут же нарисовать на новом месте.

Недостатки этого метода очевидны: даже если мы не будем использовать "медленные" операторы БЕЙСИКа (LINE, DRAW, PSET, PAINT, которые не годятся для динамической игры), а используем для этого вставку в машинных кодах, все рано при стирании старого положения графического объекта изображение на экране будет заметно "мерцать".

Избежать этого просто. Чаще всего объект перемещается на определённый шаг в каком-либо направлении и значение шага в 2 - 4 раза меньше протяжённости самого объекта (при таком шаге перемещение видится плавным и достаточно быстрым). Используя это можно предложить следующий метод: на экран накладывается не только сам графический объект, но и "окаймление" вокруг него с цветом фона (высота и ширина окаймления равна шагу перемещения в соответствующем направлении). Теперь замена "старого" изображения на "новое" проводится только одним действием - наложением "нового" изображения на "старое" со смещением (шагом) в нужном направлении. В этом случае мерцания не происходит, так как "старое" изображение стирается лишь частично, да и то одновременно с появлением на экране нового изображения.

Этот метод даёт очень хорошие результаты для многих (почему не всех - будет сказано позже) динамических игр. Для его реализации необходимо иметь "библиотеку графических образов", где будут храниться все рисунки необходимые для игры, и программу в машинных кодах, которая будет осуществлять копирование части ОЗУ "библиотеки" в ОЗУ игрового поля.

Остановимся на этом методе поподробнее. Начнём с выбора оптимального размера графического объекта. Как показывает опыт наиболее удобны для визуального восприятия (с учётом размеров экрана, количества точек на нём, а также аппаратной организации ОЗУ экрана) такие размеры (все данные даются для режима 32 символа в строке): по горизонтали 4, 8, 12, 16, 20, 24, 28, 32 точек (чаще всего 16), по вертикали от 1 до 20 (чаще всего 18). Большое значение имеет так же цвет объекта. Необходимо, чтобы он смотрелся наиболее контрастно на окружающем его фоне. Но поскольку в БК-0010 всего четыре цвета, то все они (кроме синий на чёрном) смотрятся достаточно контрастно. Во многих игровых программах требуется, чтобы объект "висел" над фоном (различные самолёты, шары в спортивных играх и т.д.). Такой эффект очень хорошо достигается с помощью тени (тень желательно давать черным цветом, следовательно, фон должен быть другого цвета, например, красного). Тень необходимо перемещать параллельно объекту, причём от расстояния между ним и тенью зависит мнимая высота объекта над фоном. Для того чтобы два объекта при совпадении их траекторий не "наезжали" друг на друга (при этом они начинают мерцать, так как выводятся поочерёдно в одно и тоже место экрана) необходимо перед перемещением объекта в нужную сторону проверить отсутствие там другого графического объекта.

Итак, всем хорош данный метод кроме одного: он обязательно требует полностью однородного фона. Именно поэтому он и не подходит для всех игр. Там, где, например, самолёт пролетает над сложным рельефом, этот метод непригоден, так как он "затрёт" фон по мере своего перемещения.

Существуют и другие методы перемещения без "стирания фона". Например, в GWBASIC IBM PC существуют графические операторы GET и PUT, которые запоминают графический образ в массиве, а затем позволяют накладывать его в нужное место экрана, совершая над ним и экраном операцию "исключающее или". Если затем повторить эту операцию, то на этом месте любой фон будет восстановлен. Но этот метод имеет массу недостатков. Цвет самого объекта, наложенного на сложный фон, изменяется в зависимости от цвета фона. Перемещение объекта проходит за два такта (а не за один, как в предыдущем случае), поэтому объект (если он крупный) все-таки "мерцает". И если первый недостаток ещё можно устранить, использовав два массива (один для объекта, другой для фона) и операцию PSET (замещение), то от второго недостатка избавиться намного сложнее.

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

Как уже говорилось выше, на многих бытовых компьютерах спрайты организованы аппаратно. Аппаратная организация спрайта это отдельное ОЗУ, где хранится "маска" рисунка, который "накладывается" на определённое место экранного ОЗУ, а на экран выводится уже общая картина. Спрайтов обычно бывает несколько (от 8 до 64) в зависимости от компьютера, каждый из них может перемещаться по экрану в произвольно заданном слое. Послойная организация необходима для обеспечения "наложения" "ближних" спрайтов на "дальние".

Такая аппаратная поддержка позволяет писать зрелищные игровые программы даже на относительно "слабых" восьмиразрядных компьютерах.

Поскольку БК-0010 лишён аппаратных спрайтов, то возникает необходимость написания программы, имитирующей спрайт. Для создания такой программы необходимо решение двух задач:

  1. Необходимо перемещать рисунок по экрану без "мерцания".
  2. Нужно, чтобы сложный фон "под рисунком" не изменялся".

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

Для его реализации необходимо дополнительное ОЗУ, состоящее из трёх частей. В первой части будет храниться "маска" рисунка, т.е. то, что будет накладываться на фон. Во второй (равной по величине первой) будет храниться часть фона, которую "закрывает" на экране рисунок. В третьей части (большей по объёму) будут производиться все действия (накладка маски, замена фона и т.д.), а затем уже подготовленная картинка будет целиком копироваться в нужное место экрана.

Если размеры рисунка ("маски"), например, А*В, а величина шага перемещения рисунка по экрану С, то соответственно размеры первой, второй и третьей частей будут А*В, А*В, (А + С)*(В + С)

Для "облегчения" алгоритма третью часть ОЗУ я взял несколько больше (А + 2*С)*(В + 2*С).

В графическом виде это будет выглядеть так:

A – Первая часть ОЗУ

B – Вторая часть ОЗУ

C - Третья часть ОЗУ

D - ОЗУ экрана

Алгоритм перемещения спрайта будет выглядеть следующим образом:

  1. Начальная установка спрайта:
    1. Из нужного места D копируем содержимое в C
    2. Из C копируем среднюю часть в B
    3. Накладываем A на среднюю часть C
    4. Копируем C в нужное место D
  2. Перемещение спрайта:
    1. Копируем из D в C со смещением на один шаг в нужную сторону, так чтобы "старый" рисунок сместился из средней части C к границе.
    2. Копируем B в C, затирая "старый" рисунок сохранённым в B фоном.
    3. Копируем среднюю часть C в B, чтобы запомнить в B "новый" фон.
    4. Накладываем A на среднюю часть C.
    5. Копируем C в нужное место D.
  3.  Для того чтобы убрать спрайт с экрана есть два метода. Либо использовать "чёрную" маску, либо (если нет такой возможности) выполнить подряд 1, 2, 3, 5 пункты (пропустив 4) из II раздела (перемещение спрайта).

Программа, реализующая данный алгоритм достаточно точно имитирует аппаратный спрайт. Единственное отличие (и недостаток) данного метода в том, что он не допускает изменения той части фона, которая находится "под спрайтом". Но даже при этом недостатке данный алгоритм позволяет создавать игровые программы практически не уступающие "фирменным".

Именно этот алгоритм реализован в программе "Редактор спрайтов" в виде вставки в машинных кодах. Кроме этого алгоритма в этой программе реализован алгоритм копирования части ОЗУ (заданных размеров) в другое место ОЗУ.

Краткая характеристика программы "RS"

Программа "RS" предназначена для создания, редактирования и сохранения на магнитной ленте библиотеки графических образов. Библиотека графических образов в дальнейшем используется в игровых программах вместе с подпрограммой "спрайт" для обеспечения перемещения по экрану графических объектов.

Файл, записанный на магнитной ленте, может быть использован программой на языке БЕЙСИК, что позволяет сохранить до 2 кБайт программного ОЗУ.

Кроме графических образов в файл, по желанию пользователя, включаются две подпрограммы в машинных кодах: п/п "Спрайт" и п/п "Перемещение".

Текст программ "Спрайт" и "Перемещение":

Адрес:

Восьмеричные коды:

37400

12737

112021

37626

4537

37410

37606

12700

431

12701

37420

650

12702

24

112120

37430

112120

112120

112120

5720

37440

5302

1371

12700

451

37450

61500

10003

12701

650

57460

12702

24

112021

112021

37470

112021

112021

5720

5502

37500

1371

10300

12701

0

37510

12702

24

12703

4

37520

111104

10405

6304

50504

37530

42704

125

10405

6204

37540

50504

140410

111005

112104

37550

60504

110420

5303

1360

37560

62701

74

5720

5302

37570

1351

12737

112120

37626

37600

4537

37606

207

12700

37610

0

12701

400

12702

37620

34

12703

6

0

37630

5303

1375

62700

72

37640

5302

1367

205

11500

37650

12704

100

163704

37672

37660

12701

0

12702

0

37670

12703

0

112120

5303

37700

1375

60400

60401

5302

37710

1367

207

 

 

 

Подпрограмма "Перемещение" предназначена для реализации процесса перемещения рисунка по экрану. Размеры рисунка в данном случае могут варьироваться в больших пределах. Подпрограмма копирует часть ОЗУ (например, ОЗУ экрана) в другое место экрана. Начало подпрограммы находится по адресу 37646 (восьмеричное), соответствующий оператор БЕЙСИКа:

DEF USR1 = &O37646.

Перед обращением к подпрограмме необходимо задать следующие параметры:

После этого нужно обратиться к подпрограмме, передав ей адрес приёмника (куда копируем).

А% = USR1 (<адрес>)

Получив управление, подпрограмма скопирует часть ОЗУ с заданными размерами из источника в приёмник.

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

Подпрограмма "Спрайт" предназначена для перемещения по экрану цветного графического объекта фиксированных размеров, 16x20 точек, без затирания фонового рисунка на экране.

Начало подпрограммы находится по адресу 37400

DEF USR0 = &O37400

Адрес "маски" (изображения) засылается в ячейку 37506

POKE &О37506, <маска>

Для предварительного задания местоположения спрайта необходимо заслать в ячейку 37610 адрес верхнего левого угла спрайта, уменьшенного на 401

РОКЕ &O37610, <адрес>-&O401

Для высвечивания спрайта на пустом месте (начальная установка) необходимо сначала заслать в ячейку 37412 число 414, после чего фиктивно обратиться к подпрограмме (с параметром 0), а затем снова записать в ячейку 37412 число 12700

POKE &O37412, &O414
А% = USR0(0%)
POKE &O37412, &O12700

После этого можно приступать к перемещению спрайта. Перемещение спрайта осуществляется с помощью приращения по горизонтали DX%, и по вертикали DY%

DX% = [-1;0;1]

соответствует 4 точкам

DY% = [-4;-3;-2;-1;0;1;2;3;4]

соответствует 1 точке

Для перемещения спрайта в нужном направлении необходимо выполнить следующие действия:

А% = USR0(DY%*6% + DX%)
POKE &O37610,PEEK(&O37610)+DY%*64%+DX%

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

POKE &O37502, &О433
А% = USR0(0%)
РОКЕ &O37502, &O10300

В результате выполнения этих операторов спрайт станет невидимым.

Инструкция по эксплуатации и описание работы программы "Редактор спрайта".

Программа ''Редактор спрайтов" проста в эксплуатации и не требует специальных знаний от пользователя.

После запуска программы и прохождения заставки на экране высвечивается меню, состоящее из трёх режимов:

Выбранный режим высвечивается красным цветом (остальные два режима - зелёным). Переключение режимов осуществляется с помощью клавиш <вверх> и <вниз>. Запуск режима клавише <ввод>. При нажатии клавиши <Н> на экран выводится вспомогательная информация.

Режим "Чтение файлов с ленты"

Программа запрашивает имя файла на чтение. Если вместо имени нажать <ввод>, то программа вернётся в меню. Если имя файла задано, на экране появляется надпись: ''Включите магнитофон и нажмите любую клавишу (кроме клавиши <ввод>)".

После нажатия любой клавиши экран очищается и происходит чтение файлов с ленты. На экран выводятся имена встретившихся файлов, а заданный файл загружается в ОЗУ с восьмеричного адреса 37400. Если файл не считался, то на экран выводится соответствующее сообщение и программа возвращается в режим "Чтение файла с ленты".

Режим "Запись файла на ленту"

Программа запрашивает имя файла на запись. Если вместо имени нажать <ввод>, то программа вернётся в меню. Если имя файла задано, на экране появляется надпись: "Включите магнитофон и нажмите любую клавишу (кроме клавиши <ввод>)". После нажатия любой клавиши происходит запись части ОЗУ начиная с адреса 37400. Длина записи зависит от информации на экране.

Режим "Редактирование спрайтов"

Это основной режим программы. При его вызове на экране возникает таблица с информацией. Режим "Редактирование спрайтов" имеет два подрежима - графический и цифровой.

В графическом режиме в таблице высвечивается окно из 18x24 элементов (в виде цветных квадратов), каждый из которых соответствует точке на экране. Окно может перемещаться в верхней части экрана по вертикали и горизонтали. Местоположение окна по горизонтали индицируется горизонтальной линией длиной 24 точки. Для более точного определения местоположения "окна" в левой части таблицы выводятся абсолютные адреса ОЗУ, соответствующие адресам левых восьми точек в каждой строке. Таким образом, в таблице отображается часть экрана, увеличенная в 8-10 раз. По всей площади ''окна" (18x24) перемещается мерцающий курсор (с помощью клавиш (вправо), (влево), (вверх), (вниз)). Если курсор попытаться вывести за пределы "окна'', то произойдёт автоматическое смещение координат окна в нужную сторону. По вертикали окно перемещается с дискретностью в одну точку, а по горизонтали дискретность перемещения восемь точек. Слева от таблицы, внизу, высвечивается "образец текущего цвета". Это квадрат, который закрашен в тот цвет, с каким в данный момент работает редактор. Для смены цвета служит клавиша <С>(color). Для того, чтобы нарисовать в нужном месте точку нужного цвета, необходимо задав цвет клавишей <С>, и установив курсор стрелочными клавишами, нажать клавишу <пробел>. После этого на месте курсора в "окне" появится квадрат, а в соответствующем месте экрана высветится точка заданного цвета. С помощью графического режима пользователь может создавать образцы графических объектов, которые он затем сможет использовать, например, в игровых программах.

После того, как закончено формирование графических объектов, нужно нажать клавишу (ввод). Внизу экрана появляется надпись* "Включить п/п "СПР" в ОЗУ? (Д/Н)". Если нажата клавиша (Д), то начиная с адреса 37400 в ОЗУ записываются две подпрограммы: подпрограмма "Перемещение" и "Спрайт". Обе эти подпрограммы написаны в машинных кодах и могут быть использованы для организации перемещений графических объектов в различных программах. Способ использования обеих подпрограмм описан в предыдущей части.

"Редактор спрайтов" позволяет так же редактировать информацию в восьмеричной форме. Для этого создан цифровой подрежим редактора. Он служит для исправления существующих и написания новых программ в машинных кодах. Для перехода в цифровой режим необходимо нажать клавишу (8). В этом случае вся информация в окне будет представляться в привычном всем программистам восьмеричном виде. Информация редактируется с помощью стрелочных клавиш и цифровых клавиш (0-7) При изменении цифровой информации в "окне" изменяется и соответствующая информация в ОЗУ. Во всем остальном этот режим аналогичен графическому. Для перехода в графический режим нужно нажать клавишу (9).

Описание работы программы

Прежде чем приступить к описанию работы программы несколько рекомендаций.

  1. Все комментарии в начале программы необходимо исключить в целях экономии памяти (но даже если вы будете набирать программу целиком эти строки исчезнут сами собой).
  2. Не набирайте программу подряд. Прежде наберите строки с оператором DATA и проверьте правильность их ввода следующей программой:
1 S! = 0
2 FOR I= 1 ТО 218
3 READ А%
4 S! = S! + А%
5 NEXT I
6 ? S!

Запустите программу и если она выдаст значение 767045 то наберите: DELETE-6 и продолжайте набор оставшейся части программы (как правило, ошибки при наборе происходят именно в блоке данных). В противном случае проверьте правильность набора данных в операторах DATA.

Ну а теперь о самой программе.

Программа состоит из "рекламы" (строки 2850-3205), трёх основных режимов:

и множества мелких вспомогательных подпрограмм, например:

и так далее.

В подпрограммах "Чтение" и "Запись" я использовал программу, предложенную Д. Бароновым в девятом номере "Вычислительной техники" за 1988 год. Компактность этой программы позволяет включать её практически в любую программу на БЕЙСИКе.

Строка 10 обеспечивает стирание экрана, установку "рулона" в начальное положение, и стирание "командной строки" экрана. В 20-й строке вызывается рекламная заставка, поэтому останавливаться на её описании не стоит.

В строках 35-150 происходит очистка экрана и загрузка в ОЗУ подпрограмм в машинных кодах ("Чтение/запись", "Графический режим").

В строках 140-180 происходит стирание экрана и вывод меню. В строках 210-340 организуется опрос клавиатуры и перемещение курсора с выбором соответствующего режима работы. В зависимости от значения переменной К% вызывается либо подпрограмма "Чтение" (350-570), либо "Запись" (580-800), либо "Редактирование" (1890-2810)

И, наконец, чтобы проверить работоспособность программы DEM.ASC (или DEM.COD) рекомендуется создать с помощью программы "Редактор Спрайтов" на ленте файл "DEM" с изображением двух графических объектов. Чтобы создать этот файл на ленте необходимо войти в режим "Редактирование спрайтов" в цифровой подрежим и набрать следующую информацию. Информация набирается сверху вниз (адреса даны для ориентира, набираются только числа в нужном месте.)

Адрес:

Число:

Адрес:

Число:

Адрес:

Число:

Адрес:

Число:

40000

1760

40002

7700

40006

1760

40010

7700

40100

7774

40102

37760

40106

7774

40110

37760

.....

37777

.....

177774

.....

37777

.....

177774

.....

177777

.....

177777

.....

177777

.....

177777

.....

153777

.....

177727

.....

153777

.....

177727

.....

40774

.....

37501

.....

40774

.....

37501

.....

46760

.....

7501

.....

40760

.....

7501

.....

40701

.....

1501

.....

40700

.....

41501

.....

177701

.....

1777

.....

177700

.....

41777

.....

37705

.....

1774

.....

37700

.....

51774

.....

1725

.....

53700

.....

1725

.....

53700

.....

1725

.....

53700

.....

1725

.....

53700

.....

7400

.....

50360

.....

7405

.....

360

.....

177400

.....

40377

.....

177401

.....

377

.....

176000

.....

40077

.....

176001

.....

77

.....

12520

.....

24

.....

12000

.....

2524

41700

0

41702

24

41706

12000

41710

0

42000

0

42002

2524

42606

12520

42010

0

 

После ввода этой информации на экране должно появиться две картинки, изображающие мышь в двух различных положениях. Первая картинка должна быть в левом верхнем углу экрана, а вторая на 8 точек правее первой. Если все получилось правильно, нажмите <Ввод>, и после появления надписи "Включить п/п "СПР" в ОЗУ? (Д/Н)", нажмите клавишу <Д>. После этого выберите режим "Запись" и запишите на ленту файл "DEM".

После этого вы можете, вызвав файл DEM.ASC (или DEM.COD), запустить его на выполнение. Сразу после очистки экрана включите магнитофон с файлом "DEM" (тем, что создан программой "Редактор спрайтов"). Он должен загрузиться (в верхней части экрана появится изображение) и по случайно закрашенному фону изображение начнёт перемещаться в различных направлениях, и меняя свою скорость. Таким образом, написав вместо программы DEM.ASC любую другую программу пользователь может, используя файл, созданный программой "Редактор спрайтов" (в качестве библиотеки графических объектов и подпрограммы перемещения этих объектов), сохранить для своих нужд до 2 кБ программного ОЗУ и получить возможность писать зрелищные и эффектные программы.

10 'Демонстрационная программа по использо-
10 'ванию подпрограммы "Спрайт" и библиотеки
10 'графических образов, которые были созда-
10 'ны и записаны на магнитную ленту прог-
10 'рамной *Редактор Спрайтов* (файл называ-
10 'ется "DEM"). Данная программа может слу-
10 'жить примером фрагмента игровой програм-
10 'мы или графического редактора
10 ?CHR$(&O214)CHR$(&O214)CHR$(&O224)CHR$(&O236)
20 FOR I%=&O400 TO &O414 STEP 2%
30 READ A%
40 POKE I%,A%
50 NEXT I%
60 DEF USR1=&O400
70 DEF USR2=&O100602
80 POKE &O320,3%
90 POKE &O322,&O37400
100 A$=USR1("DEM             ")
110 A%=USR2(A%)
120 IF PEEK(&O320)\256%>0% THEN 110
130 DEF USR3=&O37400
140 FOR I%=0% TO 100%
145 LINE(RND(1%)*255%,RND(1%)+239%+10%)-(RND(1%)*255%,RND(1%)*239%+10%), RND(1%)*3%+0.6!
150 NEXT I%
160 COLOR 1%
200 POKE &O37610,&O60000
205 POKE &O375O6,&O40402
210 POKE &O37412,&O414
215 A%=USR3(0%)
220 POKE &O37412,&O12700
221 N%=16642%
230 DY%=1%
231 DX%=1%
235 FOR I%=0% TO 6000%
236 IF I% MOD 4%=0% THEN N%=33290!-N%
237 POKE &O37506,N%
240 A%=USR3(DY%*6%+DX%)
245 POKE &O37610,PEEK(&O37610)+DY%*64%+DX%
246 FOR R%=0% TO Z%
247 NEXT R%
250 P%=PEEK(&O37610)
251 IF P%>&O74000 OR P%<&O41100 THEN DY%=-DY%
252 P%=PEEK(&O37610) MOD 64%
253 IF P%>57% OR P%<1% THEN DX%=-DX%
255 IF I% MOD 50%<>0% THEN 270
260 IF ABS(DY%)=4% THEN DY%=SGN(DY%) ELSE DY%=(ABS(DY%)+1%)*SGN(DY%)
265 IF I% MOD 1000%=0% THEN Z%=200%-Z%
270 NEXT I%
500 STOP
1000 DATA 5443%,4930%,5569%,214%,-27503%,32450%,135%

 

10 'Программа *Редактор Спрайтов*
10 'Любутов О.Д. Г. Ереван ул. Церетели
10 'д. 46 кв. 38 тел. 42-33-96
10 'Версия 1.0 1990 Г.
10 ?CHR$(&O214)CHR$(&O214)CHR$(&O224)CHR$(&O236)CHR$(&O221)
20 GOSUB 2850
30 TT%=-1%
35 RESTORE 1650
40 GOSUB 870
50 FOR I%=&O400 TO &O514 STEP 2%
60 READ J%
70 POKE I%,J%
80 NEXT I%
90 DEF USR0=&O416
100 DEF USR1=&O400
110 DEF USR2=&O100602
120 DD%=&O37400
130 POKE &O322,DD%
140 GOSUB 870
150 GOSUB 1250
160 COLOR 2%
170 GOSUB 810
180 ? AT(9%,23%)"Помощь - клавиша H";
190 K%=1%
200 GOSUB 1190
210 I$=INKEY$
220 IF I$<>CHR$(26%) THEN 250
230 IF K%=1% THEN K%=3% ELSE K%=K%-1%
240 GOSUB 1190
250 IF I$<>CHR$(27%) THEN 280
260 IF K%=3% THEN K%=1% ELSE K%=K%+1%
270 GOSUB 1190
280 IF I$<>CHR$(72%) AND I$<>CHR$(104%) THEN 310
290 GOSUB 1480
300 GOTO 150
310 IF I$<>CHR$(10%) THEN 210
320 ? AT(9%,23%)STRING$(18%,32%);
330 ON K% GOSUB 350,580,1890
340 GOTO 150
350 CLS
360 GOSUB 870
370 GOSUB 810
380 ? AT(9%,5%)"Имя файла на чтение:"
390 GOSUB 1290
400 ? AT(11%,8%);
410 COLOR 1%
420 INPUT A$
430 COLOR 2%
440 IF A$=CHR$(10%) THEN RETURN
450 A$=A$+STRING$(16%-LEN(A$),32%)
460 POKE &O320,3%
470 GOSUB 1310
472 ? AT(0%,4%);
480 I$=INKEY$
490 IF I$=CHR$(10%) THEN 350
500 IF I$="" THEN 480
501 GOSUB 1250
502 ? AT(0%,4%);"Найдены файлы:"
510 A$=USR1(A$)
520 I%=USR2(I%)
530 IF PEEK(&O320)\256%=0% THEN RETURN
540 GOSUB 1250
550 ?AT(2%,5%)"К сожалению файл не считался"
560 ?AT(3%,7%)"Попробуйте повторить чтение"
570 IF INKEY$="" THEN 570 ELSE GOTO 350
580 GOSUB 1250
590 GOSUB 810
600 ? AT(9%,5%)"Имя файла на запись:"
610 GOSUB 1290
620 ? AT(11%,8%);
630 COLOR 1%
640 INPUT A$
650 COLOR 2%
660 IF A$=CHR$(10%) THEN RETURN
670 A$=A$+STRING$(16%-LEN(A$),32%)
680 POKE &O320,2%
690 I%=&O43576
700 IF PEEK(I%)<>0% THEN 730
710 I%=I%-2%
720 IF I%>=DD% THEN 700 ELSE RETURN
730 POKE &O324,I%-DD%+2%
740 GOSUB 1310
750 I$=INKEY$
760 IF I$=CHR$(10%) THEN 580
770 IF I$="" THEN 750
780 A$=USR1(A$)
790 I%=USR2(I%)
800 RETURN
810 ?AT(6%,3%)CHR$(170%);STRING$(24%,181%);CHR$(163%);
820 FOR I%=4% TO 21%
830 ?AT(6%,I%)CHR$(183%)AT(31%,I%)CHR$(183%);
840 NEXT I%
850 ?AT(6%,22%)CHR$(166%);STRING$(9%,181%)"=LOD="STRING$(10%,181%);CHR$(185%);
860 RETURN
870 FOR I%=&O37400 TO &O42000 STEP 2%
880 POKE I%,0%
890 NEXT I%
900 RETURN
910 F%=&O45400+(TA% MOD 64%)
920 POKE F%-2%,0%
930 FOR I%=F% TO F%+4% STEP 2%
940 POKE I%,TT%
950 NEXT I %
960 POKE F%+6%,V%
970 LOCATE 0%,0%,0%
980 ? AT(0%,4%);
990 FOR I%=TA% TO TA%+1088% STEP 64%
1000 ? OCT$(I%)
1910 NEXT I%
1020 IF R%=1% THEN 1410
1030 TY%=19328%
1040 FOR I%=TA% TO TA%+1088% STEP 64%
1050 TY%=TY%+640%
1060 TX%=-2%
1070 FOR J%=I% TO I%+4% STEP 2%
1080 TX%=TX%+16%
1090 POKE &O456,TY%+TX%
1100 A%=USR0(J%)
1110 NEXT J%,I%
1120 RETURN
1130 ? AT(8%,7%)"ЧТЕНИЕ ФАЙЛА С ЛЕНТЫ   "
1140 RETURN
1150 ? AT(8%,11%)"ЗАПИСЬ ФАЙЛА НА ЛЕНТУ  "
1160 RETURN
1170 ? AT(8%,15%)"Редактирование спрайтов"
1180 RETURN
1190 FOR I%=1% TO 3%
1209 IF I%=K% THEN ?CHR$(&O221);
1210 ON I% GOSUB 1130,1150,1170
1220 IF I%=K% THEN ?CHR$(&O222);
1230 NEXT I%
1240 RETURN
1250 FOR I%=3% TO 22%
1260 ? AT(0%,I%);STRING$(32%,32%);
1270 NEXT I%
1280 RETURN
1290 ? AT(7%,20%)"Для выхода нажать <Ввод>"
1300 RETURN
1310 ? AT(9%,15%)"Включите магнитофон,"
1320 ? AT(7%,16%)"и нажмите любую клавишу"
1330 ? AT(8%,17%)"(кроме клавиши <Ввод>)"
1340 RETURN
1350 FOR N%=1% TO 500%
1360 NEXT N%
1370 RETURN
1380 LINE (40%,220%)-@(7%,7%),C%,B
1390 PAINT (41%,221%),C%,C%
1400 RETURN
1410 FOR I%=TA% TO TA%+1088% STEP 64%
1420 FOR J%=I% TO I%+4% STEP 2%
1430 O$=OCT$(PEEK(J%))
1440 O$=STRING$(6%-LEN(O$),48%)+O$
1450 ?AT((J%-I%)*4%+7%,(I%-TA%)/64%+4%)" "O$" ";
1460 NEXT J%,I%
1470 RETURN
1480 COLOR 1
1490 ?AT(7%,5%)"1 Курсор влево"
1500 ?AT(7%,6%)"> Курсор вправо"
1510 ?AT(7%,7%)"3 Курсор вверх"
1520 ?AT(7%,8%)"- Курсор вниз"
1530 ?AT(7%,10%)"С Выбор текущего цвета"
1540 ?AT(7%,11%)"9 Переход в граф,режим"
1550 ?AT(7%,12%)"8 Переход в цифр,режим"
1560 ?AT(7%,15%)"<Пробел> Фиксация точки"
1570 ?AT(7%,18%)"<Ввод> Выход в главное"
1580 ?AT(16%,19%)"меню"
1590 IF INKEY$="" THEN 1590 ELSE RETURN
1600 DATA &O11500,&O12701,&O50077,&O12702,&O60000,&O12703,&O10,&O12704
1610 DATA &O100,&O5005,&O6000,&O102001,&O5305,&O110512,&O60402,&O110512
1620 DATA &O60402,&O110512,&O60402,&O5005,&O6000,&O102001,&O5303,&O110511
1630 DATA &O60401,&O110511,&O60401,&O110511,&O60401,&O5303,&O1350,&O5337
1640 DATA &O404,&O5237,&O410,&O207
1650 DATA 5443%,4930%,5569%,214%,-27503%,32450%,135%
1660 DATA 4933%,4933%,5568%,8%,4420%,17860%,-4%,3205%
1670 DATA 3205%,3268%,26052%,326%,4868%,5569%,10%,5570%
1680 DATA 0%,4362%,26050%,64%,2753%,763%,26079%,2%
1690 DATA 302%,2752%,745%,135%,0%,21845%,-21846%,-1%
1700 DATA &O12737,&O112021,&O37626,&O4537,&O37606
1710 DATA &O12700,&O431,&O12701,&O650,&O12702
1720 DATA &O24,&O112120,&O112120,&O112120,&O112120,&O5720,&O5302,&O1371
1730 DATA &O12700,&O431,&O61500,&O10003,&O12701,&O650,&O12702,&O24
1740 DATA &O112021,&O112021,&O112021,&O112021,&O5720,&O5302,&O1371
1750 DATA &O10300,&O12701,&O0,&O12702,&O24,&O12703,&O4,&O11104,&O10405
1760 DATA &O6304,&O50504,&O42704,&O125,&O10405,&O6204,&O50504,&O140410
1770 DATA &O111005,&O112104,&O60504,&O110420,&O5303,&O1360,&O62701,&O74
1780 DATA &O5720,&O5302,&O1351
1790 DATA &O12737,&O112120,&O37626,&O4537,&O37606,&O207
1800 DATA &O12700,&O0,&O12701,&O400,&O12702,&O34,&O12703,&O6,&O0
1810 DATA &O5303,&O1375,&O62700,&O72,&O5302,&O1367,&O205
1820 DATA &O11500,&O12704,&O100,&O163704,&O37672,&O12701,&O0,&O12702,&O0
1830 DATA &O12703,&O0,&O112120,&O5303,&O1375,&O60400,&O60401,&O5302,&O1367,&O207
1840 DATA &O12570,&O40206,&O40206,&O35272,&O0,&O57774,&O20006,&O20006,&O57774,&O0
1850 DATA &O52536,&O20406,&O25656,&O20122,&O12,&O52400,&O22102,&O7070,&O52724,&O25252
1860 DATA &O52524,&O35252,&O3011,&O1440,&O77724,&O0,&O24024,&O45256
1870 DATA &O56526,&O45256,&O24024,&O0,&O36532,&O60206,&O60206,&O37772,&O0
1880 DATA &O52574,&O40606,&O40606,&O37372
1890 GOSUB 1250
1900 GOSUB 810
1910 C%=1%
1920 R%=0%
1930 ?AT(0%,3%)"АДРЕС:*1 СЛОВО 2 СЛОВО 3 СЛОВО "
1940 ?AT(0%,22%)"Цвет:"
1950 GOSUB 1380
1960 TA%=&O40000
1970 GOSUB 910
1980 X%=0%
1990 Y%=0%
2000 L%=1
2010 LOCATE X%+7%,Y%+4%,L%
2020 I$=INKEY$
2030 IF I$<>CHR$(8%) THEN 2100
2040 IF X%>0% THEN 2090
2050 IF (TA% MOD 64%)=0% THEN 2820
2060 TA%=TA%-2%
2070 GOSUB 910
2080 GOTO 2820
2090 X%=X%-1%
2100 IF I$<>CHR$(25%) THEN 2180
2110 IF X%<23% THEN 2160
2120 IF (TA% MOD 64%)=58% THEN 2820
2130 TA%=TA%+2%
2140 GOSUB 910
2150 GOTO 2820
2160 X%=X%+1%
2170 GOTO 2820
2180 IF I$<>CHR$(26%) THEN 2250
2190 IF Y%>0% THEN 2240
2200 IF TA%<&O37500 THEN 2820
2210 TA%=TA%-64%
2220 GOSUB 970
2230 GOTO 2820
2240 Y%=Y%-1%
2250 IF I$<>CHR$(27%) THEN 2320
2260 IF Y%<17% THEN 2310
2270 IF TA%>&O43000 THEN 2820
2280 TA%=TA%+64%
2290 GOSUB 970
2300 GOTO 2820
2310 Y%=Y%+1%
2320 IF I$<>CHR$(32%) OR R%=1% THEN 2430
2330 X1%=TA%+Y%*64%+(X%\8%)*2%
2340 X2%=4%^(X% MOD 8%)
2350 X3!=3!+X2%
2360 X2!=(4!-C%)*X2%
2370 IF X3!>32767% THEN X3%=X3!-65536! ELSE X3%=X3!
2380 IF X2!>32767% THEN X2%=X2I-65536! ELSE X2%=X2!
2390 OUT X1%,X3%,0%
2400 OUT X1%,X2%,4%-C%
2410 LOCATE 0%,0%,0%
2420 GOSUB 1030
2430 IF I$<>CHR$(10%) THEN 2600
2440 TT%=0%
2450 GOSUB 910
2480 TT%=-1%
2470 LOCATE 0,0,0
2480 ?AT(0%,23%)"Включить п/п 'СПР' В ОЗУ? (Д/Н)";
2490 I$=INKEY$
2500 IF I$<>CHR$(&O144) AND I$<>CHR$(&O104) THEN 2580
2510 RESTORE 1700
2520 FOR I%=&O37400 TO &O377I2 STEP 2%
2530 READ A%
2540 POKE I%,A%
2550 NEXT I%
2560 ? AT(0%,23%);STRING$(31%,32%);
2570 RETURN
2580 IF I$=CHR$(&O156) OR I$=CHR$(&O116) THEN 2560
2590 GOTO 2490
2690 IF I$<>CHR$(99%) AND I$<>CHR$(67%) THEN 2630
2610 IF C%=4% THEN C%=1% ELSE C%=C%+1%
2620 GOSUB 1380
2630 IF I$<>CHR$(56%) THEN 2660
2640 R%=1%
2650 GOSUB 970
2660 IF I$<>CHR$(57%) THEN 2690
2670 R%=0%
2680 GOSUB 970
2690 IF I$<CHR$(48%) OR I$>CHR$(55%) OR R%=0% THEN 2620
2700 X1%=6%-(X% MOD 8%)
2710 X2%=TA%+Y%*64%+(X%\8%)*2%
2720 IF X1%=6% OR X1%=-1% THEN 2820
2730 IF X1%=5% THEN 2770
2740 OUT X2%,7%+8%^X1%,0%
2750 OUT X2%,VAL(I$)*8%^X1%,1%
2760 GOTO 2800
2770 IF I$>CHR$(49%) THEN 2820
2780 OUT X2%,&O100000,0%
2790 OUT X2%,&O100000,VAL(I$)
2800 ? I$
2810 GOTO 2110
2820 L%=1%-L%
2830 GOSUB 1350
2840 GOTO 2010
2850 FOR I%=&O400 TO &O506 STEP 2%
2860 READ A%
2370 POKE I%,A%
2880 NEXT I%
2890 DEF USR8=&O37646
2900 DEF USR9=&O400
2950 GOSUB 2510
2960 RESTORE 1840
2970 POKE &O37666,24%
2980 POKE &O37672,1%
2990 FOR I%=0% TO 40%
3040 READ A%
3050 A%=USR9(A%)
3060 FOR J%=1% TO 100%
3070 NEXT J%,I%
3080 FOR I%=0% TO 22%
3081 FOR J%=0% TO 41%
3085 POKE &O37662,24616%+I%-J%
3090 A%=USR8(24617%+I%-J%)
3095 POKE &O37662,20503%-I%+J%
3100 A%=USR8(20502%-I%+J%)
3105 NEXT J%,I%
3110 COLOR 2%
3115 ? AT(13%,22%)"=LOD="
3200 IF INKEY$="" THEN 3200
3205 RETURN

Примечание.

Выйти из режимов «Чтение файла с ленты», «Запись файла на ленту» можно только выполнив их, хотя по замыслу автора должен быть выход по клавише <Ввод>. Устранить эту неточность можно поставив в строках 440 и 660 сравнение не с CHR$(10), а с пустыми кавычками "".

А для того, чтобы выйти из этих режимов, если единожды уже давали имя, можно добавить строки 415 и 635, где обнулять переменную A$ (A$="").

 

Performed by © gid, 2012-2022.