Здесь показаны различия между двумя версиями данной страницы.
msx:basic_programming_guide:05 [2020-04-01 14:23] |
msx:basic_programming_guide:05 [2022-09-09 23:26] (текущий) |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
- | [<>] | + | ~~HIDEPAGE:search;sitemap~~ |
- | + | ~~REDIRECT>msx:basic_dialogue_programming_language:005~~ | |
- | ====== Глава V. Графические средства MSX BASIC ====== | + | |
- | + | ||
- | ~~TOC wide~~ | + | |
- | + | ||
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | Лучше один раз увидеть, чем сто раз услышать. | + | |
- | <WRAP rightalign> | + | |
- | —//Пословица// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | До появления цветной машинной графики результаты работы компьютера были трудны для восприятия. Важная информация терялась среди второстепенной. Машинные игры, например, больше напоминали утомительную работу. Одной из ранних машинных игр была игра "Посадка на Луну". Играющие сидели перед черно-белым экраном, созерцая колонки цифр, говоривших об изменении высоты и скорости спускаемого летательного аппарата. Вводя команды, они пытались добиться надёжной, мягкой посадки на Луну. При неудаче на экране появлялись фразы типа: "Столкновение с поверхностью… Корабль разбит… Никого в живых". При успешной игре, наоборот, на экране можно было прочесть: "Высота 0… Успешная посадка!". Компьютерный "Гольф" был, скорее, упражнением в быстром чтении, чем игрой. Длинные пассажи, описывающие направление движения ("Слева от Вас песчаная лунка, а справа дерево. Свободное поле открывается под углом 18 градусов…"), кончались вопросом: "Какую биту Вы выбираете?". После каждого удара возникало новое описание, так что один раунд игры с компьютером занимал почти столько же времени, сколько реальная игра. | + | |
- | + | ||
- | Сегодняшние интерпретаторы языка BASIC содержат операторы цвета и графики, которые можно применять в программе наряду с "обычными" операторами. Эти средства дают не только чисто зрительный, но и практический эффект в традиционных задачах обработки данных и вычислений. В живой и наглядной форме они помогают представить результаты, которые иначе оказались бы весьма трудны для восприятия. | + | |
- | + | ||
- | В разделах V.1—V.8 мы будем говорить о графических средствах ПЭВМ серии [[msx:msx_1]], которые для компьютеров серии [[msx:msx_2]] изменениям не подверглись! | + | |
- | + | ||
- | {{anchor:screen1}} | + | |
- | ===== V.1. Оператор SCREEN в простейшем случае (для компьютера MSX 1) ===== | + | |
- | + | ||
- | На компьютерах серии [[msx:msx_1]] существуют четыре режима работы дисплея: два //текстовых// (символьных) режима и два //графических//, служащих для индикации соответственно текстовой (символьной) и графической информации. В обоих графических режимах экран рассматривается как сетка из графических элементов — //точек// (пикселей, от англ. "picture element" — "элемент изображения"). Графическое изображение получается на дисплее путём высвечивания точек различным цветом. | + | |
- | + | ||
- | Переключение с одного режима работы на другой (или, как говорят, "с одного экрана на другой") осуществляется оператором | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | SCREEN n | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''SCREEN''("screen" — "экран") — служебное слово; | + | |
- | * n — арифметическое выражение, целая часть значения которого должна принадлежать отрезку [0,3]; этот параметр указывает режим работы дисплея: | + | |
- | * n=0: символьный экран, одноцветный, имеющий максимум 24 строки и 40 столбцов (по умолчанию число столбцов— 39); | + | |
- | * n=1: символьный экран, многоцветный, имеющий максимум 24 строки и 32 столбца (по умолчанию число столбцов 29); | + | |
- | * n=2: графический экран высокого разрешения, имеющий 256 точек в строке и 192 — в столбце; | + | |
- | * n=3: графический экран низкого разрешения, имеющий 64 укрупнённые "точки" в строке и 48 — в столбце. | + | |
- | При включении питания компьютер автоматически устанавливается в режим ''SCREEN 0''. Этот режим обычно используется для ввода программ или для работы с программами редактирования текстов. | + | |
- | + | ||
- | Ясно, что в режиме высокого разрешения экран разбивается на большее число точек, чем в режиме низкого разрешения. Вследствие этого, в первом случае точки оказываются гораздо меньшего размера, благодаря чему изображение может содержать существенно большее число деталей. | + | |
- | + | ||
- | Отметим, что //только// в символьных режимах допустимо применение операторов ввода–вывода ''INPUT'' и ''PRINT'', т.к. оператор ''PRINT'' в графических режимах игнорируется, а использование оператора ''INPUT'' в графических режимах ''SCREEN 2'' или ''SCREEN 3'' переводит компьютер в режим ''SCREEN 0'', после чего вновь необходима установка режима ''SCREEN 2'' или ''SCREEN 3'' соответственно. | + | |
- | + | ||
- | Любая пара целых чисел (X,Y) в диапазоне 0≤X≤255, 0≤Y≤191, задаёт на графических экранах ''SCREEN 2'' и ''SCREEN 3'' точку, однако учтите, что в режиме ''SCREEN 3'' блок размером 4×4 точек создаёт изображение одной "точки", поэтому фактические размеры экрана ''SCREEN 3'' — 64×48 укрупнённых "точек"(см. [[#pict_05_01|рис. 1]]). | + | |
- | + | ||
- | Для сравнения, стандартный телевизионный монитор (телевизор) имеет разрешающую способность экрана 512×256 точек, а профессиональная микро–ЭВМ фирмы Tektronix (модель 4054) имеет экран с разрешающей способностью 4096×3125 точек. | + | |
- | + | ||
- | {{anchor:pict_05_01}} <code> | + | |
- | 0 255 0 63 | + | |
- | 0┌───────────────────┐──▶X 0┌───────────────────┐──▶X | + | |
- | │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ | + | |
- | │▨▨▨▨▨ SCREEN2 ▨▨▨▨▨│ │▨▨▨▨▨ SCREEN3 ▨▨▨▨▨│ | + | |
- | │▨▨ 256×192 точек ▨▨│ │▨▨▨▨ 64×48 точек ▨▨│ | + | |
- | │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ | + | |
- | 191│─ ─ ─ ─ ─ ─ ─ ─ ─ ─┘ 47│─ ─ ─ ─ ─ ─ ─ ─ ─ ─┘ | + | |
- | ▼ Y ▼ Y | + | |
- | </code> __//Рис. 1//__ | + | |
- | + | ||
- | Отметим, что система координат, изображённая на [[#pict_05_01|рис. 1]], используется также в таких микро–ЭВМ, как Apple, TRS–80, IBM, Atari. | + | |
- | + | ||
- | В любой момент времени одна из точек (α,β) экрана находится в особом состоянии или, как говорят, отмечена //графическим курсором//. Числа α и β в этом случае называют //текущими координатами// графического курсора. При включении компьютера графический курсор устанавливается в начальное положение (0,0) — верхний левый угол экрана. | + | |
- | + | ||
- | Заметим, что текущие координаты X и Y графического курсора можно определить в режиме ''SCREEN 0'' или ''SCREEN 1'' при помощи команды (оператора) | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | PRINT PEEK(&HFCB3);PEEK(&HFCB5) | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | . | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | + | ||
- | //Примечания//: | + | |
- | - При включении питания компьютера, неявно выполняется оператор ''SCREEN 0''. | + | |
- | - При вводе оператора ''SCREEN n'' (n=0,1,2,3) всегда очищается экран. | + | |
- | - В прямом режиме Вы находитесь в ''SCREEN 0'' или ''SCREEN 1''. Возвращаясь в прямой режим, Вы снова перейдёте в экран ''SCREEN 0'' или в ''SCREEN 1'', в зависимости от последнего выполненного оператора. Соответственно, ввод команды ''SCREEN 2'' в прямом режиме очищает экран перед возвратом в режимы ''SCREEN 0'' или ''SCREEN 1''. | + | |
- | + | ||
- | ===== V.2. Оператор WIDTH. Операторы KEY OFF и KEY ON ===== | + | |
- | {{anchor:width}} | + | |
- | Оператор ''WIDTH'' используется для установки ширины экрана дисплея в символьных режимах ''SCREEN 0'' и ''SCREEN 1'' (каждому режиму может соответствовать своя ширина экрана). | + | |
- | Синтаксис оператора: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | WIDTH α | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''WIDTH''("width" — "ширина") — служебное слово; | + | |
- | * α — арифметическое выражение, целая часть значения которого должна принадлежать отрезку [1,40] для режима ''SCREEN 0'' или отрезку [1,32] для режима ''SCREEN 1''. | + | |
- | После выполнения оператора ''WIDTH α'' средняя часть экрана шириной ''INT(α)'' становится доступной для ввода или вывода информации. | + | |
- | + | ||
- | {{anchor:e052-01}} __//Пример//__: | + | |
- | \\ {{.examples:052-01.bas|}} \\ [[+tab|wmsxbpge>052-01.bas]] | + | |
- | <code> | + | |
- | Ok | + | |
- | 10 WIDTH 1:?"Проверка":FOR I=1 TO 180:NEXT | + | |
- | 20 WIDTH 40:?:?:?:?:?TAB(15);"Проверка" | + | |
- | 30 FOR I=1 TO 180:NEXT:GOTO 10 | + | |
- | </code> | + | |
- | + | ||
- | Отметим, что оператор ''WIDTH'' является и командой непосредственного режима. Например, для возвращения к "обычной" ширине экрана используйте команду ''WIDTH 39'' или команду ''WIDTH 29''. | + | |
- | + | ||
- | Отметим, что оператор ''WIDTH 80'', разрешённый только для компьютера серии [[msx:msx_2]], позволяет производить отображение 80 символов в одной экранной строке. Ширина символов при этом уменьшается наполовину. (Напомним, что аргумент оператора ''WIDTH'' должен лежать в диапазоне от 1 до 80 для компьютеров серии [[msx:msx_2]]). | + | |
- | + | ||
- | {{anchor:keyoff}} | + | |
- | В результате выполнения оператора | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | KEY OFF | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где ''KEY OFF'' ("key" — "клавиша") — служебное слово, из 24–й строки символьных экранов ''SCREEN 0'' и ''SCREEN 1'' убирается индикация значений функциональных клавиш <key>F1</key>—<key>F10</key>. Тем самым эта строка становится доступной для ввода информации (размер экрана увеличивается на одну строку). | + | |
- | + | ||
- | {{anchor:e052-02}} __//Пример//__: | + | |
- | \\ {{.examples:052-02.bas|}} \\ [[+tab|wmsxbpge>052-02.bas]] | + | |
- | <code> | + | |
- | 10 KEY OFF:LOCATE 5,23 | + | |
- | 20 PRINT "Проверка KEY OFF" | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:keyon}} | + | |
- | Оператор | + | |
- | <code> | + | |
- | KEY ON | + | |
- | </code> | + | |
- | отменяет действие оператора ''KEY OFF'' и отводит 24–ю строку экрана для индикации значений функциональных клавиш <key>F1</key>—<key>F10</key>. | + | |
- | + | ||
- | В этой строке удобно показывать вспомогательную информацию, т.к. она в отличие от других не участвует в вертикальном сдвиге содержимого экрана! | + | |
- | + | ||
- | ===== V.3. Управление текстовым курсором ===== | + | |
- | + | ||
- | В данном разделе речь пойдёт об операторе LOCATE установки текстового курсора "█" (не графического!) и функциях ''POS(α)'', ''LPOS(α)'', ''CSRLIN'' управления текстовым курсором. | + | |
- | + | ||
- | ==== V.3.1. Оператор LOCATE. Функция CSRLIN. Функции POS(α) и LPOS(α) ==== | + | |
- | + | ||
- | {{anchor:locate}} | + | |
- | Синтаксис оператора ''LOCATE'': | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | LOCATE [X][,Y][,α] | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''LOCATE''("to locate" — "устанавливать") — служебное слово; | + | |
- | * X — арифметическое выражение, целая часть значения которого задаёт номер экранного столбца, в котором находится курсор (столбцы нумеруются слева направо, начиная с нуля); | + | |
- | * Y — арифметическое выражение, целая часть значения которого задаёт номер экранной строки, в которой находится курсор (строки нумеруются сверху вниз, начиная с нуля); | + | |
- | * α — арифметическое выражение; если значение α равно 0, то курсор не отображается на экране (сливается с фоном), в противном случае курсор отображается на экране (по умолчанию α=0). Значение α хранится в области системных переменных в ячейке с номером ''&HFCA9'' (примените команду ''PRINT PEEK(&HFCA9)''). Целая часть значения α должна принадлежать отрезку [0,255], в противном случае на экране дисплея появится сообщение об ошибке: <WRAP centeralign>"Illegal function call"\\ (//"Неправильный вызов функции"//).</WRAP> | + | |
- | + | ||
- | Любой параметр оператора ''LOCATE'' может быть опущен, но запятые(запятая!), определяющие его позицию, обязательно должны присутствовать. Если X, или Y, или α опущены, то сохраняются их предыдущие значения. Примеры записи оператора: | + | |
- | * <code>LOCATE 25,10,1 | + | |
- | LOCATE 15,,1 | + | |
- | LOCATE 9 | + | |
- | LOCATE ,,1 | + | |
- | LOCATE ,4,1 | + | |
- | LOCATE ,8 | + | |
- | </code> | + | |
- | * <WRAP> | + | |
- | <code> | + | |
- | LOCATE 17,1 | + | |
- | </code> | + | |
- | но не | + | |
- | <code> | + | |
- | LOCATE 17,1, | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | Оператор ''LOCATE'' перемещает курсор из текущей позиции в позицию (X,Y). Учтите, что данный оператор позволяет управлять курсором //только// в символьных экранах ''SCREEN 0'' и ''SCREEN 1''! | + | |
- | + | ||
- | __//Примеры//__: | + | |
- | * {{anchor:e0531-01}} 1) \\ {{.examples:0531-01.bas|}} \\ [[+tab|wmsxbpge>0531-01.bas]]<code> | + | |
- | 10 LOCATE 15,15,0 | + | |
- | 20 FOR I=1 TO 300:NEXT | + | |
- | </code> | + | |
- | * {{anchor:e0531-02}} 2) \\ {{.examples:0531-02.bas|}} \\ [[+tab|wmsxbpge>0531-02.bas]]<code> | + | |
- | 10 LOCATE 15,15,1 | + | |
- | 20 FOR I=1 TO 300:NEXT | + | |
- | </code> | + | |
- | Если используются строка или столбец с номерами, большими, чем максимально отображаемые, но меньшими 255, то ошибки не произойдёт, но курсор переместится на максимально возможную позицию экрана дисплея в этом направлении. | + | |
- | * {{anchor:e0531-03}} 3) \\ {{.examples:0531-03.bas|}} \\ [[+tab|wmsxbpge>0531-03.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 CLS:LOCATE 5,3 | + | |
- | 20 LINEINPUT A$ | + | |
- | run | + | |
- | ······ | + | |
- | ······ | + | |
- | ······ 4 строка | + | |
- | ·····█ ◀── 6 столбец | + | |
- | Компьютер ждёт ввода символа! | + | |
- | </code> | + | |
- | * {{anchor:e0531-04}} 4) \\ {{.examples:0531-04.bas|}} \\ [[+tab|wmsxbpge>0531-04.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 3 CLS'Вначале очистим экран! | + | |
- | 5 LOCATE 255,1,1 | + | |
- | 7 FOR I=1 TO 400:NEXT | + | |
- | 10 LOCATE ,255,1 | + | |
- | 20 FOR I=1 TO 400:NEXT | + | |
- | 30 LOCATE 1,,1 | + | |
- | 40 FOR I=1 TO 400:NEXT | + | |
- | 50 LOCATE ,1,1 | + | |
- | 60 FOR I=1 TO 400:NEXT:GOTO 3 | + | |
- | </code> | + | |
- | + | ||
- | С помощью оператора ''LOCATE'' можно выводить информацию на текстовый экран, начиная с нужного места. | + | |
- | * {{anchor:e0531-05}} 5) \\ {{.examples:0531-05.bas|}} \\ [[+tab|wmsxbpge>0531-05.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 CLS:LOCATE 3,2 | + | |
- | 20 PRINT"Смотри: ";CHR$(255) | + | |
- | run | + | |
- | ···· | + | |
- | ···· | + | |
- | ···Смотри: █ | + | |
- | Ok | + | |
- | </code> | + | |
- | * {{anchor:e0531-06}} 6) \\ {{.examples:0531-06.bas|}} \\ [[+tab|wmsxbpge>0531-06.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 LOCATE 14,15 | + | |
- | 20 ?PEEK(&HF3DD);PEEK(&HF3DC) | + | |
- | </code> | + | |
- | * {{anchor:e0531-07}} 7) \\ {{.examples:0531-07.bas|}} \\ [[+tab|wmsxbpge>0531-07.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 CLS:LOCATE 1,1 | + | |
- | 20 ?CHR$(255);"Я здесь!" | + | |
- | 30 LOCATE 2,2,0:FOR I=1 TO 1000:NEXT | + | |
- | 40 ? CHR$(255);"А теперь здесь!" | + | |
- | run | + | |
- | ··· | + | |
- | ·█Я здесь! | + | |
- | ··█А теперь здесь! | + | |
- | Ok | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:csrlin}} | + | |
- | Функция | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | CSRLIN | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где ''CSRLIN'' ("Cursor ScReen LINe" — "строка курсора") — служебное слово, возвращает в символьных экранах ''SCREEN 0'' и ''SCREEN 1'' номер экранной строки, в которой находится курсор. | + | |
- | + | ||
- | Учтите, что "верхняя" строка имеет номер нуль, "нижняя" имеет номер или 22 или 23 (в зависимости от того, используется ли эта строка для индикации значений функциональных клавиш). | + | |
- | + | ||
- | {{anchor:e0531-08}} __//Пример//__: табулирование функции y=x² на отрезке [A,B] с шагом H с предотвращением непрерывного вертикального движения (скроллинга) результатов табулирования по экрану (информация движется постранично, "высота" страницы — 22 строки). Напомним: //скроллинг// — рулонный режим перемещения строк снизу вверх или сверху вниз. | + | |
- | \\ {{.examples:0531-08.bas|}} \\ [[+tab|wmsxbpge>0531-08.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 CLS:INPUT A,B,H:FOR X=A TO B STEP H' Оператор CLS важен! | + | |
- | 20 IF CSRLIN=22 THEN ? X,X^2:FOR I=1 TO 1000:NEXT:LOCATE 0,1 ELSE ?X,X^2 | + | |
- | 30 NEXTX:FORI=(22-CSRLIN)*POS(0)TO(23-CSRLIN)*39:?CHR$(32);:NEXT:A$=INPUT$(1) | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:pos}} | + | |
- | Функция | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | POS(α) | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''POS''("POSition" — "позиция") — служебное слово; | + | |
- | * α — числовая константа (при выполнении функции не используется, но обязательно должна быть указана при обращении); возвращает в символьных экранах ''SCREEN 0'' и ''SCREEN 1'' номер экранного столбца, в котором находится курсор. | + | |
- | + | ||
- | Например: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | 10 LOCATE 14,15:PRINT POS(0);CSRLIN | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | . | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | + | ||
- | {{anchor:lpos}} | + | |
- | Функция ''LPOS(α)'' ("Line Printer Position") указывает позицию печатающей головки MSX–принтера в строке. | + | |
- | + | ||
- | Функция ''LPOS(α)'' применяется для печати данных "в столбик" на принтере. | + | |
- | + | ||
- | Например: | + | |
- | <code> | + | |
- | 25 IF LPOS(0)>10 THEN LPRINT X ELSE LPRINT TAB(10):LPRINT X | + | |
- | </code> | + | |
- | + | ||
- | ===== V.4. Базовые графические операторы MSX BASIC ===== | + | |
- | + | ||
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | Я думаю, что чертежи очень полезное средство | + | |
- | против неопределённости слов. | + | |
- | <WRAP rightalign> | + | |
- | —//Г.В.Лейбниц// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | ==== V.4.1. Оператор COLOR для компьютера MSX 1 ==== | + | |
- | + | ||
- | {{anchor:color1}} | + | |
- | На экране дисплея можно выделить три отдельные области: передний план, фон и бордюр. //Передний план// (изображение) — область, где располагаются цифровые и текстовые данные и графические изображения, которые накладываются на фон. | + | |
- | + | ||
- | //Фон//, как это следует из самого названия, — область экрана, на которой воспроизводится все, что выводится на экран; фон можно видеть сразу же после включения компьютера. | + | |
- | + | ||
- | //Бордюр// (или цветовая //рамка//) занимает на экране область, непосредственно прилегающую к его физическому контуру за пределами основного прямоугольного поля, используемого для вывода информации. Ясно, что бордюр окружает фон, но, например, в режиме ''SCREEN 0'' он того же цвета, что и сам фон, и поэтому не различим. Благодаря наличию бордюра сглаживаются различия между экранами //разнотипных// дисплеев. | + | |
- | + | ||
- | Оператор ''COLOR'' позволяет задавать различные цвета фона, бордюра и изображения, выводимого на передний план. | + | |
- | + | ||
- | Его синтаксис: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | COLOR [I],[F][,B] | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''COLOR''("color" — "цвет") — служебное слово; | + | |
- | * I — арифметическое выражение, целая часть значения которого задаёт код цвета изображения (по умолчанию I=15); | + | |
- | * F — арифметическое выражение, целая часть значения которого задаёт код цвета фона (по умолчанию F=4); | + | |
- | * B — арифметическое выражение, целая часть значения которого задаёт код цвета бордюра (по умолчанию B=4). | + | |
- | * Целые части значений I, F, B должны принадлежать [0,15]. | + | |
- | + | ||
- | Приведём коды 15 возможных цветов для многоцветных дисплеев. Для монохроматических (от греч."μоvoσ" — "один") дисплеев эти коды задают различные оттенки чёрного и зелёного цветов. | + | |
- | | 0 |@#000000:<fc #b3b3b3>Прозрачный</fc>| | + | |
- | | 1 |@#000000:<fc #ffffff>Чёрный</fc>| | + | |
- | | 2 |@#24db24:<fc #000000>Зелёный</fc>| | + | |
- | | 3 |@#6dff6d:<fc #000000>Светло–зелёный</fc>| | + | |
- | | 4 |@#2424ff:<fc #ffffff>Cиний</fc>| | + | |
- | | 5 |@#496dff:<fc #ffffff>Светло–синий</fc>| | + | |
- | | 6 |@#b62424:<fc #ffffff>Тёмно–красный</fc>| | + | |
- | | 7 |@#49dbff:<fc #000000>Голубой</fc>| | + | |
- | | 8 |@#ff2424:<fc #ffffff>Красный</fc>| | + | |
- | | 9 |@#ff6d6d:<fc #000000>Светло–красный</fc>| | + | |
- | | 10 |@#dbdb24:<fc #000000>Жёлтый</fc>| | + | |
- | | 11 |@#dbdb92:<fc #000000>Светло–жёлтый</fc>| | + | |
- | | 12 |@#249224:<fc #ffffff>Тёмно–зелёный</fc>| | + | |
- | | 13 |@#db49b6:<fc #ffffff>Лиловый</fc>| | + | |
- | | 14 |@#b6b6b6:<fc #000000>Серый</fc>| | + | |
- | | 15 |Белый| | + | |
- | + | ||
- | Отметим, что объект прозрачного цвета всегда приобретает цвет бордюра, а бордюр "нулевого" цвета — чёрный (поэтому возможных цветов не 16, а 15)! | + | |
- | + | ||
- | Полное отсутствие параметров в операторе ''COLOR'' приводит к появлению на экране дисплея сообщения об ошибке: <WRAP centeralign>"Missing operand" \\ (//"Пропуск операнда"//),</WRAP> а слишком большое значение хотя бы одного из параметров — к сообщению: <WRAP centeralign>"Illegal function call".</WRAP> | + | |
- | + | ||
- | Заметим, что параметры I, F, B можно не указывать, но если они не последние в записи, то ограничивающие их запятые обязательны. Любой опущенный параметр (обозначенный только запятой перед ним) сохраняет старое значение. | + | |
- | Каждый назначенный параметр "действует" до тех пор, пока не получит другое значение в последующем операторе ''COLOR''. Таким образом, Вы можете написать подпрограмму для рисования некоторого объекта, а его цвет определить в основной программе перед обращением к подпрограмме. | + | |
- | Приведём примеры записи оператора: | + | |
- | <code> | + | |
- | COLOR 15,4,4 | + | |
- | COLOR ,,4 | + | |
- | COLOR 1,15 | + | |
- | COLOR ,1 | + | |
- | COLOR 15,,1 | + | |
- | COLOR 15 | + | |
- | COLOR ,4,1 | + | |
- | </code> | + | |
- | Укажем удобные для работы сочетания оттенков изображения, фона и бордюра для монохроматического зелёного дисплея: | + | |
- | - <WRAP> для текстового экрана ''SCREEN 0'': | + | |
- | * ''COLOR 15,4'' (тёмный фон); | + | |
- | * ''COLOR 1,15'' (светлый фон); | + | |
- | </WRAP> | + | |
- | - <WRAP> для экранов ''SCREEN 1'', ''SCREEN 2'' и ''SCREEN 3'': | + | |
- | * ''COLOR 15,4,2'' (тёмный фон); | + | |
- | * ''COLOR 1,15,8'' (светлый фон); | + | |
- | * ''COLOR 1,15,2'' (светлый фон) . | + | |
- | </WRAP> | + | |
- | + | ||
- | //Внимание!// Если Вы случайно установите один и тот же код цвета и для изображения, и для фона, то экран окажется "чистым". В этом случае "вслепую" в непосредственном режиме наберите, например, команду ''COLOR 1,15'' или | + | |
- | ''COLOR 15,4'' и нажмите клавишу <key>'Ввод '⏎</key>. На экране появится информация, которая ранее была "невидима"! | + | |
- | + | ||
- | {{anchor:e0541-01}} __//Пример//__. Программа, позволяющая подобрать удобные сочетания цветов изображения, фона и бордюра. | + | |
- | \\ {{.examples:0541-01.bas|}} \\ [[+tab|wmsxbpge>0541-01.bas]] | + | |
- | <code> | + | |
- | Ok | + | |
- | 10 SCREEN 1:FOR I=1 TO 15:FOR F=1 TO 15:FOR B=1 TO 15 | + | |
- | 20 COLOR I,F,B:LOCATE 9,10:PRINT I;F;B | + | |
- | 30 FOR K=1 TO 1000:NEXT:NEXT:NEXT:NEXT | + | |
- | </code> | + | |
- | В любой момент времени Вы можете, нажав на клавишу <key>STOP</key> Вашего компьютера, приостановить работу программы и выписать понравившуюся Вам комбинацию значений I, F, B, которая выводится на экран дисплея. | + | |
- | + | ||
- | //Замечание//. Если Вы прервали программу,используя клавиши <key>CTRL+STOP</key>, то можете тут же возвратить начальные значения цветов нажатием клавиш <key>SHIFT+F1</key> (только для компьютеров серии [[msx:msx_2]])! | + | |
- | + | ||
- | При формировании конкретных изображений необходимо осторожно подходить к выбору цветов. Их случайный выбор может вызвать неприятные ощущения вплоть до раздражения. | + | |
- | + | ||
- | Учтите, что | + | |
- | * //белый// цвет располагает к чистоте, создаёт ощущение лёгкости, прохлады; | + | |
- | * //жёлтый// — возбуждает радость, создаёт ощущение тепла, простора, лёгкости, ускоряет пульсацию крови, расширение зрачков; | + | |
- | * //красный// — создаёт впечатление теплоты, возбуждает, ускоряет пульсацию крови, вызывает расширение зрачков, однако при длительном действии приводит к чрезмерной усталости; | + | |
- | * //пурпурный// — возбуждает, вызывает возвышенное чувство, ощущение тепла; | + | |
- | * //зелёный// — вызывает ощущение холода, успокаивает, налаживает кровообращение, улучшает мускульную деятельность; | + | |
- | * //голубой// — вызывает ощущение прохлады, отдалённости, успокаивает; | + | |
- | * //чёрный// — вызывает ощущение тяжести, тесноты, громоздкости, снижает настроение, угнетает; | + | |
- | * //серый// — холодный, вызывает скуку, апатию. | + | |
- | + | ||
- | Обычно рекомендуется уменьшать число используемых цветов. Можно получить хороший эффект, если для фона выбрать цвет, являющийся "дополнительным" к одному из используемых цветов. В перечень взаимодополняющих цветов входят: красный и голубой, жёлтый и синий, зелёный и красный (пурпурный). Если же парные дополнительные цвета расположить рядом, то в зрительном восприятии яркость каждого цвета усиливается. Это явление называется //цветовым контрастом//. | + | |
- | + | ||
- | Если в изображении используется большое число цветов,то для фона лучше выбрать серый или нейтральный тон, причём чёрные контуры вокруг областей разного цвета улучшают восприятие изображения [[bibliography#b14|[14]]]. | + | |
- | + | ||
- | Отметим различия в выполнении оператора ''COLOR'' в режимах ''SCREEN 1'' и ''SCREEN 2'': | + | |
- | * во время выполнения оператора ''COLOR'' в режиме ''SCREEN 2'' изменяется только цвет бордюра, а не цвет изображения или фона; | + | |
- | * цвет фона изменится только в том случае, если после выполнения оператора ''COLOR'' будет выполнен оператор ''CLS'' (см. ниже [[#V.4.3. Оператор CLS|раздел 4.3.]]); | + | |
- | + | ||
- | Для проверки вышесказанного сравните следующие программы: | + | |
- | * {{anchor:e0541-02}} {{.examples:0541-02.bas|}} \\ [[+tab|wmsxbpge>0541-02.bas]]<code> | + | |
- | 10 SCREEN 2:COLOR 1,15,6 | + | |
- | 20 GOTO 20 'изменяется только цвет бордюра! | + | |
- | </code> | + | |
- | * {{anchor:e0541-03}} {{.examples:0541-03.bas|}} \\ [[+tab|wmsxbpge>0541-03.bas]]<code> | + | |
- | 10 SCREEN 2:COLOR 1,15,6:CLS | + | |
- | 20 GOTO 20 'изменяется цвет фона и бордюра! | + | |
- | </code> | + | |
- | * {{anchor:e0541-04}} {{.examples:0541-04.bas|}} \\ [[+tab|wmsxbpge>0541-04.bas]]<code> | + | |
- | 10 COLOR 1,15,6:SCREEN 2 | + | |
- | 20 GOTO 20 'изменяется цвет фона и бордюра! | + | |
- | </code> | + | |
- | Оператор ''SCREEN'' выполняет операцию, аналогичную ''CLS''! | + | |
- | + | ||
- | В заключение этого раздела заметим, что коды текущего цвета изображения, фона и бордюра соответственно можно получить, выполнив в непосредственном режиме команду: | + | |
- | <code> | + | |
- | PRINT PEEK(&HF3E9);PEEK(&HF3EA);PEEK(&HF3EB) | + | |
- | </code> | + | |
- | + | ||
- | ==== V.4.2. Оператор COLOR для компьютера MSX 2 ==== | + | |
- | + | ||
- | {{anchor:color2}} | + | |
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | //Палитра// (от франц."palette" — "пластинка"), четырёхугольная или овальная деревянная дощечка, металлическая или фарфоровая пластинка для смешивания красок; подбор цветов, которыми пользуется художник. | + | |
- | <WRAP rightalign> | + | |
- | —//Советский Энциклопедический Словарь// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | {{anchor:colorsinrgb}} | + | |
- | Известно, что цвета, (пронумерованные в [[msx:basic:]] от 0 до 15), содержат //красный// ("Red"), //зелёный// ("Green") и //синий// ("Blue") цвет в определённых пропорциях. | + | |
- | + | ||
- | В приведённой ниже таблице Вы сможете почерпнуть сведения о пропорциях RGB в изначально установленных цветах экрана дисплея: | + | |
- | ^ Номер ^ Цвет ^ R ^ G ^ B ^ | + | |
- | | 0 |@#000000:<fc #b3b3b3>Прозрачный</fc>| 0 | 0 | 0 | | + | |
- | | 1 |@#000000:<fc #ffffff>Чёрный</fc>| 0 | 0 | 0 | | + | |
- | | 2 |@#24db24:<fc #000000>Зелёный</fc>| 1 | 6 | 1 | | + | |
- | | 3 |@#6dff6d:<fc #000000>Светло–зелёный</fc>| 3 | 7 | 3 | | + | |
- | | 4 |@#2424ff:<fc #ffffff>Cиний</fc>| 1 | 1 | 7 | | + | |
- | | 5 |@#496dff:<fc #ffffff>Светло–синий</fc>| 2 | 3 | 7 | | + | |
- | | 6 |@#b62424:<fc #ffffff>Тёмно–красный</fc>| 5 | 1 | 1 | | + | |
- | | 7 |@#49dbff:<fc #000000>Голубой</fc>| 2 | 6 | 7 | | + | |
- | | 8 |@#ff2424:<fc #ffffff>Красный</fc>| 7 | 1 | 1 | | + | |
- | | 9 |@#ff6d6d:<fc #000000>Светло–красный</fc>| 7 | 3 | 3 | | + | |
- | | 10 |@#dbdb24:<fc #000000>Жёлтый</fc>| 6 | 6 | 1 | | + | |
- | | 11 |@#dbdb92:<fc #000000>Светло–жёлтый</fc>| 6 | 6 | 4 | | + | |
- | | 12 |@#249224:<fc #ffffff>Тёмно–зелёный</fc>| 1 | 4 | 1 | | + | |
- | | 13 |@#db49b6:<fc #ffffff>Лиловый</fc>| 6 | 2 | 5 | | + | |
- | | 14 |@#b6b6b6:<fc #000000>Серый</fc>| 5 | 5 | 5 | | + | |
- | | 15 |Белый| 7 | 7 | 7 | | + | |
- | + | ||
- | {{anchor:colorspalette}} | + | |
- | Программа для иллюстрации таблицы [[bibliography#b91|[91] ]]. | + | |
- | * {{.examples:colors_r.bas|}}, [[+tab|wmsxbpge>colors_r.bas|запуск в WebMSX]] | + | |
- | * <WRAP> <hidden Текст программы colors_r.bas> | + | |
- | <code> | + | |
- | 10 REM Цвета | + | |
- | 20 REM | + | |
- | 30 REM MSX Computer Magazine | + | |
- | 40 REM | + | |
- | 50 REM Только для MSX 2! | + | |
- | 60 REM | + | |
- | 70 GOSUB 660:' Инициализация | + | |
- | 80 ' **************** | + | |
- | 90 ' * Рисование экрана * | + | |
- | 100 ' **************** | + | |
- | 110 FOR X=1 TO 5 | + | |
- | 120 FOR Y=1 TO 3 | + | |
- | 130 LINE ((X-1)*100,(Y-1)*50)-(X*100,Y*50),X+(Y-1)*5,BF | + | |
- | 140 PRESET ((X-1)*100+8,(Y-1)*50+5) | + | |
- | 150 PRINT #1, " Цвет: "X+(Y-1)*5 | + | |
- | 160 PRESET ((X-1)*100+16,(Y-1)*50+15) | + | |
- | 170 PRINT #1, "R G B" | + | |
- | 180 PRESET ((X-1)*100+8,(Y-1)*50+25) | + | |
- | 190 PRINT #1, KW(X+(Y-1)*5,1);KW(X+(Y-1)*5,2);KW(X+(Y-1)*5,3) | + | |
- | 200 NEXT Y | + | |
- | 210 NEXT X | + | |
- | 220 X=1: Y=1 | + | |
- | 230 ' ************** | + | |
- | 240 ' * Выбор цвета * | + | |
- | 250 ' ************** | + | |
- | 260 PRESET (0,160): PRINT #1, SPACE$(70) | + | |
- | 270 PRESET (0,170): PRINT #1, SPACE$(50) | + | |
- | 280 PRESET (0,160) | + | |
- | 290 PRINT #1, "Выбирайте цвет на палитре с помощью стрелок" | + | |
- | 300 PRESET (0,170) | + | |
- | 310 PRINT #1, "<Пробел> для перехода в режим изменения RGB" | + | |
- | 320 PUT SPRITE 1,((X-1)*50+24,(Y-1)*50+35) | + | |
- | 330 A$=INPUT$(1) | + | |
- | 340 IF A$=CHR$(28) AND X<5 THEN X=X+1 | + | |
- | 350 IF A$=CHR$(29) AND X>1 THEN X=X-1 | + | |
- | 360 IF A$=CHR$(30) AND Y>1 THEN Y=Y-1 | + | |
- | 370 IF A$=CHR$(31) AND Y<3 THEN Y=Y+1 | + | |
- | 380 IF A$=CHR$(32) THEN KL=X+(Y-1)*5: GOTO 430 | + | |
- | 390 GOTO 320 | + | |
- | 400 ' ********************** | + | |
- | 410 ' * Выбор значений RGB * | + | |
- | 420 ' ********************** | + | |
- | 430 PRESET (0,160):PRINT #1, SPACE$(50) | + | |
- | 440 PRESET (0,170):PRINT #1, SPACE$(50) | + | |
- | 450 PRESET (0,160) | + | |
- | 460 PRINT #1, "Выбор R, G или B : влево/вправо, изменение значения : вверх/вниз" | + | |
- | 470 PRESET (0,170) | + | |
- | 480 PRINT #1, "<Пробел> для выбора цвета на палитре" | + | |
- | 490 KW=1 | + | |
- | 500 PUT SPRITE 1,((X-1)*50-16+KW*12,(Y-1)*50+16) | + | |
- | 510 A$=INPUT$(1) | + | |
- | 520 IF A$=CHR$(28) AND KW<3 THEN KW=KW+1 | + | |
- | 530 IF A$=CHR$(29) AND KW>1 THEN KW=KW-1 | + | |
- | 540 IF A$=CHR$(30) AND KW(KL,KW)<7 THEN KW(KL,KW)=KW(KL,KW)+1 | + | |
- | 550 IF A$=CHR$(31) AND KW(KL,KW)>0 THEN KW(KL,KW)=KW(KL,KW)-1 | + | |
- | 560 IF A$=CHR$(32) THEN 260 | + | |
- | 570 COLOR=(KL,KW(KL,1),KW(KL,2),KW(KL,3)) | + | |
- | 580 PRESET ((X-1)*100+24*KW-16,(Y-1)*50+25) | + | |
- | 590 PRINT #1, " " | + | |
- | 600 PRESET ((X-1)*100+24*KW-16,(Y-1)*50+25) | + | |
- | 610 PRINT#1,KW(KL,KW) | + | |
- | 620 GOTO 500 | + | |
- | 630 '***************** | + | |
- | 640 '* Инициализация * | + | |
- | 650 '***************** | + | |
- | 660 SCREEN 7 | + | |
- | 670 DEFINT K | + | |
- | 680 OPEN "GRP:" FOR OUTPUT AS #1 | + | |
- | 690 DIM KW(15,3) | + | |
- | 700 RESTORE 770 | + | |
- | 710 FOR N1=1 TO 15 | + | |
- | 720 FOR N2=1 TO 3 | + | |
- | 730 READ KW(N1,N2) | + | |
- | 740 NEXT N2 | + | |
- | 750 NEXT N1 | + | |
- | 760 ' RGB данные стандартных цветов | + | |
- | 770 DATA 0,0,0,1,6,1,3,7,3,1,1,7,2,3,7,5,1,1,2,6,7,7,1,1,7,3,3,6,6,1,6,6,4,1,4,1,6,2,5,5,5,5,7,7,7 | + | |
- | 780 ' Определение спрайта | + | |
- | 790 RESTORE 920 | + | |
- | 800 FOR N=1 TO 8 | + | |
- | 810 READ A$ | + | |
- | 820 B$=B$+CHR$(VAL("&B"+A$)) | + | |
- | 830 NEXT N | + | |
- | 840 SPRITE$(1)=B$ | + | |
- | 850 B$="" | + | |
- | 860 FOR N=2 TO 9 | + | |
- | 870 B$=B$+CHR$(N) | + | |
- | 880 NEXT N | + | |
- | 890 COLOR SPRITE$(1)=B$ | + | |
- | 900 RETURN | + | |
- | 910 ' Спрайт-указатель | + | |
- | 920 DATA 00000001 | + | |
- | 930 DATA 00000010 | + | |
- | 940 DATA 00000100 | + | |
- | 950 DATA 00011110 | + | |
- | 960 DATA 00111111 | + | |
- | 970 DATA 01111110 | + | |
- | 980 DATA 11111110 | + | |
- | 990 DATA 01111100 | + | |
- | + | ||
- | </code> | + | |
- | </hidden> | + | |
- | </WRAP> | + | |
- | + | ||
- | + | ||
- | В компьютере серии [[msx:msx_2]] эти пропорции могут быть изменены при помощи оператора: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | COLOR=(C,R,G,B) | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * C — арифметическое выражение, целая часть значения которого определяет номер //изменяемого// цвета; | + | |
- | * R,G,B — арифметические выражения, целые части значений которых определяют соответственно пропорции красного, зелёного и синего цветов. | + | |
- | + | ||
- | Последние три числа должны находиться в диапазоне от 0 до 7. | + | |
- | + | ||
- | Например, пусть значением C является 4 (текущий цвет фона) и попробуйте изменить для него пропорции RGB. Так, для получения чистого красного цвета фона, введите: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | COLOR=(4,7,0,0) | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | . | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | + | ||
- | Таким образом, можно получить 512 различных оттенков каждого цвета. | + | |
- | + | ||
- | Этот полезный оператор позволяет оперировать термином //"номер палитры"// вместо термина "номер цвета", принятого на компьютерах серии [[msx:msx_1]]. | + | |
- | + | ||
- | Отметим, что оператор ''SCREEN'' устанавливает палитры в начальное положение. Однако, для установки палитры без стирания экрана используйте оператор: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | COLOR=NEW | + | |
- | </code> | + | |
- | или | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | + | ||
- | </WRAP> | + | |
- | </WRAP> | + | |
- | + | ||
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | COLOR | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | . | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | + | ||
- | + | ||
- | <WRAP centeralign>Обратите внимание на то, что палитра не может быть изменена для компьютера серии [[msx:msx_1]].</WRAP> | + | |
- | + | ||
- | Операторы типа ''COLOR=(4,7,0,0)'', ''COLOR=NEW'' или ''COLOR'' без параметров здесь являются запрещёнными! | + | |
- | + | ||
- | {{anchor:cls}} | + | |
- | ==== V.4.3. Оператор CLS ==== | + | |
- | + | ||
- | Существует быстрый способ получить чистый(свободный от изображения) экран дисплея определённого цвета. Оператор | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | CLS | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где ''CLS''("to CLear Screen" — "очищать экран") — служебное слово; окрашивает весь экран цветом фона, не меняя положения графического курсора в графических режимах (в символьных режимах после действия ''CLS'' курсор помещается в левый верхний угол экрана!). | + | |
- | + | ||
- | {{anchor:e0543-01}} | + | |
- | Помещайте самый первый оператор ''COLOR'' в Вашей программе перед операторами ''SCREEN 2'' или ''SCREEN 3'', в противном случае для изменения цвета фона экрана после оператора ''COLOR'' примените оператор ''CLS''. Сравните результаты работы двух фрагментов: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | {{.examples:0543-011.bas|}} \\ [[+tab|wmsxbpge>0543-011.bas]] | + | |
- | <code> | + | |
- | 10 SCREEN 2:COLOR 1,15,4 | + | |
- | 20 FOR I=1 TO 1000:NEXT | + | |
- | 30 COLOR 15,1,4:CLS | + | |
- | 40 FOR I=1 TO 1000:NEXT:END | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | {{.examples:0543-012.bas|}} \\ [[+tab|wmsxbpge>0543-012.bas]] | + | |
- | <code> | + | |
- | 10 SCREEN 2:COLOR 1,15,4 | + | |
- | 20 FOR I=1 TO 1000:NEXT | + | |
- | 30 ::::'Пустой оператор! | + | |
- | 40 COLOR 15,1,4 | + | |
- | 50 FOR I=1 TO 1000:NEXT | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | + | ||
- | Очистка экрана необходима для того, чтобы получить результат работы программы в "чистом" виде (экран дисплея, как правило, "засорён" текстом, отражающим работу по составлению программы, но не относящимся к её исполнению). Кроме того, использование оператора ''CLS'' является элементом "культурного" программирования! Так оратор откашливается перед выступлением, заботясь о том, чтобы все слова донести до слушателей. | + | |
- | + | ||
- | ==== V.4.4. Оператор PSET. Оператор PRESET ==== | + | |
- | + | ||
- | {{anchor:pset}} | + | |
- | - <WRAP>{{anchor:pset1}}</WRAP> Первая форма записи оператора ''PSET'': <WRAP> | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | PSET[@](Х,Y)[,С] | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * PSET("to SET Point" — "установить точку") — служебное слово; | + | |
- | * X — арифметическое выражение, целая часть значения которого определяет x–координату точки (номер колонки); | + | |
- | * Y — арифметическое выражение, целая часть значения которого определяет y–координату точки (номер строки); | + | |
- | * С — арифметическое выражение, целая часть значения которого задаёт код цвета точки; | + | |
- | * @ — необязательный элемент оператора ''PSET'', никак не влияющий на его выполнение; он используется только для совместимости с другими версиями языка BASIC. | + | |
- | + | ||
- | При попытке использовать оператор ''PSET'' в символьных экранах ''SCREEN 0'' и ''SCREEN 1'', компьютер сообщает об ошибке: <WRAP centeralign>"Illegal function call".</WRAP> | + | |
- | Целые части значений X и Y должны принадлежать отрезку [-32768,32767], а целая часть значения C должна находиться на отрезке [0,15]; по умолчанию (отсутствие параметра C) используется текущий цвет изображения. Если точка (X,Y) находится "вне" графического экрана ''SCREEN 2'', (вне диапазона 0≤X≤255, 0≤Y≤191), то оператор не оказывает никакого действия. Поэтому, чтобы быть уверенным, что изображение точки строится в пределах экрана, желательно включать в программу проверку условий: 0≤X≤255, 0≤Y≤191. | + | |
- | + | ||
- | В результате выполнения оператора ''PSET'' графический курсор устанавливается в точку, определяемую параметрами (X,Y), и раскрашивает её цветом, определяемым значением параметра С. | + | |
- | + | ||
- | Обратим Ваше внимание на то, что оператор ''PSET'' может привести в режиме ''SCREEN 2'' к //изменению цвета// до 8 расположенных рядом точек в строке, определяемой значением Y. Например: | + | |
- | {{anchor:e0544-01}} {{.examples:0544-01.bas|}} \\ [[+tab|wmsxbpge>0544-01.bas]] | + | |
- | <code> | + | |
- | 10 INPUT A:COLOR 1,15,8:SCREEN 2: 'Исследуйте:80≤A≤87,96≤A≤103 | + | |
- | 20 CIRCLE(90,90),7,11:PAINT STEP(0,0),11:PSET(A,90),8 | + | |
- | 30 GOTO 30 | + | |
- | </code> | + | |
- | Дело в том, что каждая из 192 линий экрана ''SCREEN 2'' разбивается на 32 8–ми точечных сегмента (8–ми пиксельных сегмента). Каждому сегменту "присваивается" только //два// цвета — цвет изображения и цвет фона. Отображаемый на экране пиксел имеет цвет изображения, тогда как отсутствие пиксела означает появление пиксела, имеющего цвет фона. Следовательно, для восьмипиксельного сегмента возможно наличие всего //двух// цветов. | + | |
- | + | ||
- | Для режима ''SCREEN 3'' каждый блок точек 4×4 создаёт на экране изображение одной "точки", поэтому любое изменение цвета "маленькой" точки в этом блоке вызывает //изменение цвета// всего блока. | + | |
- | + | ||
- | Итак, вследствие неизбежного побочного эффекта "перетекания цветов", Вы должны быть очень аккуратны, применяя оператор ''PSET'', так как при этом легко можно изменить цвет уже нарисованной части изображения! | + | |
- | + | ||
- | __//Примеры//__: | + | |
- | * {{anchor:e0544-11}} 1) построение графика параболы Y²=50·X, X≥0, Y≥0. \\ {{.examples:0544-11.bas|}} \\ [[+tab|wmsxbpge>0544-11.bas]] <code> | + | |
- | 10 COLOR 1,15,8:SCREEN 2 | + | |
- | 20 FOR X=0 TO 255:PSET(X,191-SQR(50*X)):NEXT | + | |
- | 30 GOTO 30 | + | |
- | </code> | + | |
- | А теперь исключите оператор ''GOTO 30''. Обнаружили разницу при запуске?… Думаем, что да! Запомните этот приём! | + | |
- | * {{anchor:e0544-12}} 2) \\ {{.examples:0544-12.bas|}} \\ [[+tab|wmsxbpge>0544-12.bas]] <code> | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN2:FOR T=0 TO 6.28*4 STEP .05:X=3*SIN(2*T):Y=3*COS(3*T):PSET(44+10*X,96-15*Y),1 | + | |
- | 55 U=30*COS(T)-30/5*COS(5*T):V=30*SIN(T)-30/5*SIN(5*T) | + | |
- | 56 PSET(125+U,60+V),1:Z=T*COS(T):H=4*T*SIN(T):PSET(205+Z,96+H),1:E=25*COS(T)+25/2*COS(3*T):G=25*SIN(T)-25/2*SIN(3*T):PSET(125+E,130+G):NEXT | + | |
- | 80 GOTO 80'Замените эту строку на 80 A$=INPUT$(1) ! | + | |
- | </code> | + | |
- | * {{anchor:e0544-13}} 3) \\ {{.examples:0544-13.bas|}} \\ [[+tab|wmsxbpge>0544-13.bas]] <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 INPUT A,B,K,N:COLOR 1,15,8:SCREEN2 | + | |
- | 20 FOR T=0 TO 6.28 STEP.05:R=A*(1+COS(K*T)^N)+B*SIN(K*T)^N:X=R*COS(T):Y=R*SIN(T):PSET(128+X,96+Y):NEXT | + | |
- | 40 GOTO 40 'Замените эту строку на 40 A$=INPUT$(1) ! | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | - Вторая форма записи оператора ''PSET'': <WRAP> | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | PSET[@]STEP(X,Y)[,C] | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''STEP'' ("step" — "шаг") — служебное слово; | + | |
- | * @,X,Y,C имеют тот же смысл, что и в [[#pset1|пункте 1]]. | + | |
- | Элемент конструкции ''STEP''(X,Y) задаёт смещение координат изображаемой точки на X и Y соответственно относительно //текущей// позиции графического курсора. Например: | + | |
- | <code> | + | |
- | 10 COLOR 0,15,8:SCREEN 2:PSET(20,20):PSET STEP(5,7):GOTO 10 | + | |
- | </code> | + | |
- | В результате работы данного фрагмента программы на экране дисплея будут изображены две красные точки: (20,20) и (25,27). | + | |
- | + | ||
- | __//Примеры//__: | + | |
- | * {{anchor:e0544-21}} 1) построение крошечных точек с разной раскраской. \\ {{.examples:0544-21.bas|}} \\ [[+tab|wmsxbpge>0544-21.bas]] <code> | + | |
- | 10 COLOR 1,15,8:SCREEN3:PSET(45,95) ' Попробуйте режим | + | |
- | 30 FOR X=0 TO 15:PSET STEP(10,0),X:NEXT ' SCREEN2 ! | + | |
- | 60 GOTO60 'Подумайте, почему в режиме SCREEN3 расстояние между точками различно?! | + | |
- | </code> | + | |
- | * {{anchor:e0544-22}} 2) построение графика функции y=0.77x+14·sin(x/6),-128≤x≤127 (объясните назначение операторов ''PSET(0,95)'' и ''PSET(128,0)''). \\ {{.examples:0544-22.bas|}} \\ [[+tab|wmsxbpge>0544-22.bas]] <code> | + | |
- | 10 COLOR 1,15,8:SCREEN 2:PSET(0,95):FOR J=0 TO 255:PSET STEP(1,0),1:NEXT:PSET(128,0):FOR J=1 TO 191:PSET STEP(0,1),1:NEXT:FOR I=-128 TO 127:PSET(I+128,191/2-.77*I-14*SIN(I/6)),1:NEXT:B$=INPUT$(1) | + | |
- | </code> | + | |
- | * {{anchor:e0544-23}} 3) \\ {{.examples:0544-23.bas|}} \\ [[+tab|wmsxbpge>0544-23.bas]] <code> | + | |
- | 10 CLS:INPUT"Введите Р (от 0 до 4)14.4)";P | + | |
- | 20 COLOR 15,1,15:SCREEN3:E=0 | + | |
- | 30 FOR Y=1 TO 191 STEP4:FOR X=1 TO 255 STEP4:D=INT(E):PSET(X,Y),D:E=E+P | + | |
- | 40 IF E>14 THEN E=0 | + | |
- | 50 NEXT X,Y | + | |
- | 60 GOTO 60 | + | |
- | </code> | + | |
- | * {{anchor:e0544-24}} 4) \\ {{.examples:0544-24.bas|}} \\ [[+tab|wmsxbpge>0544-24.bas]] <code> | + | |
- | 5'Построение функциональных узоров | + | |
- | 10 DEF FNF(X,Y)=SQR(X^2+Y^2) | + | |
- | 20 SCREEN 3 | + | |
- | 30 FOR X=-.375 TO .375 STEP 1/64 | + | |
- | 40 FOR Y=-.375 TO .375 STEP 1/64 | + | |
- | 50 R=INT(200*FNF(X,Y)) | + | |
- | 60 C=R-2*INT(R/2) | + | |
- | 70 PSET(128+256*X,96+256*Y),C*11+4 | + | |
- | 80 NEXT Y,X | + | |
- | 90 GOTO 90 | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | + | ||
- | {{anchor:preset}} | + | |
- | Оператор ''PRESET'' ("Point RESET" — "стирание точки") представим двумя синтаксическими конструкциями: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | - <code>PRESET[@](X,Y)[,C]</code> | + | |
- | - <code>PRESET[@]STEP(X,Y)[,C]</code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | + | ||
- | </WRAP> | + | |
- | </WRAP> | + | |
- | + | ||
- | Здесь элементы @, (X,Y), ''STEP''(X,Y) и С имеют тот же смысл, что и в операторе ''PSET'', однако, при выполнении оператора ''PRESET'' без параметра С точка с координатами (X,Y) "стирается", т.е. приобретает цвет фона. Если же параметр С присутствует, то действия операторов ''PRESET'' и ''PSET'' идентичны. | + | |
- | + | ||
- | {{anchor:e0544-02}} __//Пример//__: Отрезок, "бегущий" по экрану! \\ {{.examples:0544-02.bas|}} \\ [[+tab|wmsxbpge>0544-02.bas]] <code> | + | |
- | 10 INPUT"Длина отрезка(≤45)";A:COLOR 1,15,8:SCREEN 2 | + | |
- | 20 FOR K=A TO 300:PSET(K,95):PRESET(K-A,95):NEXT:GOTO 20 | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:line}} | + | |
- | ==== V.4.5. Оператор LINE ==== | + | |
- | + | ||
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | У точек бедных крошек,\\ | + | |
- | Ни ручек нет, ни ножек.\\ | + | |
- | Как же они, не пойму я,\\ | + | |
- | Сцепляются в прямую? | + | |
- | <WRAP rightalign> | + | |
- | —//Дж.А.Линдон// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | Оператор ''LINE'' позволяет изображать отрезки прямых и прямоугольники с одновременной раскраской их требуемым цветом. | + | |
- | + | ||
- | Синтаксис оператора ''LINE'': | + | |
- | <code> | + | |
- | LINE [@][[STEP](X,Y)]-[STEP](Z,T),[C][,B(или BF)] | + | |
- | </code> | + | |
- | где: | + | |
- | * ''LINE'' ("line" — "линия") — служебное слово; | + | |
- | * сочетания параметров (X,Y)-(Z,T) или STEP(X,Y)-STEP(Z,T), или (X,Y)-STEP(Z,T), или STEP(X,Y)-(Z,T), или -(Z,T) , или -STEP(Z,T) задают на экране две точки: α и β. Если первый из элементов отсутствует, то в качестве соответствующей точки берётся та, в которой находится графический курсор (берутся координаты точки, использованной в последнем выполненном графическом операторе). Координаты точек α и β должны принадлежать отрезку [-32768,32767], однако, в режимах ''SCREEN 2'' и ''SCREEN 3'' на экране дисплея отображаются только точки с координатами X oт 0 до 255 и Y от 0 до 191; | + | |
- | * С — арифметическое выражение, целая часть значения которого задаёт код цвета линии (0≤С≤15); | + | |
- | * В ("Box" — "прямоугольник") — параметр, определяющий рисование прямоугольника (с заданием противоположных вершин) цветом С без закраски его внутренней части; | + | |
- | * BF ("Box Fill" — "заполненный прямоугольник") — параметр, определяющий рисование прямоугольника с одновременной закраской его внутренней части цветом, код которого определяется значением C; | + | |
- | * @ — необязательный элемент оператора ''LINE'', никак не влияющий на его выполнение. | + | |
- | + | ||
- | Обращение к оператору ''LINE'' в режимах ''SCREEN 0'' или ''SCREEN 1'', вызовет сообщение об ошибке: <WRAP centeralign>"Illegal function call".</WRAP> | + | |
- | + | ||
- | Если параметр C отсутствует, а параметр B (или BF) присутствует, то перед ним обязательно ставятся //две// запятые. В этом случае рисунок имеет цвет, заданный ранее оператором ''COLOR''. | + | |
- | + | ||
- | Рассмотрим три случая: | + | |
- | + | ||
- | - Параметр B (или BF) отсутствует. <WRAP> | + | |
- | + | ||
- | В этом случае компьютер проводит на экране линию, имеющую цвет C и соединяющую точки α и β. | + | |
- | Примеры записи оператора: | + | |
- | <code> | + | |
- | LINE(3,17)-(10,20),4 | + | |
- | LINE -(0,15),1 | + | |
- | LINE STEP(3,20)-(21,23) | + | |
- | LINE STEP(10,20)-STEP(15,60) | + | |
- | </code> | + | |
- | + | ||
- | __//Примеры//__: | + | |
- | + | ||
- | * {{anchor:e0545-01}} 1) \\ {{.examples:0545-01.bas|}} \\ [[+tab|wmsxbpge>0545-01.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 2:FOR X=-.5 TO .5 STEP.01:Y=1/(X^2-.05):K=K+2 | + | |
- | 40 LINE(K+25,Y+100)-(127,150):NEXT:A$=INPUT$(1) | + | |
- | </code> | + | |
- | * {{anchor:e0545-02}} 2) \\ {{.examples:0545-02.bas|}} \\ [[+tab|wmsxbpge>0545-02.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 K=8*ATN(1):SCREEN 2:PSET(128,96+80*COS(10)) | + | |
- | 20 FOR I=0TO K*6+.05 STEP.2:X=100*SIN(I):Y=80*COS(I+10) | + | |
- | 40 LINE-(128+X,96+Y),1,B:NEXT:A$=INPUT$(1) | + | |
- | </code> | + | |
- | * {{anchor:e0545-03}} 3) \\ {{.examples:0545-03.bas|}} \\ [[+tab|wmsxbpge>0545-03.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN2:XM=256:YM=191:XC=XM/2:YC=YM/2 | + | |
- | 50 FOR X=0 TO XM:C=INT(RND(1)*16):LINE (XC,YC)-(X,0),C | + | |
- | 80 NEXT X:FOR Y=0 TO YM:C=INT(RND(1)*16):LINE(XC,YC)-(XM,Y),C:NEXTY | + | |
- | 140 FOR X=XM TO 0 STEP-1:C=INT(RND(1)*16):LINE(XC,YC)-(X,YM),C:NEXT X:FOR Y=YM TO 0 STEP-1:C=INT(RND(1)*16):LINE(XC,YC)-(0,Y),C:NEXTY | + | |
- | 220 GOTO 220 | + | |
- | </code> | + | |
- | * {{anchor:e0545-04}} 4) \\ {{.examples:0545-04.bas|}} \\ [[+tab|wmsxbpge>0545-04.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10'Построение линейчатых поверхностей ("ruled surface") | + | |
- | 20 INPUT"i0,i1,h";I0,I1,H:INPUT"j0,j1";J0,J1 | + | |
- | 45 COLOR1,15,1:SCREEN2 | + | |
- | 50 'Лист Мебиуса.Начальные данные:{0,6.28,.0628,-20,20} | + | |
- | 60 DEFFNX(U,V)=COS(U)*(50+V*COS(U)):DEFFNY(U,V)=SIN(U)*(50+V*COS(U)):DEFFNZ(U,V)=V*SIN(U) | + | |
- | 90 'Геликоид. Начальные данные:{-.7,6,.12,-45,45} | + | |
- | 100 'DEFFNX(U,V)=V*COS(U):DEFFNY(U,V)=V*SIN(U) | + | |
- | 120 'DEFFNZ(U,V)=25*U-80 | + | |
- | 300 FOR I=I0 TO I1 STEP H | + | |
- | 310 J=J0:GOSUB 370:A=X:B=Y:I=I+H:GOSUB370:K=X:D=Y:I=I-H | + | |
- | 320 J=J1:GOSUB 370:A1=X:B1=Y:I=I+H:GOSUB370:K1=X:D1=Y:I=I-H:LINE(A,B)-(A1,B1):LINE(A,B)-(K,D):LINE(A1,B1)-(K1,D1):NEXTI:A$=INPUT$(1):END | + | |
- | 370 X=120+.7*(FNX(I,J)-FNY(I,J)):Y=94-(.7*(FNX(I,J)+FNY(I,J))+.7*FNZ(I,J)):RETURN '──▶ | + | |
- | </code> | + | |
- | * {{anchor:e0545-05}} 5) \\ {{.examples:0545-05.bas|}} \\ [[+tab|wmsxbpge>0545-05.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 11 COLOR 15,4,4:SCREEN2:PI=3.14159:FORB=10TO 50 STEP 10 | + | |
- | 25 A=B/2:FOR D=0 TO360 STEP4:FI=2*PI*D/360:R=A*(1+COS(5*FI))+B*SIN(5*FI)^2:X=R*COS(FI)+256/2:Y=R*SIN(FI)+191/2 | + | |
- | 85 IF D=0THEN LINE(X,Y)-(X+1,Y+1),15 ELSE LINE-(X,Y),15 | + | |
- | 90 NEXT:NEXT:PAINT(4,104),15:A$=INPUT$(1) | + | |
- | </code> | + | |
- | + | ||
- | Используя в операторе ''LINE'' пропуск координат первой точки (''(X,Y)'' или ''STEP(X,Y)''), можно "подхватить" линию с точки, где "остановился" предыдущий оператор, т.е., например, связать прямые линии между собой в ломаную линию. | + | |
- | Более того, прежде чем продолжить рисовать, программа может выполнить какие–либо другие действия. Компьютер "не забудет", в какой точке процесс рисования был приостановлен! Если же в операторе указан параметр ''STEP'', то заданные в круглых скобках координаты прибавляются к координатам последней упомянутой позиции графического курсора. | + | |
- | + | ||
- | * {{anchor:e0545-06}} 6) \\ {{.examples:0545-06.bas|}} \\ [[+tab|wmsxbpge>0545-06.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN2:PSET(115,95):GOSUB 100:END | + | |
- | 100 RESTORE 1000:READ N:FOR I=1 TO N:READ X,Y | + | |
- | 110 LINE -STEP(X,Y):NEXT:A$=INPUT$(1):END | + | |
- | 1000 DATA 6,35,0,23,-35,-23,-35,-35,0,-23,35,22,35 | + | |
- | </code> | + | |
- | + | ||
- | "Относительный"вариант синтаксиса оператора ''LINE'' (с использованием параметра ''STEP'') позволяет рисовать фигуры в "относительных" координатах. Затем можно легко помещать один и тот же объект в различные места экрана, указывая лишь его "начальную" точку! | + | |
- | + | ||
- | * {{anchor:e0545-07}} 7) Программа рисования пятиугольника, разделённого на сегменты. Заданы: начальная точка (XB,YB), масштаб (S) и цвет (C). \\ {{.examples:0545-07.bas|}} \\ [[+tab|wmsxbpge>0545-07.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 INPUT XB,YB,S,C:GOSUB 120'──▶ | + | |
- | 30 GOTO 30 | + | |
- | 120 RESTORE 170:SCREEN 2:COLOR 9:FOR X=1 TO 5:READ A,B | + | |
- | 130 LINE (XB,YB)-STEP(A*S,B*S),C:NEXT:RESTORE 170:FOR X=1 TO 5:READ A,B:LINE-(A*S+XB,B*S+YB),C:NEXT:RETURN'──▶ | + | |
- | 170 DATA 10,2,6,10,-6,10,-10,-2,0,-10 | + | |
- | </code> | + | |
- | Подумайте, какие изменения нужно внести в программу, чтобы на экране компьютер изобразил "почти" правильный пятиугольник. | + | |
- | * {{anchor:e0545-08}} 8) \\ {{.examples:0545-08.bas|}} \\ [[+tab|wmsxbpge>0545-08.bas]]<code> | + | |
- | 5 INPUT "Введите Р=2,5,7,10,13";P:SCREEN2 | + | |
- | 10 RAD=60 | + | |
- | 20 FOR ANG%=0 TO 360 STEP P | + | |
- | 30 RNG=ANG%*6.28/360:RG2=(ANG%+150)*6.28/360 | + | |
- | 50 X1=RAD*COS(RNG)+110:Y1=RAD*SIN(RNG)+90 | + | |
- | 70 X2=RAD*COS(RG2)+110:Y2=RAD*SIN(RG2)+90 | + | |
- | 85 LINE(X1,Y1)-(X2,Y2) | + | |
- | 90 NEXT ANG% | + | |
- | 100 GOTO 100 | + | |
- | </code> | + | |
- | * {{anchor:e0545-09}} 9) \\ {{.examples:0545-09.bas|}} \\ [[+tab|wmsxbpge>0545-09.bas]]<code> | + | |
- | 10 SCREEN 2:N=18:DIM X(N),Y(N):R=99:DT=2*3.1415/N:T=0 | + | |
- | 70 FOR I=1 TO N:T=T+DT:X(I)=160+R*COS(T):Y(I)=100-R*SIN(T) | + | |
- | 100 NEXT | + | |
- | 110 FOR I=1 TO N-1:FOR J=I+1 TO N:LINE (X(I),Y(I))-(X(J),Y(J)) | + | |
- | 140 NEXT:NEXT | + | |
- | 160 GOTO 160 | + | |
- | </code> | + | |
- | * {{anchor:e0545-10}} 10) \\ {{.examples:0545-10.bas|}} \\ [[+tab|wmsxbpge>0545-10.bas]]<code> | + | |
- | 170 DIM X(3),Y(3),XD(3),YD(3) | + | |
- | 180 SCREEN2:R=150:XL=100:YU=50:N=60 | + | |
- | 220 X(0)=XL:X(1)=XL+R:X(2)=XL+R:X(3)=XL | + | |
- | 230 Y(0)=YU+R:Y(1)=YU+R:Y(2)=YU:Y(3)=YU | + | |
- | 240 SMU=.08:RMU=1-SMU | + | |
- | 250 FOR I=1 TO N:FOR J=0 TO 3 | + | |
- | 260 XD(J)=RMU*X(J)+SMU*X((J+1)MOD4) | + | |
- | 270 YD(J)=RMU*Y(J)+SMU*Y((J+1)MOD4) | + | |
- | 280 NEXT | + | |
- | 290 FOR J=0 TO 3:LINE (X(J),Y(J))-(X((J+1)MOD4),Y((J+1)MOD4)) | + | |
- | 310 NEXT | + | |
- | 320 FOR J=0 TO 3:X(J)=XD(J):Y(J)=YD(J):NEXT:NEXT | + | |
- | 360 GOTO 360 | + | |
- | </code> | + | |
- | * {{anchor:e0545-11}} 11) \\ {{.examples:0545-11.bas|}} \\ [[+tab|wmsxbpge>0545-11.bas]]<code> | + | |
- | 10 DIM X(3),Y(3),XD(3),YD(3):COLOR 1,15:SCREEN2 | + | |
- | 30 R=60:XL=10:YU=17 | + | |
- | 50 FOR K=1 TO 2:FOR L=1 TO 3 | + | |
- | 70 X(0)=XL:X(1)=XL+R:X(2)=XL+R:X(3)=XL | + | |
- | 90 IF KMOD2=0 AND LMOD2=0 THEN 130 '──▶ | + | |
- | 100 IF KMOD2=1 AND LMOD2=1 THEN 130 '──▶ | + | |
- | 110 Y(0)=YU+R:Y(1)=YU+R:Y(2)=YU:Y(3)=YU | + | |
- | 120 GOTO 140 '──▶ | + | |
- | 130 Y(0)=YU :Y(1)=YU::Y(2)=YU+R:Y(3)=YU+R | + | |
- | 140 SMU=.08:RMU=1-SMU | + | |
- | 160 FOR I=1 TO 21:FOR J=0 TO 3 | + | |
- | 180 XD(J)=RMU*X(J)+SMU*X((J+1)MOD4) | + | |
- | 190 YD(J)=RMU*Y(J)+SMU*Y((J+1)MOD4) | + | |
- | 200 NEXT | + | |
- | 210 FOR J=0 TO 3 | + | |
- | 220 LINE(X(J),Y(J))-(X((J+1)MOD 4),Y((J+1)MOD4)) | + | |
- | 230 NEXT | + | |
- | 240 FOR J=0 TO 3:X(J)=XD(J):Y(J)=YD(J):NEXT:NEXT | + | |
- | 290 XL=XL+R:NEXT:XL=10:YU=YU+R:NEXT | + | |
- | 330 GOTO 330 | + | |
- | </code> | + | |
- | * {{anchor:e0545-12}} 12) И наконец, о "перетекании цветов". Сравните результаты работы двух программ: <WRAP group> | + | |
- | <WRAP half column> | + | |
- | {{.examples:0545-121.bas|}} \\ [[+tab|wmsxbpge>0545-121.bas]]<code> | + | |
- | 10 SCREEN 2 | + | |
- | 20 LINE(9,50)-(14,50),15 | + | |
- | 30 LINE(12,40)-(12,60),1 | + | |
- | 40 GOTO 40 | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | {{.examples:0545-122.bas|}} \\ [[+tab|wmsxbpge>0545-122.bas]]<code> | + | |
- | 10 SCREEN 2 | + | |
- | 20 LINE(8,50)-(15,50) | + | |
- | 30 LINE(12,40)-(12,60),1 | + | |
- | 40 GOTO 40 | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | + | ||
- | </WRAP> | + | |
- | - Параметр В есть. <WRAP> | + | |
- | В этом случае компьютер рисует прямоугольник со сторонами цвета C, параллельными "экранным" осям координат, причём, если указаны две точки α и β, то они представляют собой противоположные вершины изображаемого прямоугольника. Внутренняя часть прямоугольника не закрашивается. Если же указана только вторая точка (не забудьте указать перед ней тире !), то в качестве первой используется точка, изображённая или упомянутая в Вашей программе последней. | + | |
- | * {{anchor:e0545-131}} 13.1) \\ {{.examples:0545-131.bas|}} \\ [[+tab|wmsxbpge>0545-131.bas]]<code> | + | |
- | 10 COLOR 1,11:SCREEN 2 | + | |
- | 20 LINE(8,10)-STEP(7,8),15,B | + | |
- | 30 LINE(16,10)-STEP(7,8),1,B | + | |
- | 40 GOTO 40 | + | |
- | </code> | + | |
- | * {{anchor:e0545-132}} 13.2) \\ {{.examples:0545-132.bas|}} \\ [[+tab|wmsxbpge>0545-132.bas]]<code> | + | |
- | 10 COLOR 1,11:SCREEN 2 | + | |
- | 20 LINE(8,20)-STEP(3,8),15,B | + | |
- | 30 LINE(12,20)-STEP(11,8),1,B | + | |
- | 40 GOTO 40 | + | |
- | </code> | + | |
- | * {{anchor:e0545-133}} 13.3) \\ {{.examples:0545-133.bas|}} \\ [[+tab|wmsxbpge>0545-133.bas]]<code> | + | |
- | 10 COLOR 1,11:SCREEN 2 | + | |
- | 20 LINE(8,30)-STEP(11,8),15,B | + | |
- | 30 LINE(20,30)-STEP(3,8),1,B | + | |
- | 40 GOTO 40 | + | |
- | </code> | + | |
- | + | ||
- | //Вывод//: данные примеры совсем не означают, что невозможно создать многоцветные рисунки в режиме ''SCREEN 2''. Однако, расположение элементов рисунка должно быть тщательно выверено! | + | |
- | + | ||
- | При возникновении "конфликтов" между цветом линий и их расположением, параметр BF действует точно так же, как и оператор ''PSET'': он изображает все "задействованные" пиксели, переустанавливает цвет изображения сегмента, тогда как цвет фона остаётся неизменным. Чтобы проверить это, вернитесь к программе, приведённой выше и замените параметр B на BF. | + | |
- | </WRAP> | + | |
- | - Параметр BF есть. <WRAP> | + | |
- | + | ||
- | Компьютер, как и в случае β, изображает на экране дисплея прямоугольник, но внутренняя часть его закрашивается цветом С. | + | |
- | + | ||
- | __//Примеры//__ [[bibliography#b4|[4]]]: | + | |
- | * {{anchor:e0545-14}} 14) \\ {{.examples:0545-14.bas|}} \\ [[+tab|wmsxbpge>0545-14.bas]]<code> | + | |
- | 5 'Смещенные прямоугольники | + | |
- | 10 COLOR 1,15,8:SCREEN2 | + | |
- | 20 FOR X=0 TO 15 | + | |
- | 30 LINE(40+7*X,30+5*X)-(130+7*X,90+5*X),15-X,BF:NEXT | + | |
- | 50 GOTO 50 | + | |
- | </code> | + | |
- | * {{anchor:e0545-15}} 15) \\ {{.examples:0545-15.bas|}} \\ [[+tab|wmsxbpge>0545-15.bas]]<code> | + | |
- | 5' Вложенные прямоугольники | + | |
- | 10 COLOR 1,15,8:SCREEN2 | + | |
- | 20 FOR X=0 TO 15 | + | |
- | 30 LINE(2+8*X,6+6*X)-(254-8*X,185-6*X),15-X,BF:NEXT | + | |
- | 40 GOTO 40 | + | |
- | </code> | + | |
- | * {{anchor:e0545-16}} 16) \\ {{.examples:0545-16.bas|}} \\ [[+tab|wmsxbpge>0545-16.bas]]<code> | + | |
- | 5 'Прямоугольники разных цветов | + | |
- | 10 COLOR 1,15,8:SCREEN2:PSET(-4,160) | + | |
- | 20 FOR X=0 TO15:LINE STEP(8,-130)-STEP(8,130),X,BF:NEXT | + | |
- | 50 GOTO 50V.4.6. Оператор CIRCLE | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | + | ||
- | {{anchor:circle}} | + | |
- | ==== V.4.6. Оператор CIRCLE ==== | + | |
- | + | ||
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | Noli turbare CIRCilos meos! | + | |
- | <WRAP rightalign> | + | |
- | —//по преданию, Архимед встретил этими словами римского солдата—завоевателя, покушавшегося на его жизнь.// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | С помощью этого оператора компьютер изображает окружности, эллипсы или их дуги (точнее, ту их часть, которая "умещается" на экране дисплея). | + | |
- | + | ||
- | Синтаксис оператора ''CIRCLE'': | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | CIRCLE [@][STEP](X,Y),R,[C],[α],[β][,γ] | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * CIRCLE("circle" — "круг, окружность") — служебное слово; | + | |
- | * @ — необязательный элемент оператора ''CIRCLE'', никак не влияющий на его выполнение; | + | |
- | * X — арифметическое выражение, целая часть значения которого задаёт координату центра окружности (эллипса) по горизонтали; | + | |
- | * Y — арифметическое выражение, целая часть значения которого задаёт координату центра окружности (эллипса) по вертикали, значения X и Y должны принадлежать отрезку [-32768, 32767]. | + | |
- | + | ||
- | Отметим, что центр окружности (эллипса) (X,Y) может быть расположен в //любой// точке координатной плоскости (Вы, конечно, помните, что на экране будут изображены только те точки, координаты которых лежат в пределах 0≤X≤255 и 0≤Y≤191, причём начало координат находится в левом верхнем углу экрана). | + | |
- | + | ||
- | Далее, если указан параметр ''STEP'', то координаты центра вычисляются путём сложения координат, указанных после служебного слова ''STEP'' с последними упомянутыми координатами графического курсора (//относительное// задание координат центра); | + | |
- | * R — арифметическое выражение, целая часть значения которого должна принадлежать отрезку [-32768,32767]; | + | |
- | * C — арифметическое выражение, целая часть значения которого принадлежит [0,15] и определяет код цвета изображения; | + | |
- | * α — арифметическое выражение,значением которого является начало дуги окружности в радианах (по умолчанию α=0); | + | |
- | * β — арифметическое выражение, значением которого является конец дуги окружности в радианах (по умолчанию с одинарной точностью β=2·π=6.28319). | + | |
- | + | ||
- | Важно отметить, что -6.28319≤α, β≤6.28319, причём, если значение α меньше значения β, то дуга окружности (эллипса) проводится против часовой стрелки, а если первое значение больше второго, то — по часовой стрелке! | + | |
- | + | ||
- | У компьютера "школьное" представление об окружности: поворот от направления оси OX против часовой стрелки на прямой угол равен π/2 радиан, а полный поворот составляет 2π радиан. | + | |
- | + | ||
- | Заметим, что если любой из параметров α, β является отрицательным, то используется его абсолютное значение; при этом соответствующий конец дуги соединяется с центром линией радиуса (это необходимо при построении секторных диаграмм); к сожалению компьютер "не различает" значения параметров α и β, равные (-0) и 0, однако его можно "обмануть", если вместо -0 указать, например, -0.001; | + | |
- | * γ — арифметическое выражение, значение которого задаёт коэффициент "сжатия" окружности; если значение параметра γ≠1 (по умолчанию γ=1), то компьютер изображает эллипс; так, например, при γ=2 будет изображён эллипс с отношением вертикальной и горизонтальной осей равным 2 (величина вертикальной оси равна 2R); ориентация эллипса всегда либо горизонтальная, либо вертикальная; если окружность на экране оказывается чуть "сплюснутой", то выберите параметр γ в полуинтервале (1,1.33] (ибо 256/192≈1.33). | + | |
- | Величина параметра R определяет: | + | |
- | - радиус окружности, если γ=1; | + | |
- | - вертикальную полуось эллипса, если γ>1; | + | |
- | - горизонтальную полуось эллипса, если γ<1. | + | |
- | + | ||
- | Отметим, что любой необязательный параметр ''(STEP,C,α,β,γ)'' может быть опущен — однако, соответствующие запятые в записи оператора должны указывать на его отсутствие. После последнего параметра запятая не нужна. | + | |
- | + | ||
- | В результате выполнения оператора ''CIRCLE'' компьютер нарисует эллипс(или его дугу), после чего графический курсор переместится в точку (R,Y)! Однако, если далее нужно провести другую линию или поставить точку, то графический курсор вначале переместится в точку (X,Y), отмеченную в операторе ''CIRCLE'', а уже затем компьютер будет считать последней упомянутой точкой центр окружности. Оператор графики, ссылающийся на последнюю упомянутую точку, начнёт построение из центра окружности. | + | |
- | + | ||
- | На примере показано, как использовать эту возможность, чтобы нарисовать красный леденец на жёлтой палочке: | + | |
- | {{anchor:e0546-00}} {{.examples:0546-00.bas|}} \\ [[+tab|wmsxbpge>0546-00.bas]]<code> | + | |
- | 10 COLOR 8,15,4:SCREEN2:CIRCLE(126,95),20,8:LINE-(126,140),11 | + | |
- | 20 GOTO 20'Обратите внимание на эффект "перетекания цветов"! | + | |
- | </code> | + | |
- | Ошибки в задании параметров влекут за собой сообщения: <WRAP centeralign>"Overflow" \\ (//"Переполнение"//) </WRAP> или <WRAP centeralign>"Syntax error" \\ (//"Синтаксическая ошибка"//).</WRAP> | + | |
- | + | ||
- | Если компьютер "долгое" время ничего не рисует, то это скорее всего означает, что Вы задали слишком большую величину радиуса окружности, и изображение вышло за рамки экрана дисплея. | + | |
- | + | ||
- | __//Примеры//__: | + | |
- | * <WRAP> {{anchor:e0546-01}} 1) \\ {{.examples:0546-01.bas|}} \\ [[+tab|wmsxbpge>0546-01.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 INPUT R,A,B,T:SCREEN2:CIRCLE(127,95),R,,A,B,T | + | |
- | 20 GOTO 20 | + | |
- | </code> | + | |
- | ^ R ^ A ^ B ^ T ^ | + | |
- | | 40 | -3.14 | -0.79 | 1 | | + | |
- | | 40 | 6.00 | -6.28 | 1 | | + | |
- | | 40 | -.79 | -2.36 | .3 | | + | |
- | | 40 | 0 | 3.14 | 1 | | + | |
- | | 40 | 3.14 | 6.28 | 1 | | + | |
- | | 40 | 0 | 6.28 | 1 | | + | |
- | | 40 | -0 | -3.14 | 1 | | + | |
- | | 40 | -.01 | -3.14 | 1 | | + | |
- | | 40 | 0 | 6.28 | 4 | | + | |
- | | 40 | 0 | 6.28 | 0.25 | | + | |
- | | 110 | 0 | 3.14 | 1 | | + | |
- | </WRAP> | + | |
- | * {{anchor:e0546-02}} 2) \\ {{.examples:0546-02.bas|}} \\ [[+tab|wmsxbpge>0546-02.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR1,15,4:SCREEN2:LINE(30,10)-(220,180),1,BF | + | |
- | 30 CIRCLE(125,95),75,15:FOR R=5TO70STEP5:CIRCLE(125,92.5),R,15:CIRCLE(125,97.5),R,15:NEXT | + | |
- | 100 GOTO 100 | + | |
- | </code> | + | |
- | * {{anchor:e0546-03}} 3) \\ {{.examples:0546-03.bas|}} \\ [[+tab|wmsxbpge>0546-03.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN2:PSET(0,125):FOR K=1 TO 25:CIRCLE STEP(10,0),50,4,0,3.14159:NEXT:PSET(0,160):FOR K=1 TO50:CIRCLE STEP(5,0),30,4:NEXT:PSET(0,37):FOR K=1TO26 STEP.5:CIRCLE STEP(5,0),K,1:NEXT:A$=INPUT$(1) | + | |
- | </code> | + | |
- | * {{anchor:e0546-04}} 4) \\ {{.examples:0546-04.bas|}} \\ [[+tab|wmsxbpge>0546-04.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN2 | + | |
- | 20 FOR K=1 TO 100:C=INT(RND(1)*16):E=RND(1):CIRCLE(128,95),80,C,,,E:NEXT | + | |
- | 60 GOTO 60 | + | |
- | </code> | + | |
- | * {{anchor:e0546-05}} 5) \\ {{.examples:0546-05.bas|}} \\ [[+tab|wmsxbpge>0546-05.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN2:R=100:P=50 | + | |
- | 20 I=I+.1:P=P-.5:R=R-Q:Q=Q+.1:Y=P*SIN(I):CIRCLE(128,Y+95),R,,,,.2 | + | |
- | 60 GOTO 20 | + | |
- | </code> | + | |
- | * {{anchor:e0546-06}} 6) \\ {{.examples:0546-06.bas|}} \\ [[+tab|wmsxbpge>0546-06.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 5 '"Ползущий" эллипс | + | |
- | 10 COLOR 1,15,8:SCREEN2 | + | |
- | 20 PSET(0,95):FOR K=1 TO 25:CIRCLE STEP(10,0),50,4,,,.5:CIRCLE STEP(0,0),50,15,,,.5:NEXT:GOTO20 | + | |
- | </code> | + | |
- | * {{anchor:e0546-07}} 7) \\ {{.examples:0546-07.bas|}} \\ [[+tab|wmsxbpge>0546-07.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN2 | + | |
- | 12 FOR E=5 TO 0 STEP-.099:CIRCLE(128,96),80,1,,,E:NEXT | + | |
- | 30 GOTO 30 | + | |
- | </code> | + | |
- | * {{anchor:e0546-08}} 8) \\ {{.examples:0546-08.bas|}} \\ [[+tab|wmsxbpge>0546-08.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 5 '"Вороне где-то бог послал кусочек сыру..." | + | |
- | 10 COLOR15,4,4:SCREEN2 | + | |
- | 15 CIRCLE(90,100),2,15:CIRCLE(100,50),2,15:CIRCLE(60,80),4,15:CIRCLE(70,125),3,15:CIRCLE(130,105),2,15 | + | |
- | 17 CIRCLE(100,140),3,15:CIRCLE(140,57),1,15:CIRCLE(150,80),2,15:CIRCLE(100,130),3,15:CIRCLE(110,60),4,15 | + | |
- | 20 CIRCLE(100,100),75,,-1,-1E-03,1.2 | + | |
- | 30 CIRCLE STEP(10,-5),75,,-1E-03,-1,1.2 | + | |
- | 50 PAINT(70,100):PAINT(130,80):B$=INPUT$(1) | + | |
- | </code> | + | |
- | * {{anchor:e0546-09}} 9) \\ {{.examples:0546-09.bas|}} \\ [[+tab|wmsxbpge>0546-09.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN2:Q=3 | + | |
- | 20 Q=Q-.05:I=I+Q | + | |
- | 30 CIRCLE(128,95),I | + | |
- | 40 IF I>88 THEN 50 ELSE 20 | + | |
- | 50 GOTO 50 | + | |
- | </code> | + | |
- | * {{anchor:e0546-10}} 10) \\ {{.examples:0546-10.bas|}} \\ [[+tab|wmsxbpge>0546-10.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN2 | + | |
- | 20 I=I+0.5 | + | |
- | 30 CIRCLE(128,95),I | + | |
- | 40 IF I>88 THEN 50 ELSE 20 | + | |
- | 50 GOTO 50 | + | |
- | </code> | + | |
- | * <WRAP>{{anchor:e0546-11}} 11) [[bibliography#b14|[14]]] \\ {{.examples:0546-11.bas|}} \\ [[+tab|wmsxbpge>0546-11.bas]] | + | |
- | \\ | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 'Моделирование движения подпрыгивающего мяча [14]. | + | |
- | 20 XM=256:YM=191:X=-10:INPUTH:W=3.14159/40:D=90*3.14159/180:K=.01:COLOR15,4,8:SCREEN2 | + | |
- | 100 KE=1:FORXN=0TOXM-10STEP4:YN=H*SIN(W*XN+D)*EXP(-K*XN) | + | |
- | 130 LINE(0,YM)-(XM,YM):YN=YM-ABS(YN)-3:CIRCLE(X,Y),4,4:IF Y>186 THEN KE=KE+2:CIRCLE(XN+10,YN),4,KE ELSE CIRCLE(XN+10,YN),4,KE | + | |
- | 170 X=XN+10:Y=YN:NEXT XN:GOTO 100 | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | * {{anchor:e0546-12}} 12) \\ {{.examples:0546-12.bas|}} \\ [[+tab|wmsxbpge>0546-12.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN2 | + | |
- | 20 FOR I=1 TO 13 | + | |
- | 30 CIRCLE(40+I*15,40+I*10),55-I*3,15-I,0,6.28:PAINT STEP(0,0),15-I | + | |
- | 40 NEXT | + | |
- | 50 GOTO 50 | + | |
- | </code> | + | |
- | К сожалению, оператор ''CIRCLE'' не позволяет ориентировать эллипс под любым углом по отношению к горизонтальной оси. Если Вы хотите отобразить такую кривую, воспользуйтесь следующим приёмом: | + | |
- | {{anchor:e0546-13}} {{.examples:0546-13.bas|}} \\ [[+tab|wmsxbpge>0546-13.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN2:PI=4*ATN(1) | + | |
- | 30 FOR I=0 TO 200 | + | |
- | 40 X=120+70*SIN(I*PI/100+PI/4):Y=90-50*COS(I*PI/100) | + | |
- | 60 PSET(X,Y) | + | |
- | 70 NEXT | + | |
- | 80 GOTO 80 | + | |
- | </code> | + | |
- | Сдвиг PI/4 (45 градусов) в программной строке 40 определяет угол наклона большой полуоси эллипса к оси X. | + | |
- | + | ||
- | ==== V.4.7. Функция POINT. Оператор PAINT ==== | + | |
- | + | ||
- | {{anchor:point}} | + | |
- | Синтаксис функции ''POINT'': | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | POINT [STEP](X,Y) | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''POINT'' ("point" — "точка") — служебное слово; | + | |
- | * X — арифметическое выражение, целая часть значения которого принадлежит отрезку [0,255] и задаёт x–координату точки; | + | |
- | * Y — арифметическое выражение, целая часть значения которого принадлежит отрезку [0,191] и задаёт y–координату точки; | + | |
- | * STEP(X,Y) определяет смещение координат точки на X и Y соответственно относительно текущей позиции графического курсора. | + | |
- | + | ||
- | Функция ''POINT'' в графическом режиме (''SCREEN 2'', ''SCREEN 3'') возвращает код цвета точки с координатами (X,Y), т.е. целое число, принадлежащее отрезку [0,15]. На текстовом экране функция ''POINT'' всегда возвращает //нуль//. | + | |
- | + | ||
- | Будьте осторожны! Иногда в режиме ''SCREEN 2'' //восемь// (!) последовательных точек в строке окрашиваются одним цветом, т.к. на 8 соседних в строке точек изображения (с номерами 0÷7,8÷15,…,248÷255) должно приходиться только два цвета: основной и фоновый. Попытка установить для этих восьми точек третий цвет приведёт к переопределению уже имеющихся цветов! | + | |
- | + | ||
- | Если точка находится за пределами координатных ограничений (0≤X≤255, 0≤Y≤191), то функция возвращает -1; если точка не принадлежит изображению, то функция возвращает код цвета фона. | + | |
- | + | ||
- | Функция ''POINT'' в основном используется для: | + | |
- | - определения принадлежности точки некоторому рисунку; | + | |
- | - определения цвета границы; | + | |
- | - определения, было ли столкновение движущегося на графическом экране объекта с другим объектом, также находящимся на графическом экране. | + | |
- | + | ||
- | __//Примеры//__: | + | |
- | * <WRAP> {{anchor:e0547-01}} 1) \\ {{.examples:0547-01.bas|}} \\ [[+tab|wmsxbpge>0547-01.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 5 '"Столкновение" движущегося отрезка с неподвижной "границей" | + | |
- | 10 COLOR 1,15,8:SCREEN2:LINE(150,0)-(150,150),6 | + | |
- | 20 FOR K=10TO295:PSET(K,95):PRESET(K-10,95):FORI=1TO19:NEXT:IF POINT(150,95)=1 THEN FORI=1TO1000:NEXT:SCREEN0:LOCATE 11,12:PRINT"Столкновение":END ELSE NEXT | + | |
- | </code> | + | |
- | А теперь замените в условии оператора ''IF…THEN…ELSE'' ''POINT(150,95)'' на ''POINT(149,95)…'' Заметили разницу?! | + | |
- | </WRAP> | + | |
- | * {{anchor:e0547-02}} 2) \\ {{.examples:0547-02.bas|}} \\ [[+tab|wmsxbpge>0547-02.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN 3 | + | |
- | 20 FORK=1TO12:PSET(20*K,95),INT(RND(-TIME)*16):NEXT:P=0 | + | |
- | 50 FOR K=1 TO 12:IF POINT(20*K,95)=1 THEN P=1 | + | |
- | 70 NEXT:FOR K=1 TO 1000:NEXT:SCREEN0:KEY OFF | + | |
- | 80 IF P=1 THEN GOSUB 110:FORI=1TO1000:NEXT:GOTO 10 ELSE GOSUB 100:FOR I=1 TO 1000:NEXT:GOTO 10 | + | |
- | 100 LOCATE 9,12:PRINT"Черных точек нет!":RETURN | + | |
- | 110 LOCATE 9,12:PRINT"Черные точки есть!":RETURN | + | |
- | </code> | + | |
- | * <WRAP> 3) Для закраски точки (X,Y) примените следующий приём: | + | |
- | PSET(X,Y),POINT(U,V) | + | |
- | где точка (U,V) принадлежит //фону//! Другой способ закраски точки на графическом экране Вы узнаете, изучив оператор ''PAINT''. | + | |
- | + | ||
- | Забегая //далеко вперёд//, отметим, что эта функция игнорирует //спрайты//. Если точка изображается в белом цвете потому, что скрыта белым спрайтом, возвращаемый цвет соответствует действительному цвету точки. | + | |
- | </WRAP> | + | |
- | + | ||
- | {{anchor:paint}} | + | |
- | Для закрашивания областей, ограниченных замкнутыми //одноцветными// линиями, используется оператор ''PAINT'', синтаксис которого: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | PAINT [@][STEP](X,Y),[C][,G] | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''PAINT''("to paint" — "красить") — служебное слово; | + | |
- | * @ — необязательный элемент оператора ''PAINT'', никак не влияющий на его выполнение; | + | |
- | * X — арифметическое выражение, целая часть значения которого принадлежит отрезку [0,255] и определяет x–координату точки; | + | |
- | * Y — арифметическое выражение, целая часть значения которого принадлежит отрезку [0,191] и определяет y–координату точки; (заметим, что, в отличие от других графических операторов, значения X и Y должны обязательно находиться в прямоугольнике [0,255]×[0,191], в противном случае компьютер сообщает об ошибке: <WRAP centeralign>"Illegal function call in …";</WRAP> параметр ''STEP'', как всегда, указывает смещение закрашиваемой точки от последней упомянутой Вами точки; | + | |
- | * С — арифметическое выражение, целая часть значения которого принадлежит отрезку [0,15] и задаёт код цвета закраски области графического экрана; если параметр С опущен, то область закрашивается текущим цветом изображения; | + | |
- | * G — арифметическое выражение, целая часть значения которого принадлежит отрезку [0,15] и задаёт код цвета границы закрашиваемой области; если параметр G опущен, то используется код текущего цвета изображения; этот параметр игнорируется в режиме ''SCREEN 2'', поэтому в ''SCREEN 2'' контур другого цвета можно получить, рисуя этот контур повторно требуемым цветом. В режимах ''SCREEN 3'', ''SCREEN 5'' — ''SCREEN 8'' такой проблемы не существует! | + | |
- | + | ||
- | Заметим, что если параметр С опущен, а параметр G присутствует, то перед параметром G должны стоять две запятые, указывающие на отсутствие параметра С. | + | |
- | + | ||
- | Пусть целые части значений параметров X,Y определяют точку с координатами (X1,Y1). | + | |
- | + | ||
- | Обозначим ∑ — совокупность областей, ограниченных замкнутыми линиями цвета C, для которых точка (X1,Y1) является //внутренней// (если точка принадлежит границе области, то компьютер окажется в "раздумье": что же ему закрашивать? И… ничего не закрасит!). Если таких областей нет, то примем за ∑ весь экран дисплея. Далее, пусть область σ — пересечение областей семейства ∑. Тогда после выполнения оператора ''PAINT'' область σ закрашивается цветом С. | + | |
- | + | ||
- | Итак, для закрашивания области необходимо указать: | + | |
- | - координаты произвольной точки, лежащей внутри области; | + | |
- | - цвет закраски области и цвет контура, который Вы не хотите пересекать при закрашивании. | + | |
- | Отметим, что оператор ''PAINT'' — очень "медленный" оператор по сравнению с оператором ''LINE'' (с параметром BF); так, закраска всего экрана занимает в режиме ''SCREEN 2'' около 15 секунд. Наконец, учтите, что даже мельчайшая "прореха" в границе (разрыв контура) позволяет оператору ''PAINT'' "пролиться наружу" и закрасить те участки экрана, которые Вы и не собирались окрашивать! | + | |
- | + | ||
- | Поскольку при выполнении оператора ''PAINT'' используется стековая память, понятно, что в процессе закрашивания некоторой области на экране внезапно может появиться сообщение об ошибке: <WRAP centeralign>"Out of memory".</WRAP> | + | |
- | Вероятность появления такой ошибки повышается, если оператор ''PAINT'' является частью "глубоко" вложенных друг в друга циклов ''FOR…NEXT'' или подпрограмм, или же если контур, ограничивающий закрашиваемую область, имеет достаточно сложную форму. | + | |
- | + | ||
- | __//Примеры//__: | + | |
- | * {{anchor:e0547-11}} 1) \\ {{.examples:0547-11.bas|}} \\ [[+tab|wmsxbpge>0547-11.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN2 | + | |
- | 20 FOR K=0 TO 15 | + | |
- | 30 CIRCLE(128,95),127-8*K,15-K,,,.7 | + | |
- | 40 PAINT(128,95),15-K | + | |
- | 50 NEXT | + | |
- | 60 GOTO 60 | + | |
- | </code> | + | |
- | * {{anchor:e0547-12}} 2) \\ {{.examples:0547-12.bas|}} \\ [[+tab|wmsxbpge>0547-12.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN2 | + | |
- | 20 FOR K=0 TO 15 | + | |
- | 30 CIRCLE(128,95),127-8*K,15-K,0.,6.25,.7' 2π≈6.28! | + | |
- | 40 PAINT(128,95),15-K | + | |
- | 50 NEXT | + | |
- | 60 GOTO 60 | + | |
- | </code> | + | |
- | * {{anchor:e0547-13}} 3) \\ {{.examples:0547-13.bas|}} \\ [[+tab|wmsxbpge>0547-13.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN3 | + | |
- | 20 FOR K=0 TO 15:CIRCLE(128,95),127-8*K,K,,,.7:PAINT(128,95),15-K,K:NEXT | + | |
- | 60 GOTO 60 | + | |
- | </code> | + | |
- | * {{anchor:e0547-14}} 4) \\ {{.examples:0547-14.bas|}} \\ [[+tab|wmsxbpge>0547-14.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN2 | + | |
- | 20 CIRCLE(128,95),60,10 | + | |
- | 30 PAINT STEP(0,0),10 | + | |
- | 40 GOTO 40 | + | |
- | </code> | + | |
- | * {{anchor:e0547-15}} 5) \\ {{.examples:0547-15.bas|}} \\ [[+tab|wmsxbpge>0547-15.bas]]<code> | + | |
- | 10 COLOR 1,10,4:SCREEN2:FOR I=20 TO 110 STEP 10:CIRCLE(I+128,95),80,1:PAINT(1.85*I,I+1),1:NEXT:A$=INPUT$(1) | + | |
- | </code> | + | |
- | * {{anchor:e0547-16}} 6) \\ {{.examples:0547-16.bas|}} \\ [[+tab|wmsxbpge>0547-16.bas]]<code> | + | |
- | Ok | + | |
- | 10 COLOR1,15,8:SCREEN2 | + | |
- | 20 CIRCLE(95,60),20,1,-.01,-4.7124,1.1:PAINT(85,55),1:CIRCLE(95,125),20,1,-1.5708,-6.2832,1.1:PAINT(85,130),1:CIRCLE(154,60),20,1,-4.7124,-3.1416,1.1:PAINT(145,50),1:CIRCLE(154,125),20,1,-3.1416,-1.5708,1.1:PAINT(155,106),1:GOTO20 | + | |
- | </code> | + | |
- | + | ||
- | ==== V.4.8. Вывод рисунков на принтер ==== | + | |
- | + | ||
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | …Вы печатаете на клавиатуре заклинание, и вот экран дисплея оживает, показывая объекты, которых не было и не может быть никогда. | + | |
- | <WRAP rightalign> | + | |
- | —//Ф.П.Брукс// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | Твёрдая копия — зафиксированное на бумажном носителе изображение на экране дисплея. | + | |
- | <WRAP rightalign> | + | |
- | —//Толковый словарь по вычислительной технике и программированию// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | А сейчас мы научим Вас выводить на печатающее устройство (принтер) рисунки, изображённые компьютером на экране дисплея. Для этого используем вспомогательную подпрограмму, записанную в двоичных кодах, загрузка которой в оперативную память компьютера осуществляется подпрограммой с именем {{.examples:hardcopy.bas|HARDCOPY.BAS}}. | + | |
- | + | ||
- | <WRAP>{{anchor:e0548-01}} __//Пример 1//__ [[bibliography#b14|[14]]]. Восстановим облик хищного тираннозавра (ящера–разбойника), жившего в мезозойскую эру он достигал высоты 5 м, длины 14 м). | + | |
- | \\ {{.examples:0548-01.bas|}} \\ [[+tab|wmsxbpge>0548-01.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 CLS:COLOR 1,15,8:SCREEN2:R=5/6 | + | |
- | 30 READ N:IF N=0 THEN 350 | + | |
- | 50 READ X1,Y1:X1=X1/2:Y1=Y1/.9:Y1=Y1*R | + | |
- | 70 FOR P=2 TO N:READ X2,Y2:X2=X2/2:Y2=Y2/.9:Y2=Y2*R | + | |
- | 90 LINE(X1,Y1)-(X2,Y2),1:X1=X2:Y1=Y2:NEXT P | + | |
- | 130 GOTO 30 | + | |
- | 135 'Основная часть туловища тираннозавра | + | |
- | 140 DATA 38,223,60,180,71,173,65,174,63,179,64,180,62,185,62,187,60,192,60,194,57,200,57,202,55,183,55,182,59,172,58,171,62,165,57,170,50,220,31,233,31,245,40,260,60,290,67,315,72 | + | |
- | 170 DATA 345,80,360,87,380,105,400,127,425,145,452,155,502,164,450,164, 434,162,415,158,395,153,362,138,323,132,283,125 | + | |
- | 190 'Большая задняя лапа. | + | |
- | 200 DATA 16,289,92,250,120,250,135,260,157,233,163,247,163,240,165,257, 164,256,166,272,159,270,153,278,140,280,120,285,120,310,120,330,112 | + | |
- | 230 'Маленькая задняя лапа. | + | |
- | 240 DATA 11,295,127,303,158,278,162,288,162,282,163 | + | |
- | 250 DATA 291,164,283,165,315,162,315,157,325,137,323,132 | + | |
- | 260 'Передняя лапа. | + | |
- | 270 DATA 11,238,77,220,87,192,99,192,102,195,100 | + | |
- | 280 DATA 198,102,200,100,203,102,205,98,218,96,255,83 | + | |
- | 290 'Остальная часть тираннозавра. | + | |
- | 300 DATA 3,258,114,245,105,228,93,3,222,86,215,77,210,65 | + | |
- | 320 'Глаз. | + | |
- | 330 DATA 4,220,42,210,45,215,40,220,42,0 | + | |
- | 350 GOSUB 55020 '──▶ Вызов подпрограммы HARDCOPY.BAS | + | |
- | 360 A=USR(0)'Вызов подпрограммы вывода на принтер,загруженной ранее в оперативную память подпрограммой HARDCOPY.BAS | + | |
- | 370 END '"What you see is what you get!" | + | |
- | 55010 'Подпрограмма HARDCOPY.BAS | + | |
- | 55020 DT=&HEF00:DEFUSR=DT:RESTORE 55060 | + | |
- | 55030 FOR I=0 TO &HAB | + | |
- | 55040 READ DT$:POKE DT+I,VAL("&H"+DT$) | + | |
- | 55050 NEXT:RETURN '──▶ | + | |
- | 55060 DATA 21,00,20,22,AC,EF,21,91,EF,CD,87 | + | |
- | 55070 DATA EF,21,9B,EF,CD,87,EF,0E,08,2A,AC | + | |
- | 55080 DATA EF,CD,4A,00,57,E6,0F,5F,CB,3A,CB,3A | + | |
- | 55090 DATA CB,3A,CB,3A,00,3E,0F,BA,20,0D,BB | + | |
- | 55100 DATA 20,03,AF,18,11,CD,7F,EF,EE,FF,18 | + | |
- | 55110 DATA 0A,BB,28,04,3E,FF,18,03,CD,7F,EF,23 | + | |
- | 55120 DATA 22,AC,EF,06,08,21,AE,EF,CB,27,CB | + | |
- | 55130 DATA 1E,23,10,F9,0D,20,BE,06,08,21,AE | + | |
- | 55140 DATA EF,7E,CD,A5,00,23,10,F9,2A,AC,EF,AF | + | |
- | 55150 DATA BD,20,A9,3E,0D,CD,A5,00,3E,0A,CD | + | |
- | 55160 DATA A5,00,3E,38,BC,20,94,21,A2,EF,CD | + | |
- | 55170 DATA 87,EF,C9,CB,AC,CD,4A,00,CB,EC,C9,7E | + | |
- | 55180 DATA FE,FF,C8,CD,A5,00,23,18,F6,1B,54,31 | + | |
- | 55190 DATA 36,1B,45,1B,3E,0E,FF,1B,53,30,32,35 | + | |
- | 55200 DATA 36,FF,1B,4E,0F,1B,41,1B,3C,0D,0A,FF | + | |
- | </code> | + | |
- | Версия программы без вывода на принтер: \\ {{.examples:0548-012.bas|}} \\ [[+tab|wmsxbpge>0548-012.bas]] | + | |
- | </WRAP> | + | |
- | <WRAP>{{anchor:e0548-02}} __//Пример 2//__. | + | |
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | Лучше гор могут быть только горы. | + | |
- | <WRAP rightalign> | + | |
- | —//В.Высоцкий// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | Л.Карпентер и независимо от него А.Фурнье и Д.Фассел изобрели метод //"фракталов"//("fractal"), в котором неправильность естественных объектов (линия берега, горы и т.д.) имитируется компьютером за счёт внесения случайных вариаций в представленный художником рисунок, делая гладкие линии изломанными и т.п. Методом фракталов удаётся получать на удивление реалистические горы, долины, с раскиданными по ним валунами, береговые линии, скопления звёзд, цветные географические карты, хлопья снега, ветви деревьев и т.д., а художнику остаётся лишь задать небольшое количество точек. | + | |
- | Алгоритм метода изложен в монографии [[bibliography#b15|[15]]]. | + | |
- | + | ||
- | В пространстве берётся некоторый исходный треугольник и над ним выполняется следующая процедура. Находятся средние точки всех сторон треугольника и переносятся (не обязательно в одной плоскости) на расстояние, пропорциональное длине соответствующей стороны. Коэффициент пропорциональности при этом выбирается случайным образом. Соединяя три получившиеся в результате точки, определяем четыре новых треугольника. Затем та же процедура по очереди применяется к каждому из этих четырёх треугольников. Теперь | + | |
- | образуется 16 треугольников и т.д. Таким образом, из одного исходного треугольника можно получить целое множество треугольников, образующих очень сложную полигональную поверхность. Её изображение создаётся обычным образом: удаляются скрытые поверхности, и затем производится закраска. | + | |
- | + | ||
- | Приведённая ниже программа позволяет в любой момент времени вывести рисунок, изображённый на экране, "на принтер" по нажатию клавиши <key>p</key>, после чего Вы можете продолжить работу программы, нажав любую клавишу. | + | |
- | + | ||
- | Итак, включайте скорее принтер... | + | |
- | \\ {{.examples:0548-02.bas|}} \\ [[+tab|wmsxbpge>0548-02.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN2:C=120:O=RND(-TIME) | + | |
- | 20 DIM P(300,2),L(300,2) | + | |
- | 30 P(1,1)=10:P(1,2)=170:P(2,1)=240:P(2,2)=170:L(1,1)=1:L(1,2)=2:PTS=2:LNS=1:J=PTS:K=LNS | + | |
- | 40 FOR I=1 TO LNS:J=J+1:K=K+1:S=LNS | + | |
- | 50 IF I=1 THEN P1=J-1:P2=K-1:DIM Q3(S),Q4(S),Q5(S),Q6(S) | + | |
- | 60 A=L(I,1):B=L(I,2):X1=P(A,1):Q3(I)=X1:Y1=P(A,2):Q4(I)=Y1 | + | |
- | 70 X2=P(B,1):Q5(I)=X2:Y2=P(B,2):Q6(I)=Y2:LINE(X1,Y1)-(X2,Y2):IF I=<A5 THEN GOSUB 140 | + | |
- | 80 A1=RND(1):P(J,1)=(X1+X2)/2:P(J,2)=(Y1+Y2)/2-C*A1:L(I,2)=J:L(K,1)=J:L(K,2)=B:A6=A6+1:IF A6=1 THEN DIM X3(S),Y3(S),X4(S),Y4(S) | + | |
- | 90 NEXT:ERASE X3,X4,Y3,Y4:GOSUB 110:ERASE Q3,Q4,Q5,Q6 | + | |
- | 100 PTS=J:LNS=K:C=C/1.8:F=F+1:ANQ$=INKEY$:IF ANQ$="p" THEN GOTO 150 | + | |
- | 105 IF F<6THEN GOTO 40 ELSE F=0:C=130*RND(1):GOTO 30 | + | |
- | 110 J=P1:K=P2:FOR I=1 TO LNS:J=J+1:K=K+1:S=LNS:A5=S | + | |
- | 120 FOR I=1 TO LNS:J=J+1:K=K+1:A5=LNS:IF I=1 THEN DIM X3(S),X4(S),Y3(S),Y4(S) | + | |
- | 130 X3(I)=Q3(I):Y3(I)=Q4(I):X4(I)=Q5(I):Y4(I)=Q6(I):NEXT:RETURN | + | |
- | 140 LINE(X3(I),Y3(I))-(X4(I),Y4(I)),15:RETURN | + | |
- | 150 GOSUB55020:A=USR(0) | + | |
- | 160 MEE$=INKEY$:IF MEE$="" THEN 160 ELSE GOTO 105 | + | |
- | 55020 DT=&HEF00:DEFUSR=DT:RESTORE 55060 | + | |
- | 55030 FOR I=0 TO &HAB | + | |
- | 55040 READ DT$:POKE DT+I,VAL("&H"+DT$) | + | |
- | 55050 NEXT:RETURN '──▶ | + | |
- | 55060 DATA 21,00,20,22,AC,EF,21,91,EF,CD,87 | + | |
- | … … … | + | |
- | 55200 DATA 36,FF,1B,4E,0F,1B,41,1B,3C,0D,0A,FF | + | |
- | </code> | + | |
- | Версия программы без вывода на принтер: \\ {{.examples:0548-022.bas|}} \\ [[+tab|wmsxbpge>0548-022.bas]] | + | |
- | + | ||
- | Заметим, что вместо треугольников в алгоритме могут рассматриваться и четырёхугольники, при этом процедура деления лишь незначительно изменится. | + | |
- | + | ||
- | FIXME Разбиение четырёхугольника показано на рисунке: | + | |
- | {{anchor:pict_05_02}} <code> | + | |
- | ┌───────────────────────────────────────────────────┐ | + | |
- | │ │ | + | |
- | │ │ | + | |
- | │ │ | + | |
- | │ │ | + | |
- | │ │ | + | |
- | │ │ | + | |
- | │ │ | + | |
- | │ │ | + | |
- | └───────────────────────────────────────────────────┘ | + | |
- | </code> __//Рис. 2//__ | + | |
- | + | ||
- | Четыре ребра первоначального (закрашенного) четырёхугольника разбиваются с применением случайной функции, в результате чего вычисляются координаты точек P1, P2, P3 и P4. С помощью этих точек, а также случайной функции находится точка P5, и затем определяются четыре новых четырёхугольника. | + | |
- | + | ||
- | Таким образом, из начальной аппроксимации получается множество четырёхугольников. Наконец, производится удаление скрытых поверхностей и применяется соответствующая модель закраски. | + | |
- | </WRAP> | + | |
- | <WRAP>{{anchor:e0548-03}} __//Пример 3//__ [[bibliography#b14|[14]]]. | + | |
- | \\ {{.examples:0548-03.bas|}} \\ [[+tab|wmsxbpge>0548-03.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,1:SCREEN 2:DIM UB(424),LB(424) | + | |
- | 20 XC=320:YC=115:XR=175:ZR=120:H=40:W=.043:XA=107 | + | |
- | 30 FOR S=1 TO 424:UB(S)=0:LB(S)=1000:NEXT | + | |
- | 70 FOR Z=-ZR+1 TO ZR-1 STEP 5 | + | |
- | 80 XL=INT(XR*SQR(1-(Z*Z)/(ZR*ZR))+.5):X=-XL | + | |
- | 100 Y=H*SIN(W*SQR(X*X+Z*Z)):X1=X+XC+Z | + | |
- | 120 Y1=INT(199-(YC+Y+Z/2)+.5) | + | |
- | 130 FOR X=-XL+1 TO XL-1 | + | |
- | 140 Y=H*SIN(W*SQR(X*X+Z*Z)):X2=XC+X+Z | + | |
- | 160 Y2=INT(199-(YC+Y+Z/2)+.5) | + | |
- | 170 IF Y2>=LB(X2-XA) THEN 210 | + | |
- | 180 LB(X2-XA)=Y2 | + | |
- | 190 IF UB(X2-XA)=0 THEN UB(X2-XA)=Y2 | + | |
- | 200 GOTO 230 | + | |
- | 210 IF Y2<=UB(X2-XA) THEN 240 | + | |
- | 220 UB(X2-XA)=Y2 | + | |
- | 230 LINE((X1-80)/2,Y1)-((X2-80)/2,Y2) | + | |
- | 240 X1=X2:Y1=Y2 | + | |
- | 250 NEXT X,Z | + | |
- | 350 GOSUB 55020 '──▶ Вызов подпрограммы HARDCOPY.BAS | + | |
- | 360 A=USR(0) '──▶ | + | |
- | 370 END '"What you see is what you get!" | + | |
- | 55010 'Подпрограмма HARDCOPY.BAS | + | |
- | 55020 DT=&HEF00:DEFUSR=DT:RESTORE 55060 | + | |
- | 55030 FOR I=0 TO &HAB | + | |
- | 55040 READ DT$:POKE DT+I,VAL("&H"+DT$) | + | |
- | 55050 NEXT:RETURN '──▶ | + | |
- | 55060 DATA 21,00,20,22,AC,EF,21,91,EF,CD,87 | + | |
- | … … | + | |
- | 55200 DATA 36,FF,1B,4E,0F,1B,41,1B,3C,0D,0A,FF | + | |
- | </code> | + | |
- | Версия программы без вывода на принтер: \\ {{.examples:0548-032.bas|}} \\ [[+tab|wmsxbpge>0548-032.bas]] | + | |
- | </WRAP> | + | |
- | <WRAP>{{anchor:e0548-04}} __//Пример 4//__. | + | |
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | Для написания данного алгоритма требуются знание математики в объёме средней школы. | + | |
- | <WRAP rightalign> | + | |
- | —//Фраза из учебника по программированию// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | \\ {{.examples:0548-04.bas|}} \\ [[+tab|wmsxbpge>0548-04.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 2 DIM G(2000) 'Программа построения поверхностей! | + | |
- | 4 DEFFNZ(X,Y)=(60^(2/3)-(X^2+Y^2)^(1/3))^(3/2) 'L=0 | + | |
- | 5 'DEFFNZ(X,Y)=SQR(20^2-(SQR(X^2+Y^2)-35)^2) 'L=0 | + | |
- | 6 'DEFFNZ(X,Y)=10*COS(.24*SQR(X^2+Y^2)) 'L=0 | + | |
- | 7 'DEFFNZ(X,Y)=COS(.1*X)*COS(.1*Y)*10 'L=0 | + | |
- | 8 'DEFFNZ(X,Y)=25*COS(2.5E-03*X*Y) 'L=0.6, L=0 | + | |
- | 9 'DEFFNZ(X,Y)=75*EXP(-SQR(X^2+Y^2)^2/600) 'L=0 | + | |
- | 10 'DEFFNZ(X,Y)=64E-05*X*Y*(X*X-Y*Y)/SQR(X^2+Y^2)'L=1.4, 'L=2 | + | |
- | 12 'DEFFNZ(X,Y)=SIN(SQR(X^2+Y^2)/5)/SQR(X^2+Y^2)*175 'L=0 | + | |
- | 13 'DEFFNZ(X,Y)=30*COS(X*.05*EXP(-Y*.01)) 'L=.785, L=0 | + | |
- | 14 'DEFFNZ(X,Y)=(X^2-Y^2)/45 'L=.785, L=0 | + | |
- | 15 'DEFFNZ(X,Y)=20*COS((X+Y)/LOG(X^2+Y^4+.5)) 'L=.785, L=0 | + | |
- | 16 'DEFFNZ(X,Y)=30*COS((X+Y)/LOG(X^2+Y^2+.5)) 'L=.785, L=0 | + | |
- | 17 'DEFFNZ(X,Y)=10*SIN(.1*(ABS(X)+ABS(Y))) 'L=0 | + | |
- | 18 INPUT"Угол поворота";L!:N!=COS(L!):M!=SIN(L!) | + | |
- | 19 DEFFNF(X,Y)=FNZ(X*N!-Y*M!,X*M!+Y*N!) | + | |
- | 20 COLOR1,15,1:SCREEN2:A=SQR(2) | + | |
- | 30 FOR T=-90*A TO 90*A STEP A:W=-100:V=100:C=0:FOR I=-60 TO 60 STEP 6:J=I-T | + | |
- | 35 IF J>60 OR J<-60 THEN 70 | + | |
- | 37 'IF20^2<(SQR(I^2+J^2)-35)^2THEN 70 'Только для строки 5! | + | |
- | 40 'IF I=0 AND J=0 THEN 70 'Только для строк 10 и 12! | + | |
- | 43 IF (I^2+J^2)^(1/3)>60^(2/3)THEN70 'Только для строки 4! | + | |
- | 49 Y1%=INT(.70634*(I+J)+FNF(I,J)+.5) | + | |
- | 50 IFY1%>W THEN W=Y1%:C=C+1:IF C=1 THENG(INT(T)+220)=W:V=W:GOTO 60 ELSE 60 | + | |
- | 55 IF Y1%<V THEN V=Y1% ELSE 70 | + | |
- | 60 PSET(INT(120+.70634*(I-J)+.5),94-Y1%) | + | |
- | 70 NEXTI,T | + | |
- | 80 FOR T=-90*A TO 90*A STEP A:W=G(INT(T)+220) | + | |
- | 81 FOR J=-60 TO 60 STEP 6:I=J+T | + | |
- | 83 IF J=-60 THEN W=-100 ELSE W=G(INT(T)+220) | + | |
- | 85 IF I>60 OR I<-60 THEN 120 | + | |
- | 90 'IF20^2<(SQR(I^2+J^2)-35)^2THEN120 'Только для строки 5! | + | |
- | 91 'IF I=0ANDJ=0 THEN 120 'Только для строк 10 и 12! | + | |
- | 93 IF(I^2+J^2)^(1/3)>60^(2/3)THEN120 'Только для строки 4! | + | |
- | 99 Y1%=INT(.70634*(I+J)+FNF(I,J)+.5) | + | |
- | 100 IF Y1%>W THEN G(INT(T)+220)=Y1% ELSE 120 | + | |
- | 110 PSET(INT(120+.70634*(I-J)+.5),94-Y1%) | + | |
- | 120 NEXTJ,T | + | |
- | 150 GOSUB 55020 '──▶ Вызов подпрограммы HARDCOPY.BAS | + | |
- | 160 A=USR(0) '──▶ | + | |
- | 200 END | + | |
- | 55010 'Подпрограмма HARDCOPY.BAS | + | |
- | 55020 DT=&HEF00:DEFUSR=DT:RESTORE 55060 | + | |
- | 55030 FOR I=0 TO &HAB | + | |
- | 55040 READ DT$:POKE DT+I,VAL("&H"+DT$) | + | |
- | 55050 NEXT:RETURN '──▶ | + | |
- | 55060 DATA 21,00,20,22,AC,EF,21,91,EF,CD,87 | + | |
- | … … … | + | |
- | 55200 DATA 36,FF,1B,4E,0F,1B,41,1B,3C,0D,0A,FF | + | |
- | </code> | + | |
- | Версия программы без вывода на принтер: \\ {{.examples:0548-042.bas|}} \\ [[+tab|wmsxbpge>0548-042.bas]] | + | |
- | </WRAP> | + | |
- | + | ||
- | <WRAP>{{anchor:e0548-05}} __//Пример 5//__ [[bibliography#b16|[16]]]. | + | |
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | Рисуют головой, а не руками. | + | |
- | <WRAP rightalign> | + | |
- | —//Микельанджело Буонарроти// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | \\ {{.examples:0548-05.bas|}} \\ [[+tab|wmsxbpge>0548-05.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 15 COLOR 1,15,8:CLS:PRINT"Для вывода полученного графика на принтер на жмите клавишу ESC":PRINT | + | |
- | 20 PRINT "1. Построение графика функции в декартовых координатах":PRINT "2. Построение кривых в полярных координатах":INPUT"Режим (1,2)";SW: ON SW GOTO 110,390 | + | |
- | 50 ' ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ | + | |
- | 70 ' ∗ Построение графика функции в декартовых координатах∗ | + | |
- | 90 ' ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ | + | |
- | 110 SX=255:SY=191:HY=SY/2 'Форматирование экрана дисплея! | + | |
- | 120 CLS:DEFFNA(X)=EXP(-ABS(X))*SIN(1/X) | + | |
- | 130 PRINT"Область изменения X:" | + | |
- | 140 INPUT"min-значение:";A:INPUT"max-значение:";B:PRINT | + | |
- | 160 IF A>=B THEN PRINT"Ошибка!":GOTO130 | + | |
- | 170 INPUT"Количество точек на единицу площади экрана";W | + | |
- | 180 C=(B-A)/100:M=1E-30:SCREEN2 'C-шаг | + | |
- | 200 FORX=ATOBSTEPC:IFX=0THENNEXT'Учет области определения! | + | |
- | 220 Y=ABS(FNA(X)):IF M<Y THEN M=Y:NEXT ELSE NEXT | + | |
- | 240 C=C/W:FORX=A TO B STEPC:IF X=0 THEN NEXT ELSEY=-FNA(X) | + | |
- | 260 U=SX*(X-A)/(B-A):V=HY+HY*Y/M:IF V<0 OR V>SY THEN NEXT | + | |
- | 290 PSET(U,V),1:NEXT:GOTO 800 | + | |
- | 320 ' ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ | + | |
- | 340 ' ∗ Кривые в полярных координатах ∗ | + | |
- | 370 ' ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ | + | |
- | 390 SX=255:SY=191:RAT=.86:HY=SY/2:HX=SX/2 | + | |
- | 410 CLS:DEFFNA(Z)=COS(8*Z) | + | |
- | 420 ?"X=COS(A·Z)COS(8·Z)":?"Y=SIN(B·Z)COS(8·Z)":PRINT | + | |
- | 440 INPUT"A=";A:INPUT"B=";B | + | |
- | 450 M=1E-30:FOR Z=0 TO 8*ATN(1):R=ABS(FNA(Z)) | + | |
- | 470 IF M<R THEN M=R+.1:NEXT ELSE NEXT | + | |
- | 480 SCREEN2:FOR Z=0 TO 24*ATN(1) STEP.01 | + | |
- | 500 R=-FNA(Z):U=HX+HY*RAT*COS(A*Z)*R/M:IFU<0ORU>SXTHENNEXT | + | |
- | 530 V=HY+HY*SIN(B*Z)*R/M:IF V<0 OR V>SY THEN NEXT | + | |
- | 550 PSET(U,V),1:NEXT | + | |
- | 800 PIT$=INKEY$:IF PIT$<>CHR$(27) THEN 800 | + | |
- | 830 GOSUB 850'──▶ | + | |
- | 840 A=USR(0):END '───────▶ | + | |
- | 850 DT=&HEF00:DEFUSR=DT:RESTORE 890 | + | |
- | 860 FOR I=0 TO &HAB:READ DT$:POKE DT+I,VAL("&H"+DT$) | + | |
- | 880 NEXT:RETURN '──▶ | + | |
- | 890 DATA 21,00,20,22,AC,EF,21,91,EF,CD,87 | + | |
- | … … … | + | |
- | 1030 DATA 36,FF,1B,4E,0F,1B,41,1B,3C,0D,0A,FF | + | |
- | </code> | + | |
- | Версия программы без вывода на принтер: \\ {{.examples:0548-052.bas|}} \\ [[+tab|wmsxbpge>0548-052.bas]] | + | |
- | </WRAP> | + | |
- | + | ||
- | <WRAP>{{anchor:e0548-06}} __//Пример 6//__. Обратите внимание на подпрограмму вывода на принтер она написана на "чистом" [[msx:basic:]] ! | + | |
- | \\ {{.examples:0548-06.bas|}} \\ [[+tab|wmsxbpge>0548-06.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 20 SCREEN 2:COLOR 13,1,1:CLS | + | |
- | 40 CIRCLE (120,96),88:CIRCLE (120,96),88,,,,8/11 | + | |
- | 60 CIRCLE (120,96),88,,,,5/11:CIRCLE (120,96),88,,,,2/11 | + | |
- | 80 CIRCLE (120,96),88,,,,11/8:CIRCLE (120,96),88,,,,11/5 | + | |
- | 100 CIRCLE (120,96),88,,,,11/2 | + | |
- | 110 PAINT (86,27):PAINT (121,26):PAINT (154,27):PAINT (51,65) | + | |
- | 150 PAINT (94,50):PAINT (141,50):PAINT (187,61):PAINT (67,76) | + | |
- | 190 PAINT (121,69):PAINT (169,71):PAINT (44,95):PAINT (88,102) | + | |
- | 230 PAINT (150,97):PAINT (193,97):PAINT (68,121):PAINT (121,120) | + | |
- | 270 PAINT (169,119):PAINT (57,133):PAINT (95,144):PAINT (142,143) | + | |
- | 310 PAINT (187,129):PAINT (85,162):PAINT (122,167):PAINT (151,164) | + | |
- | 350 LINE (32,8)-(208,184),,B | + | |
- | 360 PAINT(41,24):PAINT(195,22):PAINT(43,171):PAINT(193,170) | + | |
- | 400 COLOR 7:LINE (212,4)-(27,188),,B:LINE (214,3)-(24,189),,B | + | |
- | 430 GOSUB 1000 '──▶ | + | |
- | 440 COLOR 15,4,7:END | + | |
- | 1000 ' ∗∗∗∗∗∗∗∗∗ (C) by TOSHIBA ∗∗∗∗∗∗∗∗∗ | + | |
- | 1040 DEFINT A-Z | + | |
- | 1050 SMO=PEEK(&HFCAF) | + | |
- | 1060 IF SMO<>2 THEN BEEP:RETURN | + | |
- | 1070 BAK=PEEK(&HF3EA) | + | |
- | 1080 COL=BASE(11) | + | |
- | 1090 CGP=BASE(12) | + | |
- | 1100 LPRINT CHR$(27);"T16";CHR$(27);"E";CHR$(14); | + | |
- | 1110 LPRINT CHR$(27);">";:POKE &HF418,1 | + | |
- | 1120 FOR YIN=1 TO 24 | + | |
- | 1130 LPRINT CHR$(27);"S0256"; | + | |
- | 1140 FOR XIN=1 TO 32 | + | |
- | 1150 FOR CLR=1 TO 8 | + | |
- | 1160 DT(CLR)=0 | + | |
- | 1170 NEXT CLR | + | |
- | 1180 FOR BIN=1 TO 8 | + | |
- | 1190 DT=VPEEK(CGP):CGP=CGP+1 | + | |
- | 1200 C0=VPEEK(COL):COL=COL+1 | + | |
- | 1210 C1=(C0 AND &HF0)/&H10 | + | |
- | 1220 C0=C0 AND &HF | + | |
- | 1230 IF C0<>BAK AND C1<>BAK THEN DT=&HFF:GOTO 1260 | + | |
- | 1240 IF C0=BAK AND C1=BAK THEN DT=0:GOTO 1260 | + | |
- | 1250 IF C1=BAK THEN DT=DT XOR &HFF | + | |
- | 1260 DT$=BIN$(DT+256) | + | |
- | 1270 FOR CAL=1 TO 8 | + | |
- | 1280 DT(CAL)=DT(CAL)+VAL(MID$(DT$,CAL+1,1))*(2^(BIN-1)) | + | |
- | 1290 NEXT CAL | + | |
- | 1300 NEXT BIN | + | |
- | 1310 FOR LOT=1 TO 8 | + | |
- | 1320 LPRINT CHR$(DT(LOT)); | + | |
- | 1330 NEXT LOT | + | |
- | 1340 NEXT XIN:LPRINT | + | |
- | 1350 NEXT YIN:LPRINT CHR$(27);"A";CHR$(27);"N"; | + | |
- | 1360 LPRINT CHR$(15);CHR$(27);"<":POKE &HF418,0 | + | |
- | 1370 RETURN '──▶ | + | |
- | </code> | + | |
- | Версия программы без вывода на принтер: \\ {{.examples:0548-062.bas|}} \\ [[+tab|wmsxbpge>0548-062.bas]] | + | |
- | </WRAP> | + | |
- | + | ||
- | {{anchor:draw}} | + | |
- | ===== V.5. Графический макроязык GML ===== | + | |
- | + | ||
- | В [[msx:basic:]] входит оператор ''DRAW'', который позволяет изображать на экране дисплея рисунки, составленные из различных комбинаций прямых линий. Начиная с последней высеченной на экране точки, с помощью оператора ''DRAW'' можно провести линию любой длины и в любом из 8 заданных направлений (см. [[#pict_05_02|рис. 2]]). После этого можно провести ещё одну линию, снова любой длины и в любом из тех же восьми направлений и т.д. Каждая проводимая линия может быть окрашена в любой из 15 допустимых цветов. Кроме того, можно проводить отрезок, соединяющий текущую точку с любой точкой, заданной абсолютными или относительными координатами. Можно также увеличивать или уменьшать весь выводимый рисунок и поворачивать его на 90°, 180° или 270°. | + | |
- | + | ||
- | Оператор ''DRAW'' — мощный оператор, являющийся по существу настоящим мини–языком в [[msx:basic:]]. Этот язык называется графическим //макроязыком// GML("Graphics Macro Language"). | + | |
- | + | ||
- | Записывается оператор в виде | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | DRAW β | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''DRAW''("to draw" — "рисовать") — служебное слово; | + | |
- | * β — строковое выражение, значение которого определяет рисунок. | + | |
- | Значение β составляется из последовательности команд GML. Обратите внимание на то, что значение параметра β всегда заключено в кавычки, поскольку это обычная строка [[msx:basic:]], состоящая из команд языка GML, констант и строковых переменных. Длина β не должна превышать 255 символов. Для удобства чтения текста программы команды можно разделять пробелами. Каждая команда GML представлена одиночной ключевой буквой, за которой следует один или два числовых параметра (аргумента). Последние, как правило, задаются | + | |
- | целыми числами. | + | |
- | + | ||
- | Например: | + | |
- | <code> | + | |
- | C 5 | + | |
- | ▲ ▲ | + | |
- | │ │ | + | |
- | Ключевая буква Аргумент | + | |
- | </code> | + | |
- | <code> | + | |
- | M 15 , 10 | + | |
- | ▲ ▲ ▲ | + | |
- | │ │ │ | + | |
- | Ключевая буква Аргументы | + | |
- | </code> | + | |
- | Команды GML в основном предназначены для перемещения графического курсора из одних точек экрана в другие с одновременным вычерчиванием соединяющих их отрезков. Однако, они могут модифицироваться следующим образом. | + | |
- | - Перед командой перемещения ставится //префикс// (приставка) B. Тогда положение курсора изменяется, но линия не рисуется. | + | |
- | - Перед командой перемещения ставится префикс N.Тогда курсор возвращается в ту точку, в которой он находился до выполнения данной команды. | + | |
- | + | ||
- | Приведём список команд GML. Работая с командами, Вы должны чётко представлять себе: | + | |
- | * какова текущая позиция графического курсора; | + | |
- | * в какую позицию Вы собираетесь его перевести; | + | |
- | * хотите ли Вы провести линию при его перемещении. | + | |
- | + | ||
- | - <WRAP>Команда перемещения βn служит для перемещения графического курсора по направлению β с рисованием прямой линии. | + | |
- | Здесь: β — указатель одного из 8 возможных направлений: β ∈ {R,E,U,H,L,G,D,F}, причём углы между смежными направлениями равны 45°. | + | |
- | + | ||
- | Внимательно изучите рисунок… | + | |
- | {{anchor:pict_05_03}} <code> | + | |
- | H U E | + | |
- | ◤ ▲ ◥ | + | |
- | ╲ │ ╱ | + | |
- | L ◀── ──▶ R | + | |
- | ╱ │ ╲ | + | |
- | ◣ ▼ ◢ | + | |
- | G D F | + | |
- | </code> __//Рис. 3//__ | + | |
- | * "Up" — "вверх" | + | |
- | * "Left" — "левый" | + | |
- | * "Right" — "правый" | + | |
- | * "Down" — "вниз" | + | |
- | + | ||
- | n — целое положительное число, задающее величину смещения курсора (выраженную в точках экрана). | + | |
- | При выполнении команды курсор смещается от своего текущего положения на n точек по направлению β, рисуя линию. | + | |
- | + | ||
- | Например, оператор ''%%DRAW"L10 U10 R10 D10"%%'' позволяет начертить линию от последней упомянутой точки на 10 точек влево, на 10 точек вверх, на 10 точек вправо и на 10 точек вниз, т.е. квадрат (интересно, что диагональ данного квадрата — также 10 точек). | + | |
- | + | ||
- | __//Пример//__. | + | |
- | {{anchor:e055-01}} {{.examples:055-01.bas|}} \\ [[+tab|wmsxbpge>055-01.bas]]<code> | + | |
- | 10 COLOR 1,15,8:SCREEN 2:PSET(80,100) | + | |
- | 20 DRAW"c13 s12 u10 e10 r10 f10 d10 g10 l10 h10" | + | |
- | 30 GOTO 30 | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | - <WRAP> Команда перемещения ''MX,Y'' ("to Move" — "двигаться")позволяет переместить курсор из текущего положения в точку с координатами (X,Y). Здесь X,Y — абсолютные координаты. | + | |
- | + | ||
- | Например, оператор ''%%DRAW"M160,100"%%'' перемещает графический курсор в точку (160,100), оставляя при этом след в виде закрашенных точек. Оператор ''%%DRAW"BM160,100"%%'' перемещает графический курсор в ту же позицию (160,100), но префикс B делает это перемещение невидимым! | + | |
- | + | ||
- | __//Пример//__ [[bibliography#b6|[6]]]. Изображение картины взрыва. | + | |
- | {{anchor:e055-02}} {{.examples:055-02.bas|}} \\ [[+tab|wmsxbpge>055-02.bas]]<code> | + | |
- | 5 COLOR 1,15,4:SCREEN2:LINE(105,65)-(225,146),1,BF | + | |
- | 10 DRAW "c8bm190,82m178,91m178,73m163,91m148,65m148,85m133,79m139,94m112,94m133,109m106,118m133,118m127,124m139,121m139,130m145,124m151,133m160,124m166,139m172,124m196,145m184,121m223,133m193,115m217,109m196,106m205,97m187,97m190,82" | + | |
- | 20 PAINT(130,100),8:A$=INPUT$(1) | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | - <WRAP> Команда перемещения ''М±X,±Y'' служит для смещения курсора из текущего положения на ±Х точек по абсциссе и ±Y точек по ординате (разумеется, указание знака "+" или "-"обязательно!). Здесь ''±X,±Y'' - относительные координаты. | + | |
- | + | ||
- | Например, оператор ''%%DRAW"M-10,+40"%%'' перемещает графический курсор из последней упомянутой точки в точку, отстоящую от последней упомянутой точки на 10 точек влево и на 40 точек вниз, с рисованием прямой линии. | + | |
- | + | ||
- | Отметим, что команда ''M±X,Y'' действует точно так же, как команда ''M±X,+Y'', а команда ''MX,+Y'' действует как команда ''MX,Y''. | + | |
- | + | ||
- | Например, оператор ''%%DRAW"M-10,40"%%'' перемещает графический курсор из последней упомянутой в Вашей программе точки на 10 точек влево и на 40 вниз, т.е. его действие совпадает с действием оператора ''%%DRAW"M-10,+40"%%''. | + | |
- | + | ||
- | __//Пример//__. | + | |
- | {{anchor:e055-03}} {{.examples:055-03.bas|}} \\ [[+tab|wmsxbpge>055-03.bas]]<code> | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN 2:PSET(100,85) | + | |
- | 20 DRAW"a1 s12 c13 nu10 ne10 nr10 nf10 nd10 ng10 nl10 h10 m+0,30 a2": PSET (190,95):DRAW"s8 c13 nu10 ne10 nr10 nf10 nd10 ng10 nl10 h10 m+0,30" | + | |
- | 30 GOTO 30 | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | - Команда ''Cp'' ("Color" — "цвет") позволяет определить цвет вычерчиваемых отрезков (p=0,1,2,…,15 — код цвета). Действует команда до нового назначения цвета (по умолчанию p — код цвета изображения). Отметим, что задание цвета командой C в операторе ''DRAW'' не меняет цвет остальной части изображения! | + | |
- | - Команда ''Sm'' ("Size" — "размер") задаёт масштабный множитель m, (1≤m≤255). При выполнении команды Sm числовые параметры всех последующих команд перемещения приобретают масштабный множитель m/4 (например, при m=8 m/4=2). Действует команда Sm на все команды ''DRAW'', не содержащие префикса "B", до нового назначения. | + | |
- | - <WRAP>Команда ''At'' ("Angle" — "угол") служит для поворота изображения вокруг точки, с которой начиналось рисование, на 90·t° против часовой стрелки (t может принимать значения 0, 1, 2, 3). Действует команда At на все последующие команды ''DRAW'' до нового назначения, причём она должна предшествовать процессу построения той фигуры, которую надо повернуть. Учтите, что поворот на 0°, 90°, 180° или 270° означает поворот против часовой стрелки на соответствующий угол от направления оси X, т.е. команда A определяет абсолютный угол поворота! | + | |
- | + | ||
- | Заметим, что угол поворота A и масштабный множитель S запоминаются в системной области памяти компьютера и сохраняются там даже после уничтожения программы пользователя, поэтому будьте осторожны при использовании принципа умолчания! | + | |
- | + | ||
- | Рекомендуем перед набором на клавиатуре программ, содержащих операторы графики, нажать клавишу <key>RESET</key>(на задней панели компьютера [[msx:msx_1]] или на передней панели компьютера [[msx:msx_2]]), а затем клавиши <key>CTRL+STOP</key>! | + | |
- | Проверить значения параметров команд S и A в памяти можно в непосредственном режиме при помощи команд: | + | |
- | * ''PRINT PEEK(&HFCBD)'' — Значение угла поворота! | + | |
- | * ''PRINT PEEK(&HFCBC)'' — Значение масштабного множителя! | + | |
- | + | ||
- | Внимание! Действие команд поворота А и изменения масштаба S не распространяется на команду M, в которой используются абсолютные координаты! | + | |
- | </WRAP> | + | |
- | - <WRAP> Команда ''Xα;'' позволяет интерпретировать значение строковой переменной α как последовательность команд GML (знак «;» обязателен!). Более того, строка команд GML, вызванная командой X, может сама содержать команды X. Ясно, что при помощи этой команды можно организовать вызов графических "подпрограмм"! | + | |
- | + | ||
- | Там, где в команде GML в качестве параметров (аргументов) используются числовые константы, можно указывать имена простых числовых переменных α, в том числе и имена элементов массивов (индекс элемента массива может быть переменной или константой, но не выражением!). Но α при этом следует записывать в форме ''=α;'' (символы "=" и «;» обязательно должны присутствовать!). | + | |
- | {{anchor:e055-04}} {{.examples:055-04.bas|}} \\ [[+tab|wmsxbpge>055-04.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 2:DRAW "bm125,100" | + | |
- | 30 FOR I=4 TO 240 STEP 12:DRAW "s=i; bu r d2 l2 u2 r b d":NEXT | + | |
- | 60 GOTO 60 | + | |
- | </code> | + | |
- | Запомните, что при переходе в другой графический режим координаты графического курсора, масштаб, угол поворота и цвет изображения остаются прежними. | + | |
- | </WRAP> | + | |
- | + | ||
- | __//Примеры//__. | + | |
- | * {{anchor:e055-11}} 1) \\ {{.examples:055-11.bas|}} \\ [[+tab|wmsxbpge>055-11.bas]]<code> | + | |
- | Ok | + | |
- | 5 '"Цветок". | + | |
- | 10 COLOR 1,15,8:SCREEN 2:FOR K=0 TO 3:L=4*K | + | |
- | 30 DRAW"a=k; s4 c13 bm128,85 e10 r10 f10 d10 g10 l10 h10 u10":NEXT:A$=INPUT$(1) | + | |
- | </code> | + | |
- | * {{anchor:e055-12}} 2) \\ {{.examples:055-12.bas|}} \\ [[+tab|wmsxbpge>055-12.bas]]<code> | + | |
- | Ok | + | |
- | 5 '"Паркет". | + | |
- | 10 COLOR 1,15,8:SCREEN 2 | + | |
- | 20 FOR J=25 TO 160 STEP 40:FOR I=18 TO 180 STEP 40 | + | |
- | 40 DRAW"s8 bm=i;,=j; e10 r10 f10 d10 g10 l10 h10 u10" | + | |
- | 50 NEXTI,J:A$=INPUT$(1) | + | |
- | </code> | + | |
- | * {{anchor:e055-13}} 3) \\ {{.examples:055-13.bas|}} \\ [[+tab|wmsxbpge>055-13.bas]]<code> | + | |
- | Ok | + | |
- | 10 '"Акробаты" | + | |
- | 20 CLS:INPUT"Введите 0,1,2 или 3";T:IF T<>0 AND T<>1 AND T<>2 AND T<>3 THEN 20 | + | |
- | 40 IF T=0 THEN X=10:O=100 ELSE IF T=1 THEN X=90:O=200 | + | |
- | 50 IF T=2 THEN X=50:O=180 ELSE IF T=3 THEN X=10:O=150 | + | |
- | 60 COLOR 1,15,8:SCREEN 2 | + | |
- | 80 PSET(X,100):DRAW"c1s4a=t;r8u20e10r15f10d20r8u2l3u18h15u25f15u30l5d18h8l3g8e1f1h8f7e7l2u3h2l6h3u10e3r8f3d5c15l2c1l3c15l4c1l3r3c15r3d1c1d3c15d1c1r2l5c15e3r6u2c1d5g3l8g2d3l5g8u18l5d30e15d25r15l15g15d18l3d2" | + | |
- | 90 IF X<O THEN X=X+73:GOTO 80 ELSE W$=INPUT$(1):GOTO 20 | + | |
- | </code> | + | |
- | * {{anchor:e055-14}} 4) \\ {{.examples:055-14.bas|}} \\ [[+tab|wmsxbpge>055-14.bas]]<code> | + | |
- | Ok | + | |
- | 10 CLS:COLOR 1,15,8:SCREEN 2 '"Блоха" | + | |
- | 30 BDY$="BM=H;,=V; L20 U20 R20 D20 F10 D10 R2" | + | |
- | 40 LEG$="BM=H;,=V; G10 D10 L2":A1$="BM=H;,=V; L10 D10 L2" | + | |
- | 60 A2$="BM=H;,=V; E10 H10 R2":NECK$="BM=H;,=V; U4" | + | |
- | 80 HEAD$="BM=H;,=V; R10 H6 G6":F1$="BM=H;,=V; H6" | + | |
- | 100 F2$="BM=H;,=V; E6":DRAW "C2":H=140:V=95:DRAW "XBDY$;" | + | |
- | 230 H=H-20:DRAW "XLEG$;":V=V-20:DRAW "XA1$;":H=H+20 | + | |
- | 280 DRAW "XA2$;":H=H-10:DRAW "XNECK$;":H=H-5:V=V-4 | + | |
- | 320 DRAW "XHEAD$;":V=V-3:DRAW "XF1$;":H=H+7:DRAW "XF2$;" | + | |
- | 370 GOTO 370 | + | |
- | </code> | + | |
- | * {{anchor:e055-15}} 5) Цифры "нестандартных" размеров на графическом экране. \\ {{.examples:055-15.bas|}} \\ [[+tab|wmsxbpge>055-15.bas]]<code> | + | |
- | Ok | + | |
- | 5 INPUT"Масштаб";I:J=INT(I)*4 '0≤I≤5 | + | |
- | 10 SCREEN 2:PSET(3,10):DRAW"s=j;" | + | |
- | 20 DRAW"e1d4l1r2be4":DRAW"r1f1d1g2r2be4" | + | |
- | 40 DRAW"r1f1g1f1g1l1be4":DRAW"br2d2r2nr1nu2d2be4" | + | |
- | 60 DRAW"nr2d2r2d2l2be4":DRAW"br2nr2d4r2u2l2be4" | + | |
- | 80 DRAW"bf2r2d1g1d2be4":DRAW"bf1e1r1f1g1l1h1f1g1f1r1e1h1be4":DRAW"bd2nr2d2r2nu2d2l2":B$=INPUT$(1) | + | |
- | </code> | + | |
- | * {{anchor:e055-16}} 6) Рисунок чёрного и белого домов [[bibliography#b1|[1]]]. \\ {{.examples:055-16.bas|}} \\ [[+tab|wmsxbpge>055-16.bas]]<code> | + | |
- | Ok | + | |
- | 10 COLOR,5:SCREEN2:BOX$="R20 U20 L20 D20":HAT$="E14 F14 BL20":DO$="R5 U10 L5 D10":WINDOW$="R4 U4 L4 D4":HOUSE$="XBOX$; BR4 XDO$; BM+10,-5 XWINDOW$;BM-18,-12 XHAT$;" | + | |
- | 20 DRAW"BM20,20 C1 S2 XHOUSE$;BM100,100 S6 C15 XHOUSE$;" | + | |
- | 30 GOTO 30 | + | |
- | </code> | + | |
- | * <WRAP>{{anchor:e055-17}} 7) \\ {{.examples:055-17.bas|}} \\ [[+tab|wmsxbpge>055-17.bas]]<code> | + | |
- | Ok | + | |
- | 10 CLS:KEYOFF:COLOR 1,15,8:SCREEN2:PSET(125,95) | + | |
- | 40 HX$="u25 e15 r25 d25 g15 l25" 'Исходный шестиугольник | + | |
- | 60 FOR SCALE=9 TO 1 STEP(-1) | + | |
- | 70 S$="s"+STR$(SCALE):C$="c"+STR$(SCALEMOD8) | + | |
- | 110 FOR ROTATE=0 TO 3:R$="a"+STR$(ROTATE):SHAPE$="xs$;xc$;xr$;xhx$;":DRAW SHAPE$:NEXT ROTATE:NEXT SCALE | + | |
- | 160 Z$=INPUT$(1)'Ожидание нажатия любой(!) клавиши для окончания работы. Данный пример приведен в [6]. | + | |
- | </code> | + | |
- | В процессе работы эта программа выводит на экран дисплея один и тот же шестиугольник, изменяя с помощью команды A угол его поворота, с помощью команды C его цвет, а с помощью команды S — размер. В программе иллюстрируется также использование команды X, позволяющей в процессе выполнения некоторой строки команд "обращаться" к другим командным строкам. Во вложенных циклах ''FOR…NEXT'' изменяются масштаб, цвет и угол поворота шестиугольника. | + | |
- | </WRAP> | + | |
- | + | ||
- | Перечислим ещё раз основные //плюсы// оператора ''DRAW''. | + | |
- | + | ||
- | Во–первых, он является самым компактным способом кодирования любой фигуры. Во–вторых, он имеет средства для "сохранения" графического курсора в некоторой точке экрана даже после проведения отрезка, выходящего из этой точки. В–третьих, нарисованная фигура может быть увеличена (уменьшена) с помощью команды S и повёрнута налево (направо) с помощью команды А. В–четвёртых, оператор ''DRAW'' позволяет вычерчивать отдельные детали какой–либо фигуры (например, руки, ноги, шляпу), а затем неоднократно воспроизводить их в различных сочетаниях. | + | |
- | + | ||
- | Отметим, что с помощью оператора ''DRAW'' нельзя чертить отрезки прямых с произвольным углом наклона, например, к оси X, однако, взгляните (A–сторона, N–количество сторон правильного многоугольника)… | + | |
- | {{anchor:e055-05}} {{.examples:055-05.bas|}} \\ [[+tab|wmsxbpge>055-05.bas]]<code> | + | |
- | 10 INPUT A,N:COLOR 1,15,8:SCREEN 2:PSET(80,90) | + | |
- | 20 FOR ANGLE=0 TO 8*ATN(1) STEP 8*ATN(1)/N:X=A*SIN(ANGLE):Y=A*COS(ANGLE):DRAW"M+=X;,+=Y;":NEXT:P$=INPUT$(1) | + | |
- | </code> | + | |
- | На экране дисплея — "окружность"! Укажите её "радиус"?! | + | |
- | + | ||
- | Заметим, что команды GML как и операторы графики "работают" в воображаемом пространстве, координаты которого принадлежат отрезку [-32768,32767]. Однако, на экране дисплея будет видна только та часть рисунка, для которой 0≤X≤255 и 0≤Y≤191. | + | |
- | + | ||
- | __//Пример//__. Как уже говорилось, командная строка, вызванная командой X, может сама содержать команды X. Используем этот факт для создания нестандартного, собственного "алфавита" [[bibliography#b4|[4]]]. Значение каждого элемента массива A$(n) задаёт при помощи языка GML рисование символа с десятичным кодом ASCII, равным n. Для иллюстрации в программе показано формирование букв "К","Л","А" и "С". Разумеется, допускается поворот и увеличение "символов". | + | |
- | {{anchor:e055-06}} {{.examples:055-06.bas|}} \\ [[+tab|wmsxbpge>055-06.bas]]<code> | + | |
- | 20 '(X,Y) - координаты левого верхнего угла первой буквы текста;S - размер букв; L - расстояние между буквами; | + | |
- | 60 COLOR 1,15,8:SCREEN 2:CLEAR 1000:GOSUB 150'──▶ | + | |
- | 80 X=70:Y=80:S=2:L=9:S=4*S | + | |
- | 90 TE$="КЛАСС":P$="s=S;bm=X;,=Y;":GOSUB 110'──▶ | + | |
- | 100 GOTO 100 | + | |
- | 110 FOR K=1 TO LEN(TE$):Z$=MID$(STR$(ASC(MID$(TE$,K))),2) | + | |
- | 130 P$=P$+"XA$("+Z$+");"+"BR=L;":NEXT:DRAW"XP$;":RETURN | + | |
- | 150 DIMA$(255):A$(32)="BR1":A$(225)="BD6U4E2F2D4U2L4BE4BR1" | + | |
- | 180 A$(236)="BD6E1U3E2R1D6U6BR2":A$(235)="D6U3R1F3H3E3BR1" | + | |
- | 200 A$(243)="BR1R2F1BD4G1L2H1U4E1BR4":RETURN'──▶ | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:sprites}} | + | |
- | ===== V.6. Спрайты ===== | + | |
- | FIXME | + | |
- | + | ||
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | Мультипликация является единственным подлинным искусством в настоящее время, потому что в ней, и только в ней, художник абсолютно свободен в своей фантазии и может делать все, что угодно. | + | |
- | <WRAP rightalign> | + | |
- | —//Ч.Чаплин// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | "Оживление" изображения при мультипликации основано на использовании набора обычных "неподвижных" картинок, каждая последующая из которых очень незначительно отличается от предыдущей. Если последовательно просматривать эти картинки, очень быстро сменяя одну другой, то отдельные картинки будут сливаться друг с другом, создавая впечатление непрерывного плавного движения. Далее с помощью кинокамеры снимают все отдельные картинки, нарисованные от руки или полученные каким–либо другим способом. После этого с помощью кинопроектора можно показывать мультфильм на экране. | + | |
- | + | ||
- | Для синтеза динамического изображения на MSX–компьютере можно также использовать кинокамеру и описанную выше технику: с помощью операторов ''PSET'', ''LINE'', ''CIRCLE'', ''PAINT'' и ''DRAW'' можно рисовать на экране дисплея отдельные картинки и по очереди фотографировать их кинокамерой. Однако для MSX–компьютера существует более удобный подход к "оживлению" изображения, позволяющий обойтись и без кинокамеры, и без проектора, используя лишь возможности языка программирования [[msx:basic:]]. | + | |
- | + | ||
- | Для того, чтобы создать впечатление движущегося по экрану объекта, следует каждый раз сначала стирать его изображение с экрана, а затем снова выводить его на экран в новом месте. При этом местоположение объекта при каждом последующем выводе должно очень незначительно отличаться от его место положения при предыдущем выводе, иначе вместо плавного перемещения будет лишь видно, как изображение объекта исчезнет в одном месте, а затем появляется в другом. Эту идею нетрудно реализовать с помощью циклической программы, использующей рассмотренные нами ранее графические операторы. Однако, для того, чтобы движение изображения не было "дёргающимся", отдельные кадры должны очень быстро сменять друг друга. Используя только базовые операторы графики, это требование выполнить очень трудно. Смотрите! | + | |
- | + | ||
- | __//Пример//__[[bibliography#b14|[14]]]. Бегущий человечек. | + | |
- | {{anchor:e056-01}} {{.examples:056-01.bas|}} \\ [[+tab|wmsxbpge>056-01.bas]]<code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 20 DIM X1(15),Y1(15),X2(15),Y2(15):XM=255 | + | |
- | 40 FOR K=1 TO13:READ X1(K),Y1(K):NEXT | + | |
- | 70 FOR K=1 TO 12:READ X2(K),Y2(K):NEXT | + | |
- | 100 XO=0 | + | |
- | 110 COLOR15:SCREEN2 | + | |
- | 120 IF XO+X1(12)>XM THEN 740 | + | |
- | 130 GOSUB210:GOSUB330 'Рисуем, а затем стираем положение 1 | + | |
- | 150 XO=XO+15 | + | |
- | 160 IF XO+X2(11)>XM THEN 740 | + | |
- | 170 GOSUB 460:GOSUB 570 'Рисуем,а затем стираем положение 2 | + | |
- | 190 XO=XO+20 | + | |
- | 200 GOTO 130 | + | |
- | 210 '¤¤¤¤¤ Рисунок первой позиции ¤¤¤¤¤ | + | |
- | 230 FORK=1TO2:LINE(XO+X2(K),Y2(K))-(XO+X2(K+1),Y2(K+1)):NEXT | + | |
- | 260 LINE (XO+X2(4),Y2(4))-(XO+X2(5),Y2(5)) | + | |
- | 270 LINE (XO+X2(5),Y2(5))-(XO+X2(6),Y2(6)) | + | |
- | 280 FORK=7TO10:LINE(XO+X2(K),Y2(K))-(XO+X2(K+1),Y2(K+1)) | + | |
- | 300 NEXTK | + | |
- | 310 CIRCLE(XO+X2(12),Y2(12)),10:RETURN'──▶ | + | |
- | 330 '¤¤¤¤¤ Уничтожение первой позиции ¤¤¤¤¤ | + | |
- | 350 FOR K=1 TO2:LINE (XO+X2(K),Y2(K))-(XO+X2(K+1),Y2(K+1)),4 | + | |
- | 370 NEXT K | + | |
- | 380 LINE (XO+X2(4),Y2(4))-(XO+X2(5),Y2(5)),4 | + | |
- | 390 LINE (XO+X2(5),Y2(5))-(XO+X2(6),Y2(6)),4 | + | |
- | 400 FOR K=7 TO10:LINE(XO+X2(K),Y2(K))-(XO+X2(K+1),Y2(K+1)),4 | + | |
- | 420 NEXTK:CIRCLE(XO+X2(12),Y2(12)),10,4:RETURN | + | |
- | 460 '¤¤¤¤¤ Рисунок второй позиции ¤¤¤¤¤ | + | |
- | 470 FORK=1TO3:LINE(XO+X1(K),Y1(K))-(XO+X1(K+1),Y1(K+1)):NEXT | + | |
- | 500 LINE (XO+X1(5),Y1(5))-(XO+X1(6),Y1(6)) | + | |
- | 510 LINE (XO+X1(6),Y1(6))-(XO+X1(7),Y1(7)) | + | |
- | 520 FORK=8TO11:LINE(XO+X1(K),Y1(K))-(XO+X1(K+1),Y1(K+1)) | + | |
- | 540 NEXT K | + | |
- | 550 CIRCLE(XO+X1(13),Y1(13)),10:RETURN '──▶ | + | |
- | 570 '¤¤¤¤¤ Уничтожение второй позиции ¤¤¤¤¤ | + | |
- | 590 FOR K=1 TO3:LINE(XO+X1(K),Y1(K))-(XO+X1(K+1),Y1(K+1)),4 | + | |
- | 610 NEXTK | + | |
- | 620 LINE(XO+X1(5),Y1(5))-(XO+X1(6),Y1(6)),4 | + | |
- | 630 LINE(XO+X1(6),Y1(6))-(XO+X1(7),Y1(7)),4 | + | |
- | 640 FOR K=8TO11:LINE(XO+X1(K),Y1(K))-(XO+X1(K+1),Y1(K+1)),4 | + | |
- | 660 NEXT K | + | |
- | 670 CIRCLE (XO+X1(13),Y1(13)),10,4:RETURN'──▶ | + | |
- | 700 DATA 14,150,20,133,15,120,20,93,5,145,25,133,15,120 | + | |
- | 710 DATA 20,115,10,110,19,92,20,108,30,113,20,83 | + | |
- | 720 DATA 2,132,25,136,40,93,43,150,50,130,30,120 | + | |
- | 730 DATA 30,111,22,103,38,95,43,110,58,104,40,83 | + | |
- | 740 XO=0:X2=0:GOTO 120 | + | |
- | </code> | + | |
- | + | ||
- | Убедились? В связи с этим в язык [[msx:basic:]] включены дополнительные средства вывода на экран графической информации — //спрайты//. | + | |
- | + | ||
- | ==== V.6.1. Формирование значения спрайта ==== | + | |
- | + | ||
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | //Эльфы// — в германских народных поверьях духи природы, населяющие воздух, землю, горы, леса, жилища людей и обычно благожелательные людям. | + | |
- | <WRAP rightalign> | + | |
- | —//Советский Энциклопедический Словарь// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | {{anchor:sprite1}} | + | |
- | В [[msx:basic:]] используются специальные нумерованные строковые переменные, называемые //спрайтами//. | + | |
- | + | ||
- | Для записи //имени// спрайта используется псевдопеременная ''SPRITE$()'', синтаксис которой: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | SPRITE$(n)=β | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''SPRITE''("sprite"–"эльф") — служебное слово; | + | |
- | * n — арифметическое выражение, целая часть значения которого определяет номер спрайта. | + | |
- | * β — строковое выражение | + | |
- | + | ||
- | Строковое выражение β это последовательность символов, каждый из которых воспринимается в виде его двоичного представления. Значение β выравнивается, если это требуется, до наибольшей длины спрайта за счёт отбрасывания его лишних правых байтов или, наоборот, за счёт добавления справа необходимого количества нулевых байтов (00000000). Полученное значение присваивается спрайту с заданным номером. | + | |
- | Например: | + | |
- | - <code>10 SCREEN1:SPRITE$(5)="12345678"</code> | + | |
- | - <code>SCREEN2:FOR S=0 TO 63:SPRITE$(S)="ABCDEFGHIJKL":NEXT</code> | + | |
- | + | ||
- | В дальнейшем вместо фразы "длина значения спрайта" мы будем употреблять фразу //"длина спрайта"//. | + | |
- | + | ||
- | <WRAP center round tip 60%> | + | |
- | Для значений спрайтов отводится определённое место в оперативной памяти, называемое //спрайтовой// областью, оно имеет объем 2Кб (2048 байт). | + | |
- | </WRAP> | + | |
- | + | ||
- | Оператор присваивания | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | A=SPRITE$(n) | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * A — строковая переменная или элемент строкового массива; | + | |
- | * n — арифметическое выражение, целая часть значения которого определяет номер спрайта; позволяет при недостатке строкового пространства хранить значения простых строковых переменных и элементов строковых массивов в спрайтовой области. | + | |
- | + | ||
- | Думаем, что теперь Вам совершенно ясен семантический смысл, например, конструкции вида: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | SPRITE$(12)=SPRITE$(7) | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | ! | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | + | ||
- | FIXME | + | |
- | + | ||
- | Итак, приступим к описанию спрайта! | + | |
- | + | ||
- | Напомним структуру байта: | + | |
- | <code> | + | |
- | 128 64 32 16 8 4 2 1 ◀── степень числа 2 | + | |
- | ┌───┬───┬───┬───┬───┬───┬───┬───┐ | + | |
- | │ 0 │ 0 │ 0 │ 1 │ 1 │ 0 │ 0 │ 0 │ = 24₁₀ | + | |
- | └───┴───┴───┴───┴───┴───┴───┴───┘ | + | |
- | </code> | + | |
- | + | ||
- | Базовый вариант спрайта это квадрат 8×8 точек, его размер 8 байт, можно задать 256 таких спрайтов. | + | |
- | + | ||
- | Для того, чтобы задать спрайт, нужно расположить значения байт следующим образом: в первой строке — 1–й байт, во второй строке — 2–й байт и т.д.: | + | |
- | + | ||
- | {{anchor:e0561-01}} | + | |
- | <code> | + | |
- | ┌─ номер байта | + | |
- | │ | + | |
- | ▼┌───┬───┬───┬───┬───┬───┬───┬───┐ | + | |
- | 1│ │ │ │ █ │ █ │ │ │ │ 00011000₂ = 24₁₀ | + | |
- | ├───┼───┼───┼───┼───┼───┼───┼───┤ | + | |
- | 2│ │ │ █ │ █ │ █ │ █ │ │ │ 00111100₂ = 60₁₀ | + | |
- | ├───┼───┼───┼───┼───┼───┼───┼───┤ | + | |
- | 3│ │ █ │ █ │ █ │ █ │ █ │ █ │ │ 01111110₂ = 126₁₀ | + | |
- | ├───┼───┼───┼───┼───┼───┼───┼───┤ | + | |
- | 4│ █ │ █ │ █ │ █ │ █ │ █ │ █ │ █ │ 11111111₂ = 255₁₀ | + | |
- | ├───┼───┼───┼───┼───┼───┼───┼───┤ | + | |
- | 5│ │ │ │ █ │ █ │ │ │ │ 00011000₂ = 24₁₀ | + | |
- | ├───┼───┼───┼───┼───┼───┼───┼───┤ | + | |
- | 6│ │ │ │ █ │ █ │ │ │ │ 00011000₂ = 24₁₀ | + | |
- | ├───┼───┼───┼───┼───┼───┼───┼───┤ | + | |
- | 7│ │ │ │ █ │ █ │ │ │ │ 00011000₂ = 24₁₀ | + | |
- | ├───┼───┼───┼───┼───┼───┼───┼───┤ | + | |
- | 8│ │ │ │ █ │ █ │ │ │ │ 00011000₂ = 24₁₀ | + | |
- | └───┴───┴───┴───┴───┴───┴───┴───┘ | + | |
- | </code> | + | |
- | в результате должно получиться 8 чисел. | + | |
- | + | ||
- | Вот программа для формирования спрайта по этим данным и вывод его на экран: | + | |
- | \\ {{.examples:0561-01.bas|}} \\ [[+tab|wmsxbpge>0561-01.bas]] | + | |
- | <code> | + | |
- | 10 SCREEN 1:KEY OFF | + | |
- | 20 DATA 24,60,126,255,24,24,24,24 | + | |
- | 30 FOR N=1 TO 8 | + | |
- | 40 READ A | + | |
- | 50 F$=F$+CHR$(A) | + | |
- | 60 NEXT | + | |
- | 70 SPRITE$(1)=F$ | + | |
- | 80 PUT SPRITE 1,(0,0) | + | |
- | 90 GOTO 90 | + | |
- | + | ||
- | </code> | + | |
- | + | ||
- | + | ||
- | + | ||
- | Большой спрайт 16×16 точек имеет размер 32 байт, можно задать 64 таких спрайта. | + | |
- | + | ||
- | Такой спрайт состоит из 4–х базовых спрайтов 8×8, ниже дан порядок описания такого спрайта. \\ Левая половина спрайта задаётся байтами 1–16, а правая байтами 17–32. | + | |
- | <code> | + | |
- | ┌─ номер байта ───────────────────────────────────────────────────┐ | + | |
- | │ │ | + | |
- | ▼┏━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┳━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┓▼ | + | |
- | 1┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃17 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 2┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃18 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 3┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃19 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 4┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃20 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 5┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃21 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 6┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃22 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 7┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃23 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 8┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃24 | + | |
- | ┣━━━┿━━━┿━━━┿━━━┿━━━┿━━━┿━━━┿━━━╋━━━┿━━━┿━━━┿━━━┿━━━┿━━━┿━━━┿━━━┫ | + | |
- | 9┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃25 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 10┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃26 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 11┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃27 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 12┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃28 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 13┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃29 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 14┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃30 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 15┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃31 | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | 16┃ │ │ │ │ │ │ │ ┃ │ │ │ │ │ │ │ ┃32 | + | |
- | ┗━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┻━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┛ | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e0561-02}} | + | |
- | Приведём пример спрайта 16×16: | + | |
- | <code> | + | |
- | ┏━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┳━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┓ | + | |
- | ┃ │ │ │ │ │ │ │ █ ┃ █ │ │ │ │ │ │ │ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ │ │ │ │ │ │ █ │ █ ┃ █ │ █ │ │ │ │ │ │ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ │ │ │ │ │ █ │ █ │ █ ┃ █ │ █ │ █ │ │ │ │ │ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ │ │ │ │ █ │ █ │ █ │ █ ┃ █ │ █ │ █ │ █ │ │ │ │ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ │ │ │ █ │ █ │ █ │ █ │ █ ┃ █ │ █ │ █ │ █ │ █ │ │ │ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ │ │ █ │ █ │ █ │ █ │ █ │ █ ┃ █ │ █ │ █ │ █ │ █ │ █ │ │ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ │ █ │ █ │ █ │ █ │ █ │ █ │ █ ┃ █ │ █ │ █ │ █ │ █ │ █ │ █ │ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ █ │ █ │ █ │ █ │ █ │ █ │ █ │ █ ┃ █ │ █ │ █ │ █ │ █ │ █ │ █ │ █ ┃ | + | |
- | ┣━━━┿━━━┿━━━┿━━━┿━━━┿━━━┿━━━┿━━━╋━━━┿━━━┿━━━┿━━━┿━━━┿━━━┿━━━┿━━━┫ | + | |
- | ┃ █ │ █ │ █ │ █ │ █ │ █ │ █ │ █ ┃ █ │ █ │ █ │ █ │ █ │ █ │ █ │ █ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ │ █ │ █ │ █ │ █ │ █ │ █ │ █ ┃ █ │ █ │ █ │ █ │ █ │ █ │ █ │ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ │ │ █ │ █ │ █ │ █ │ █ │ █ ┃ █ │ █ │ █ │ █ │ █ │ █ │ │ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ │ │ │ █ │ █ │ █ │ █ │ █ ┃ █ │ █ │ █ │ █ │ █ │ │ │ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ │ │ │ │ █ │ █ │ █ │ █ ┃ █ │ █ │ █ │ █ │ │ │ │ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ │ │ │ │ │ █ │ █ │ █ ┃ █ │ █ │ █ │ │ │ │ │ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ │ │ │ │ │ │ █ │ █ ┃ █ │ █ │ │ │ │ │ │ ┃ | + | |
- | ┠───┼───┼───┼───┼───┼───┼───┼───╂───┼───┼───┼───┼───┼───┼───┼───┨ | + | |
- | ┃ │ │ │ │ │ │ │ █ ┃ █ │ │ │ │ │ │ │ ┃ | + | |
- | ┗━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┻━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┷━━━┛ | + | |
- | </code> | + | |
- | + | ||
- | ^ № байта^ Значение₁₀ ||^№ байта| | + | |
- | ^ 1| 1 | | 128 ^17| | + | |
- | ^ 2| 3 | | 192 ^18| | + | |
- | ^ 3| 7 | | 224 ^19| | + | |
- | ^ 4| 15 | | 240 ^20| | + | |
- | ^ 5| 31 | | 248 ^21| | + | |
- | ^ 6| 63 | | 252 ^22| | + | |
- | ^ 7| 127 | | 254 ^23| | + | |
- | ^ 8| 255 | | 255 ^24| | + | |
- | | | | | | | | + | |
- | ^ 9| 255 | | 255 ^25| | + | |
- | ^ 10| 127 | | 254 ^26| | + | |
- | ^ 11| 63 | | 252 ^27| | + | |
- | ^ 12| 31 | | 248 ^28| | + | |
- | ^ 13| 15 | | 240 ^29| | + | |
- | ^ 14| 7 | | 224 ^30| | + | |
- | ^ 15| 3 | | 192 ^31| | + | |
- | ^ 16| 1 | | 128 ^32| | + | |
- | + | ||
- | А вот и программа для формирования спрайта по этим данным и вывод его на экран: | + | |
- | \\ {{.examples:0561-02.bas|}} \\ [[+tab|wmsxbpge>0561-02.bas]] | + | |
- | <code> | + | |
- | 10 SCREEN 1,3:KEY OFF | + | |
- | 20 DATA 1,3,7,15,31,63,127,255 | + | |
- | 30 DATA 255,127,63,31,15,7,3,1 | + | |
- | 40 DATA 128,192,224,240,248,252,254,255 | + | |
- | 50 DATA 255,254,252,248,240,224,192,128 | + | |
- | 60 FOR N=1 TO 32 | + | |
- | 70 READ A | + | |
- | 80 F$=F$+CHR$(A) | + | |
- | 90 NEXT | + | |
- | 100 SPRITE$(1)=F$ | + | |
- | 110 PUT SPRITE 1,(0,0) | + | |
- | 120 GOTO 120 | + | |
- | + | ||
- | </code> | + | |
- | ==== V.6.2. Вывод спрайта на экран ==== | + | |
- | FIXME | + | |
- | + | ||
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | Intelligenti pausa | + | |
- | <WRAP rightalign> | + | |
- | —//Лат. поговорка// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | Значения спрайтов можно выводить на экран ''SCREEN 1'' при помощи "тривиального" оператора ''PRINT''. | + | |
- | + | ||
- | {{anchor:e0562-01}} __//Пример 1//__. \\ {{.examples:0562-01.bas|}} \\ [[+tab|wmsxbpge>0562-01.bas]] | + | |
- | <code> | + | |
- | 10 SCREEN1'Но не SCREEN0! | + | |
- | 20 SPRITE$(50)="screen1" | + | |
- | 30 PRINT SPRITE$(50) | + | |
- | run | + | |
- | screen1 | + | |
- | Ok | + | |
- | + | ||
- | 10 SCREEN1'Но не SCREEN0! | + | |
- | 20 SPRITE$(20)="Алгоритмический язык":PRINT SPRITE$(20) | + | |
- | run | + | |
- | Алгоритм | + | |
- | Ok | + | |
- | </code> | + | |
- | + | ||
- | Можно, конечно, выводить значение спрайта и в режиме ''SCREEN 0''. Но для этого его значение нужно вначале определить в режиме ''SCREEN 1''! | + | |
- | + | ||
- | Однако, обычно, выводятся не сами значения спрайтов, а некоторые геометрические образы, порождаемые специальной двоичной интерпретацией этих значений. Вначале опишем форму представления значений спрайтов при выводе на экран дисплея. | + | |
- | + | ||
- | {{anchor:e0562-02}} __//Пример 2//__. \\ {{.examples:0562-02.bas|}} \\ [[+tab|wmsxbpge>0562-02.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN1:SPRITE$(4)="интеграл":FOR I=1 TO 8:?BIN$(ASC(MID$(SPRITE$(4),I,1))):NEXT | + | |
- | run | + | |
- | 11001001 | + | |
- | 11001110 | + | |
- | 11010100 | + | |
- | 11000101 | + | |
- | 11000111 | + | |
- | 11010010 | + | |
- | 11000001 | + | |
- | 11001100 | + | |
- | Ok | + | |
- | </code> | + | |
- | <code> | + | |
- | ┌───────────────┐ | + | |
- | │1 1 0 0 1 0 0 1│"и" ██ █ █ | + | |
- | │1 1 0 0 1 1 1 0│"н" ██ ███ | + | |
- | │1 1 0 1 0 1 0 0│"т" ██ █ █ | + | |
- | │1 1 0 0 0 1 0 1│"е" ██ █ █ | + | |
- | │1 1 0 0 0 1 1 1│"г" ██ ███ | + | |
- | │1 1 0 1 0 0 1 0│"р" ██ █ █ | + | |
- | │1 1 0 0 0 0 0 1│"а" ██ █ | + | |
- | │1 1 0 0 1 1 0 0│"л" ██ ██ | + | |
- | └───────────────┘ | + | |
- | Двоичная интерпретация Образ спрайта на | + | |
- | значения спрайта экране дисплея | + | |
- | </code> | + | |
- | + | ||
- | FIXME | + | |
- | {{anchor:putsprite}} | + | |
- | Спрайт создаётся на экране по команде ''PUT SPRITE'', синтаксис оператора приведён ниже: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | PUT SPRITE n,[STEP](X,Y)[,C][,P] | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * n — Номер спрайта | + | |
- | * ''STEP'' («step» — «шаг») — служебное слово, если этот параметр указан, то координаты интерпретируются относительно текущей позиции курсора, в этом случае значения могут быть отрицательными; | + | |
- | * X — арифметическое выражение, целая часть значения которого задаёт координату левого верхнего угла спрайта по горизонтали, значение может находиться в диапазоне от -32 до 255; | + | |
- | * Y — арифметическое выражение, целая часть значения которого задаёт координату левого верхнего угла спрайта по вертикали, значение находиться в диапазонах:<WRAP> | + | |
- | * от -32 до 191 на режимах ''SCREEN'' с 1 по 3; | + | |
- | * от -32 до 211 в режимах ''SCREEN'' с 4 по 8; | + | |
- | </WRAP> | + | |
- | * C — цвет спрайта, числовое выражение:<WRAP> | + | |
- | * от 0 до 15 в режимах ''SCREEN'' с 0 до 5 и 7; | + | |
- | * от 0 до 3 в ''SCREEN 6''; | + | |
- | * от 0 до 255 в ''SCREEN 8''; | + | |
- | по умолчанию — цвет текста или последний цвет присвоенный спрайту посредством ''PUT SPRITE'' или ''[[#colorsprite|COLOR SPRITE]]'');</WRAP> | + | |
- | * P — номер шаблона в таблице спрайтов, значение находиться в диапазонах:<WRAP> | + | |
- | * от 0 до 255 для спрайта 8x8; | + | |
- | * от 0 до 63 для спрайта 16x16. | + | |
- | Если он не указан, он равен номеру спрайта.</WRAP> | + | |
- | + | ||
- | FIXME | + | |
- | + | ||
- | {{anchor:e0562-12}} __//Пример 12//__. Фильм (чередование спрайтов на одном и том же месте экрана дисплея). \\ {{.examples:0562-12.bas|}} \\ [[+tab|wmsxbpge>0562-12.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN 2,3 | + | |
- | 20 A$="Мы":B$="изучаем":C$="язык":D$="MSX BASIC" | + | |
- | 30 SPRITE$(1)=A$:SPRITE$(2)=B$:SPRITE$(3)=C$:SPRITE$(4)=D$ | + | |
- | 40 FOR I=1 TO 4:PUT SPRITE 2,(90,90),11,I'Обратите внимание на то, что номер спрайта изменяется в цикле, а "экранный" номер постоянен! | + | |
- | 50 FOR U=1 TO 200:NEXT:NEXT:GOTO 40 | + | |
- | </code> | + | |
- | Из рассмотрения примеров 8–12 можно сделать некоторые выводы о назначении "экранного" номера спрайта. | + | |
- | * "Экранный" номер показывает нам номер "пятна" (спрайта) на экране. Для того, чтобы вывести на экран N спрайтов (или N копий одного и того же спрайта), необходимо, чтобы эти спрайты имели N различных "экранных" номеров (на экране — N "пятен"). | + | |
- | * Использование "экранных" номеров даёт нам ещё одно преимущество: для того, чтобы изобразить спрайт с "экранным" номером t в некоторой точке экрана A, а затем его же изобразить в другой точке B, нет необходимости "стирать" его на старом месте, а достаточно просто указать его новые координаты. В результате спрайт тут же "самостоятельно перепрыгнет" в точку B. Если же спрайты имеют разные "экранные" номера, то спрайт в точке А останется на том же месте, в то время как в точке B экрана появится другой спрайт! | + | |
- | * Более того, применение "экранного" номера даёт нам возможность "создавать" цветные спрайты, накладывая их образы друг на друга. При этом важно отметить, что спрайт с меньшим экранным номером "накладывается" на спрайты, имеющие большие экранные номера. | + | |
- | + | ||
- | {{anchor:e0562-13}} __//Пример 13//__. Цветные спрайты. \\ {{.examples:0562-13.bas|}} \\ [[+tab|wmsxbpge>0562-13.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 20 SCREEN2,2 | + | |
- | 30 X$=CHR$(&H0)+CHR$(&H0)+CHR$(&HF)+CHR$(&H18)+CHR$(&H34)+CHR$(&H34)+CHR$(&HE0)+CHR$(&HC1) | + | |
- | 35 T$=CHR$(&H0)+CHR$(&H0)+CHR$(&H0)+CHR$(&H1F)+CHR$(&H3F)+CHR$(&H3F)+CHR$(&H7F)+CHR$(&HFF) | + | |
- | 40 Y$=CHR$(&H67)+CHR$(&H1E)+CHR$(&H1)+CHR$(&HB)+CHR$(&HD)+CHR$(&H16)+CHR$(&H1F)+CHR$(&HE) | + | |
- | 45 A$=CHR$(&H7F)+CHR$(&HE)+CHR$(&H0)+CHR$(&H0)+CHR$(&H0)+CHR$(&H0)+CHR$(&H0)+CHR$(&H0) | + | |
- | 50 Z$=CHR$(&H0)+CHR$(&HC)+CHR$(&H9C)+CHR$(&HF4)+CHR$(&H64)+CHR$(&H48)+CHR$(&HCA)+CHR$(&HF3) | + | |
- | 55 U$=CHR$(&H0)+CHR$(&H0)+CHR$(&H0)+CHR$(&HFC)+CHR$(&HFC)+CHR$(&HF8)+CHR$(&HFA)+CHR$(&HF3) | + | |
- | 60 W$=CHR$(&HC7)+CHR$(&HE7)+CHR$(&HF7)+CHR$(&HB2)+CHR$(&H7A)+CHR$(&HFC)+CHR$(&H38)+CHR$(&H70) | + | |
- | 65 R$=CHR$(&HC7)+CHR$(&H66)+CHR$(&H7)+CHR$(&HB2)+CHR$(&HA)+CHR$(&HC)+CHR$(&H38)+CHR$(&H70) | + | |
- | 70 SPRITE$(1)=X$+Y$+Z$+W$ | + | |
- | 75 SPRITE$(2)=T$+A$+U$+R$ | + | |
- | 80 PUTSPRITE 1,(101,94),1,1 | + | |
- | 83 PUTSPRITE 2,(101,94),15,2 | + | |
- | 85 PUTSPRITE 3,(141,94),11,1 | + | |
- | 87 PUTSPRITE 4,(141,94),1,2 | + | |
- | 90 GOTO 90 | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e0562-14}} __//Пример 14//__. Движение цветных (!) спрайтов. \\ {{.examples:0562-14.bas|}} \\ [[+tab|wmsxbpge>0562-14.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 1,3:DATA 11111111 | + | |
- | 30 C$="":FOR I=1 TO 32:GOSUB 130:NEXT:SPRITE$(1)=C$ | + | |
- | 50 C$="":FOR I=1 TO 2:GOSUB 130:NEXT:SPRITE$(2)=C$:SPRITE$(3)="12345678":FOR L=1 TO 270 | + | |
- | 80 PUT SPRITE 1,(85+L,99),15,3:PUT SPRITE 2,(80+L,90),2,1 | + | |
- | 95 PUT SPRITE 3,(75+L,88),10,2:PUT SPRITE 4,(88+L,73),13,2 | + | |
- | 110 PUT SPRITE 5,(80+L,60),1,1:NEXTL:END | + | |
- | 130 RESTORE10:READB$:A$="&b"+B$:C$=C$+CHR$(VAL(A$)):RETURN | + | |
- | </code> | + | |
- | Внимание! В одной строке экрана (напомним, что, например, в экране ''SCREEN 2'' 192 строки) можно разместить не более //четырёх// спрайтов, а остальные спрайты с более высокими "экранными" номерами останутся невидимыми! | + | |
- | + | ||
- | {{anchor:e0562-15}} __//Пример 15//__. Программа демонстрирует интересные ситуации, возникающие при попытке поместить несколько (>4) спрайтов в одной строке экрана. \\ {{.examples:0562-15.bas|}} \\ [[+tab|wmsxbpge>0562-15.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 INPUT"Число спрайтов";K:INPUT"Смещение спрайтов по вертикали";Q:SCREEN2,1:COLOR ,15,15:SPRITE$(1)="логарифм" | + | |
- | 40 FOR I=1 TO K:PUT SPRITE I,(20*I,W),8,1:W=W+Q:NEXT | + | |
- | 50 A$=INPUT$(1)'Ожидание нажатия любой клавиши! | + | |
- | </code> | + | |
- | + | ||
- | Исследуем четыре возможных случая и приведём результаты исследования: | + | |
- | ^ № ^ Условие ^ Результат ^ | + | |
- | | 1 |K%%<=%%4|все K образов спрайта выводятся на экран "целиком"| | + | |
- | | 2 |K>4 AND Q=0|на экран выводятся только 4 первых образа спрайта| | + | |
- | | 3 |K>4 AND Q<4 AND Q≠0|целиком выводятся только 4 первых образа спрайта, остальные же образы выводятся на экран частично (подумайте, почему?)| | + | |
- | | 4 |K>4 AND Q>=4|на экран выводятся все образы спрайта| | + | |
- | Переменные: | + | |
- | * K — число спрайтов; | + | |
- | * Q — смещение спрайтов по вертикали; | + | |
- | + | ||
- | При замене оператора ''SCREEN 2,1'' на ''SCREEN 2,0'' вместо случаев Q<4 и Q>=4 рассмотрите соответственно случаи Q<2 и Q>=2. | + | |
- | + | ||
- | И, наконец, для того, чтобы "избавиться" от спрайта, определите его цвет как прозрачный (0) в операторе ''PUT SPRITE'' или заполните нулями соответствующий образ. | + | |
- | + | ||
- | Заметим, что если цветные спрайты создаются наложением, то нельзя использовать оператор ''ON SPRITE GOSUB'' совместно с операторами ''SPRITE ON'' или ''SPRITE STOP'', ибо "наложенные" друг на друга спрайты все время "сталкиваются" (см. [[#V.6.3. Столкновение спрайтов|раздел V.6.3.]])! | + | |
- | + | ||
- | Думаем, что рисунок, помещённый ниже, поможет Вам лучше "прочувствовать" механизм работы со спрайтами. Посмотрите на него внимательно… | + | |
- | {{anchor:pict_05_05}} <code> | + | |
- | ┌──────────┐ | + | |
- | ┌──────────┐ │ | + | |
- | ┌──────────┐ │ │ | + | |
- | ┌──────────┐ │ │ │ | + | |
- | Экран 31┌──────────┐ │ │ │ │ | + | |
- | … │ ███ │ │ │ │─┘ Бордюр | + | |
- | Экран 1┌──────────┐ ·│ │ │─┘ Внешний видеосигнал (MSX 2) | + | |
- | Экран 0┌──────────┐ │ · │ │─┘ Фоновый экран | + | |
- | Образ │ │ │· │─┘ Основной экран | + | |
- | спрайта с │ ██ │ │───┘◀── для спрайта 31 | + | |
- | "экранным" ────────▶ ██ │ │ | + | |
- | номером 0 │ │─┘◀── для спрайта 1 | + | |
- | └──────────┘◀── для спрайта 0 | + | |
- | </code> __//Рис. 5//__ | + | |
- | + | ||
- | На рисунке изображён ряд параллельных прозрачных пластинок, которые мы будем называть //экранами//. Экраны введены для того, чтобы: | + | |
- | * создать удобный механизм движения спрайтов; | + | |
- | * однозначно определять изображение, возникающее при наложении спрайтов. | + | |
- | На каждом экране может находиться не более одного спрайта. Если на некотором экране уже находится спрайт, то вывод на него нового спрайта (в любом месте) вызывает //исчезновение// первого спрайта. Это позволяет осуществлять //движение// спрайтов, печатая один и тот же спрайт на определённый экран и изменяя его координаты на этом экране! | + | |
- | + | ||
- | Далее, печатая на один экран в одном и том же месте разные спрайты, мы можем получать изображение предмета, меняющего форму. | + | |
- | + | ||
- | Каждый экран имеет определённый приоритет (по глубине): все объекты на экранах с меньшими номерами частично (или полностью) //закрывают // объекты на экранах с большими номерами. Для отображения менее приоритетных объектов соответствующая область более приоритетных экранов должна быть //прозрачной// — свободной от изображения. | + | |
- | + | ||
- | Поэтому при //наложении// спрайтов полностью виден спрайт, находящийся на экране с меньшим номером. | + | |
- | + | ||
- | И, наконец, один и тот же образ спрайта можно одновременно выводить на несколько экранов. | + | |
- | + | ||
- | Плоскость //бордюра// по формату несколько превышает остальные плоскости, образуя как бы своеобразную окантовку вокруг изображения. | + | |
- | Основное графическое изображение и текст формируются на //основном// экране. Его "содержимым" могут быть отрезки прямых, дуги окружностей и т.д. На этом же экране располагается и текстовая информация. | + | |
- | + | ||
- | Сквозь незанятые позиции основного экрана "просвечивают" //фоновый// экран и окаймляющая его цветная рамка. | + | |
- | + | ||
- | ---- | + | |
- | + | ||
- | Редактор спрайтов: [[msx:tinysprite:tinysprite|TinySprite]]. | + | |
- | + | ||
- | {{anchor:onspritegosub}} | + | |
- | ==== V.6.3. Столкновение спрайтов ==== | + | |
- | + | ||
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | Да сделайте же, наконец, CALL NETEND ! | + | |
- | <WRAP rightalign> | + | |
- | —//крик, вырвавшийся из уст пользователя %%MSX%% 2// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | //Столкновением спрайтов// мы считаем: | + | |
- | * для //программиста// — наложение на экране одной или нескольких точек их образов. Следует отметить, что столкновение спрайтов происходит только тогда, когда сталкиваются их //видимые// части. Причём закраска спрайта цветом фона вовсе не делает его невидимым! | + | |
- | * для //компьютера// — совпадение //единичных// битов в образах спрайтов, за исключением тех случаев, когда цвет хотя бы одного спрайта установлен в 0 (тогда столкновение не обнаруживается!). | + | |
- | + | ||
- | Оператор | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | ON SPRITE GOSUB n | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''ON'' ("по"), ''SPRITE'', ''GOSUB'' — служебные слова; | + | |
- | * n — номер программной строки, приводит в состояние готовности режим передачи управления подпрограмме, расположенной со строки n, при любых столкновениях спрайтов. | + | |
- | + | ||
- | Этот режим включается, выключается и приостанавливается соответственно операторами ''SPRITE ON'', ''SPRITE OFF'', ''SPRITE STOP''. | + | |
- | + | ||
- | {{anchor:sprite}} | + | |
- | Если задан режим ''SPRITE ON'', то любое столкновение спрайтов вызывает //прерывание// (по окончании выполнения текущего оператора) и затем переход к подпрограмме, указанной в операторе ''ON SPRITE''. По умолчанию устанавливается режим ''SPRITE STOP'' вплоть до оператора ''RETURN'' этой подпрограммы. | + | |
- | + | ||
- | После выполнения оператора ''RETURN'' вновь устанавливается режим ''SPRITE ON'' до тех пор, пока Вы явно не запретите обработку прерываний по столкновению спрайтов оператором ''SPRITE OFF'', который позволяет игнорировать любое столкновение спрайтов до тех пор, пока Вы не употребите вновь оператор ''SPRITE ON''. | + | |
- | + | ||
- | Оператор ''SPRITE STOP'' временно отключает обработку прерываний. Если столкновение спрайтов произошло, то этот факт "запоминается", но никаких действий не происходит; однако, если позже компьютер встретит оператор ''SPRITE ON'', то будет обработано ранее зафиксированное прерывание. | + | |
- | + | ||
- | {{anchor:e0563-01}} __//Пример 1//__. Сравните, пожалуйста,результаты работы приведённых ниже программ. \\ {{.examples:0563-011.bas|}} \\ [[+tab|wmsxbpge>0562-011.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN 1,3 | + | |
- | 20 ON SPRITE GOSUB100:SPRITE ON:X$="итерация":SPRITE$(50)=X$+X$+X$+X$ | + | |
- | 50 FOR K=0 TO 255 | + | |
- | 60 PUT SPRITE 0,(K,70),4,50:PUT SPRITE 1,(120,K),13,50 | + | |
- | 80 NEXT:GOTO 50 | + | |
- | 90 '¤¤¤¤ Подпрограмма! ¤¤¤¤ | + | |
- | 100 SPRITE OFF:PRINT "Столкновение":FOR I=1 TO 1000:NEXT:CLS:SPRITE ON:RETURN | + | |
- | </code> | + | |
- | {{.examples:0563-012.bas|}} \\ [[+tab|wmsxbpge>0562-012.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15,8:SCREEN 1,3 | + | |
- | 20 ON SPRITE GOSUB100:SPRITE ON:X$="итерация":SPRITE$(50)=X$+X$+X$+X$ | + | |
- | 50 FOR K=0 TO 255 | + | |
- | 60 PUT SPRITE 0,(K,70),4,50:PUT SPRITE 1,(120,K),13,50 | + | |
- | 80 NEXT:SPRITE ON:GOTO 50 | + | |
- | 90 '¤¤¤¤ Подпрограмма! ¤¤¤¤ | + | |
- | 100 PRINT"Столкновение":FOR I=1 TO 1000:NEXT:CLS:SPRITE OFF:RETURN | + | |
- | </code> | + | |
- | + | ||
- | Для очистки экрана дисплея от образов спрайтов примените в непосредственном режиме команду ''SCREEN 0'' (''CLS'' не поможет!). | + | |
- | + | ||
- | Укажем один из способов определения, какие именно спрайты столкнулись: он заключается в обнаружении столкновения по изменению цветов спрайтов. Напомним, что цвет спрайта с меньшим "экранным" номером накладывается на цвет спрайта с большим "экранным" номером. | + | |
- | + | ||
- | Предлагаем Вам пример простейшей программы, позволяющей определить, спрайт какого цвета "пострадал" при столкновении! Разумеется,задача значительно усложняется в случае, когда спрайты имеют одинаковые цвета! | + | |
- | + | ||
- | {{anchor:e0563-02}} __//Пример 2//__. \\ {{.examples:0563-02.bas|}} \\ [[+tab|wmsxbpge>0562-02.bas]] | + | |
- | <code> | + | |
- | Ok | + | |
- | 1 SCREEN2,0 | + | |
- | 10 OPEN"grp:" AS#1'Данный оператор применяется совместно с операторами PRINT#1 и CLOSE#1 для организации вывода символьной информации на графические экраны SCREEN 2 и SCREEN 3. | + | |
- | 20 SPRITE$(1)="итерация":SPRITE$(2)="интеграл":SPRITE$(3)="алгоритм":E=2:ON SPRITE GOSUB 500 | + | |
- | 40 PUT SPRITE 2,(60,100),2:PUT SPRITE 3,(90,100),1 | + | |
- | 60 FORK=1TO256:SPRITE ON:N=1:PUT SPRITE N,(K,100),1,3:NEXT | + | |
- | 100 GOTO 100 | + | |
- | 500 SPRITE OFF::PRESET(90,10) | + | |
- | 512 IF POINT(PEEK(&HFCB3),PEEK(&HFCB5))<>2 AND E=2 THEN PRINT #1,"Green" ELSE IF POINT(PEEK(&HFCB3),PEEK(&HFCB5))<>1AND E=3 THEN PRINT #1,"Black" | + | |
- | 520 FOR T=1 TO 500:NEXT:PUT SPRITE E,(E*10,E*10),15:E=E+1 | + | |
- | 525 CLS:SPRITE ON:RETURN | + | |
- | </code> | + | |
- | Напомним, что значения ''PEEK(&HFCB3)'' и ''PEEK(&HFCB5)'' определяют координаты текущего положения графического курсора. | + | |
- | + | ||
- | Прерывания по столкновению спрайтов широко используются в //игровых// программах. Они дают возможность, например, воспроизводить звук взрыва при всяком столкновении ракеты и мишени, если оба этих объекта являются спрайтами. | + | |
- | + | ||
- | {{anchor:e0563-03}} __//Пример 3//__. Программа демонстрирует некоторые возможности применения спрайтов. | + | |
- | \\ {{.examples:0563-03.bas|}} \\ [[+tab|wmsxbpge>0563-03.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 30 SCREEN 0:CLS:PRINT SPC(10);"Внимание!":PRINT "Перед Вами игра ";CHR$(34);"Бегущие человечки";CHR$(34):PRINT "Зеленый человечек управляется клавишами перемещения курсора, а синий движется по случайной траектории." | + | |
- | 40 PRINT "При их столкновении возникает объект, движущийся по окружности.":PRINT | + | |
- | 50 PRINT"Цель игры - за определенное время сделать как можно больше столкновений человечков." | + | |
- | 60 PRINT "Скорость движения бегущих человечков характеризуется следующими величинами:":PRINT TAB(2);"a)-шагом перемещения":PRINT TAB(2);"b)-задержкой изображения":INPUT"Чему равен шаг";U1:INPUT"Чему равна задержка";U2 | + | |
- | 80 DATA 6,9,9,9,9,9,6,0,2,2,6,2,2,2,7,0,6,9,9,2,4,8,15,0,6,9,1,2,1,9,6,0,9,9,9,15,1,1,1,0,15,8,8,15,1,1,15,0,6,9,8,14,9,9,6,0,15,1,1,2,4,4,4,0,6,9,9,6,9,9,6,0,6,9,9,7,1,9,6,0:'Информация о секундомере. | + | |
- | 90 DATA 48,48,94,123,28,55,32,96,48,48 ,28,122,26,56,40,4,48,48,24,28,24,48,60,24,48,48,28,122,26,56,40,20,12,12,122,222,56,236,4,6,12,12,56,94,88,28,20,32,12,12,24,56,24,12,60,24,12,12,56,94,88,28,20,40:'Информация о бегущих человечках. | + | |
- | 100 DATA 1,7,11,31,30,57,49,33,33,51,30 ,15,21,16,11,7,128,224,208,184,252,156 ,140,132,132,204,120,240,104,8,80,224:'Информация об объекте,движущемся по окружности. | + | |
- | 110 COLOR 1,15,8:SCREEN 2,2,1 'Установка экрана. | + | |
- | 120 RESTORE 80:FOR Z=0 TO 9:GOSUB 300:SPRITE$(Z)=Y$:NEXT:S1=0:S2=0:S3=0:S4=0:GOSUB 230 'Сформированы образы спрайтов секундомера. | + | |
- | 130 INTERVAL ON:ON INTERVAL=60 GOSUB 190 'Изменение состояния секундомера через каждую секунду. | + | |
- | 140 RESTORE 90:FOR Z=20 TO 27:GOSUB 300:SPRITE$(Z)=Y$:NEXT'Сформированы образы бегущих человечков, каждый из которых представляет смену четырех кадров. | + | |
- | 150 T=1:FA=RND(-TIME):ON SPRITE GOSUB 250 'Установлен режим перехода к подпрограмме при столкновении спрайтов. | + | |
- | 160 SPRITE ON:FOR I=24 TO 27:GOSUB 340:PUT SPRITE 21,(T-2+WX,140+WY),4,I:FOR M=0 TO U2:NEXT:PUT SPRITE 22,(249+XW*U1,140+YW*U1),2,SA:FOR M=0 TO U2:NEXT M,I:IF U1<=0 THEN T=1 ELSE T=T+1 | + | |
- | 170 GOTO 160 'Конец основной программы. | + | |
- | 180 'Подпрограмма вывода секундомера на экран. | + | |
- | 190 IF S4<=9 THEN S4=S4+1 | + | |
- | 200 IF S4=10 THEN IF S3<=6 THEN S3=S3+1:S4=0 | + | |
- | 210 IF S3=6 THEN IF S2<=9 THEN S2=S2+1:S3=0:S4=0 | + | |
- | 220 IF S2=10 THEN IF S1<6 THEN S1=S1+1:S2=0:S3=0:S4=0 ELSE S1=0:S2=0:S3=0:S4=0 | + | |
- | 230 PUT SPRITE 1,(10,10),13,S1:PUT SPRITE 2,STEP(8,0),13,S2:LINE(33,16)-(34,17),13,BF:PUT SPRITE 3,(36,10),13,S3:PUT SPRITE 4,STEP(8,0),13,S4:RETURN | + | |
- | 240 'Подпрограмма обработки столкновения спрайтов. | + | |
- | 250 T=T+8:SPRITE OFF:RESTORE 100:GOSUB 310:SPRITE$(11)=Y$'Сформирован образ нового объекта. | + | |
- | 260 PUT SPRITE 21,(20,140),15,24:PUT SPRITE 22,(227,140),15,20 'Бегущие человечки исчезают. | + | |
- | 270 DEFFN B(X)=SQR(10^2-(X-10)^2):FOR D=1 TO 20:PUT SPRITE 11,(105+D,85+FNB(D)),1,11:NEXT:FOR D=20 TO 1 STEP -1:PUT SPRITE 11,(105+D,85-FNB(D)),1,11:NEXT: 'Движение объекта по окружности. | + | |
- | 280 PUT SPRITE 11,(0,0),15,11:RETURN'Объект исчезает и "прячется" за спрайтами секундомера. | + | |
- | 290 'Подпрограммы формирования образов спрайтов. | + | |
- | 300 Y$="":FOR I=1 TO 8:READ R:Y$=Y$+CHR$(R):NEXT:RETURN | + | |
- | 310 Y$="":FOR I=1 TO 32:READ R:Y$=Y$+CHR$(R):NEXT:RETURN | + | |
- | 320 'Подпрограмма перемещения спрайтов. | + | |
- | 330 'Управление зеленым спрайтом клавишами управления курсором. | + | |
- | 340 CJ=STICK(0):IF CJ=0 THEN XW=XW+1:YW=YW+1 | + | |
- | 350 IF CJ=3 OR CJ=7 THEN YW=YW+1 | + | |
- | 360 IF CJ=4 OR CJ=5 OR CJ=6 THEN YW=YW+1 ELSE YW=YW-1 | + | |
- | 370 IF CJ=1 OR CJ=5 THEN XW=XW+1 | + | |
- | 380 IF CJ=2 OR CJ=3 OR CJ=4 THEN XW=XW+1 ELSE XW=XW-1 | + | |
- | 390 IF CJ=2 OR CJ=3 OR CJ=4 THEN SA=I ELSE SA=I-4 | + | |
- | 400 'Случайное перемещение синего спрайта и блокировка его выхода за пределы экрана по вертикали. | + | |
- | 410 IF U1=0 THEN WX=0:WY=0:RETURN | + | |
- | 420 WX=WX+INT(2*U1*RND(1)) | + | |
- | 430 IF 140+WY>=183-U1 THEN WY=WY-INT(U1*RND(1)):RETURN | + | |
- | 440 IF 140+WY<=U1 THEN WY=WY+INT(U1*RND(1)):RETURN | + | |
- | 450 WY=WY+INT((2*U1+1)*RND(1)-U1):RETURN | + | |
- | </code> | + | |
- | + | ||
- | ===== V.7. Оператор SCREEN в общем случае ===== | + | |
- | + | ||
- | {{anchor:screen}} | + | |
- | Общая форма записи оператора ''SCREEN'' следующая: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | SCREEN [n],[s],[z],[d],[p],[m] | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''SCREEN''("screen" — "экран") — служебное слово; | + | |
- | * n — арифметическое выражение, целая часть значения которого задаёт номер экрана причём: | + | |
- | * n∈{0,1,2,3} для компьютеров [[msx:msx_1]]; | + | |
- | * n∈{0,1,2,3,4,5,6,7,8} для компьютеров [[msx:msx_2]]; | + | |
- | * по умолчанию равен 0 или 1. | + | |
- | * s — арифметическое выражение, целая часть значения которого может быть равна 0, 1, 2, 3; это число определяет размеры спрайтов (оператор ''SCREEN, s'' не очищает экран, однако стирает образы спрайтов в памяти компьютера); | + | |
- | * 0 — матрица 8x8 масштаб 1 (по умолчанию) | + | |
- | * 1 — матрица 8x8 масштаб 2 | + | |
- | * 2 — матрица 16х16 масштаб 1 | + | |
- | * 3 — матрица 16х16 масштаб 2 | + | |
- | * z — арифметическое выражение, целая часть значения которого принадлежит отрезку [0,255] и определяет наличие звукового сопровождения клавиатуры: z=0 — звуковое сопровождение отсутствует; z≠0 — звуковое сопровождение есть (по умолчании z=1); | + | |
- | * d — арифметическое выражение, целая часть значения которого задаёт скорость обмена с дисководом, d∈{1,2}, причём если d=1, то устанавливается наиболее надёжная скорость передачи информации 1200 бит/с = 1200 бод (по умолчании); если же d=2, то скорость становится равной 2400 бод; | + | |
- | * p — арифметическое выражение, целая часть значения которого принадлежит отрезку [0,255] и указывает тип печатающего устройства (принтера): если p=0, то принтер совместим со стандартом MSX (будет распечатывать каждый символ из набора символов стандарта MSX); если же p≠0, то принтер при выводе преобразует графические символы в пробелы (по умолчании p=0). | + | |
- | * m (только для [[msx:msx_2]]) — арифметическое выражение, целая часть значения которого принадлежит отрезку [0,3], причём: | + | |
- | * если m=0, то изображение устойчивое (по умолчанию); | + | |
- | * если m=1, то изображение "дёргающееся" (монитор с через–строчной развёрткой); | + | |
- | * если m=2, то изображение устойчивое и в режимах ''SCREEN'' 5÷8 наблюдается одновременный показ двух экранных страниц (0 и 1, 2 и 3) на странице с нечётным номером (обычный монитор: поочерёдный вывод); | + | |
- | * если m=3, то изображение "дёргающееся" и в режимах ''SCREEN'' 5÷8 наблюдается одновременный показ двух экранных страниц (0 и 1, 2 и 3) на странице с нечётным номером (монитор с через–строчной развёрткой: поочерёдный вывод). | + | |
- | + | ||
- | Отметим, что неиспользуемые параметры в операторе можно не указывать, но если они не последние в записи, то ограничивающие их запятые обязательны. При этом, каждый назначенный параметр действует до тех пор, пока не получит новое значение в последующем операторе ''SCREEN''. | + | |
- | + | ||
- | Все значения параметры, кроме размера спрайтов можно сохранить командой ''[[07#setscreen|SET SCREEN]]''. | + | |
- | + | ||
- | ---- | + | |
- | + | ||
- | * [[bibliography#b95|[95]]] (стр. 200) | + | |
- | * [[bibliography#b99|[99]]] [[https://github.com/Konamiman/MSX2-Technical-Handbook/blob/master/md/Chapter2.md#210-additions-for-memory-switch|2.10 Additions for Memory Switch]] | + | |
- | * [[bibliography#b92|[92]]] | + | |
- | + | ||
- | Сводная таблица возможностей "экранов" ((Добавлено 2019-11-30 (примечание редактора) )) | + | |
- | ^№ экрана^ Доступность ^ Тип экрана ^ Разрешающая \\ способность ^ Возможности вывода ^^^^ | + | |
- | ^:::^:::^:::^:::^ Текст ^ Графика ^ [[#sprites|Спрайты]] ^ [[#colorsprites|Цветные спрайты]] ^ | + | |
- | | 0 | [[#screen1|MSX 1]] \\ и \\ MSX 2 | Текстовый | 240×192 | ✔ | | | | | + | |
- | | 1 |:::|:::| 256×192 | ✔ | | ✔ |:::| | + | |
- | | 2 |:::| Графический |:::| ✔ | ✔ | ✔ |:::| | + | |
- | | 3 |:::|:::| 64×48 |:::|:::|:::|:::| | + | |
- | | [[#screen4|4]] | MSX 2 |:::| 256×192 | ✔ | ✔ | ✔ | ✔ | | + | |
- | | [[#screen5|5]] |:::|:::| 256×212 |:::|:::|:::|:::| | + | |
- | | [[#screen6|6]] |:::|:::| 512×212 |:::|:::|:::|:::| | + | |
- | | [[#screen7|7]] |:::|:::|:::|:::|:::|:::|:::| | + | |
- | | [[#screen8|8]] |:::|:::| 256X212 |:::|:::|:::|:::| | + | |
- | + | ||
- | + | ||
- | __//Примеры//__: | + | |
- | <code> | + | |
- | SCREEN 1,2,0,2,0 | + | |
- | SCREEN X,Y | + | |
- | SCREEN 3,,0 | + | |
- | SCREEN 2,3,,,0 | + | |
- | </code> | + | |
- | Если какой–либо из параметров выходит за допустимый диапазон, то компьютер сообщает об ошибке: <WRAP centeralign>"Illegal function call".</WRAP> | + | |
- | + | ||
- | Запомните, что основное назначение оператора ''SCREEN'' — это определение типа экрана и размера спрайтов! | + | |
- | + | ||
- | ===== V.8. Понятие файла [5]. Вывод текстовой информации на графические экраны ===== | + | |
- | + | ||
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | Я случайно уничтожил все свои файлы! | + | |
- | <WRAP rightalign> | + | |
- | —//Крик души// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | Термин //файл// происходит от английского слова file, переводящегося на русский язык как "дело" или "досье". | + | |
- | + | ||
- | В информатике под //файлом// понимают совокупность в некотором смысле //однородных// данных, характеризующих какой–либо процесс или объект. Файлы обычно хранятся на тех или иных внешних носителях информации (дискетах или магнитных лентах). | + | |
- | + | ||
- | Далее мы будем иметь дело с //программными// файлами, состоящими из одной или нескольких программ и файлами //данных// . | + | |
- | + | ||
- | Компоненты программного файла называют //модулями// или //сегментами//. Один из них считается основным. Он в первую очередь загружается в оперативную память и управляет всем процессом обработки информации. В частности, основной модуль по мере надобности проводит автоматическую подгрузку в память других сегментов файла. Именем файла считается имя его основного модуля. Ясно, что при небольших размерах программного файла разбивать его на модули нецелесообразно. | + | |
- | + | ||
- | Нас будут интересовать два вида файлов: прямого доступа и последовательного доступа. | + | |
- | + | ||
- | Компоненты файла //прямого// доступа — это отдельные нумерованные группы значений, называемые //записями//. Запись может быть считана с внешнего носителя в //буфер// оперативной памяти и наоборот — сформирована в буфере и затем переписана во внешнюю память. Иными словами, буфер является своеобразным окном, через которое можно "рассматривать" файлы. Обращение к конкретной записи осуществляется прямым заданием её номера. | + | |
- | + | ||
- | Компоненты файла последовательного доступа называются //строками//. Каждая строка имеет специальную концевую метку и, как и запись, состоит из отдельных значений. Однако строки не нумерованы и обрабатывать их можно лишь последовательно друг за другом. Причём, запись организуется от начала или конца файла, а чтение — только от его начала. | + | |
- | + | ||
- | Теперь перейдём к делу! | + | |
- | + | ||
- | Схемы, графики, рисунки или их отдельные фрагменты, выводимые на графические экраны, обычно нуждаются в обозначениях и поясняющих сообщениях. Сформировать их оператором ''PRINT'' невозможно! В режимах ''SCREEN 2'' ÷ ''SCREEN 8'' последний не действует. | + | |
- | + | ||
- | Однако эту процедуру можно осуществить путём совместного применения в программе четырёх операторов: | + | |
- | *<WRAP> α) {{anchor:maxfiles}}<WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | MAXFILES=α | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''MAX'' ("MAXimum" — "наибольший") и ''FILES'' ("файлы") — служебные слова; | + | |
- | * α — арифметическое выражение, целая часть значения которого принадлежит отрезку [1,15]. | + | |
- | Оператор резервирует (объявляет) INT(α)+1 участков оперативной памяти для последующего временного хранения //записей// конкретных файлов. | + | |
- | + | ||
- | Эти участки называются //буферами//. | + | |
- | + | ||
- | При выполнении оператора'' MAXFILES='' кроме резервирования буферов производится "чистка" значений переменных и закрытие всех ранее открытых файлов данных. | + | |
- | </WRAP> | + | |
- | * {{anchor:open}} <WRAP>β) <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | OPEN"GRP:"[FOR OUTPUT]AS[#] N | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''OPEN''("открыть"), FOR("для"), OUTPUT("вывод"), AS("как") — служебные слова; | + | |
- | * "GRP:" — имя устройства вывода, которое передаёт информацию на графический экран (SCREEN 2 ÷ SCREEN 8); | + | |
- | * N — арифметическое выражение, целая часть значения которого определяет номер файла от 0 до значения, задаваемого оператором ''MAXFILES=''. | + | |
- | + | ||
- | Этот оператор начинает процесс ввода–вывода файла. Вы должны выполнить его до использования любого процесса, связанного с выводом файла. | + | |
- | + | ||
- | Если файл был уже "открыт" оператором ''OPEN'', то компьютер сообщает об ошибке: <WRAP centeralign>"File already open in …" \\ (//"Файл уже открыт в строке …"//).</WRAP> | + | |
- | </WRAP> | + | |
- | * {{anchor:print1}}<WRAP>γ) <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | PRINT #N, A | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * A — список арифметических и строковых выражений (разделённых запятыми или точками с запятой), значения которых выводятся на графические экраны; | + | |
- | * N — номер файла, "открытого" ранее оператором ''OPEN''. | + | |
- | Отметим, что вывод на экран происходит побайтно (посимвольно). | + | |
- | Применение оператора ''PRINT#…'' без оператора ''OPEN'' приводит к сообщению об ошибке: <WRAP centeralign> File not open in …" \\ (//"Файл не открыт в строке …"//).</WRAP> | + | |
- | Напомним также, что "обычный" оператор ''PRINT'' (без указания параметра //номер файла//) в графических экранах игнорируется! | + | |
- | </WRAP> | + | |
- | * {{anchor:close}}<WRAP>δ) <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | CLOSE [[#] N] | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | * ''CLOSE'' ("закрыть") — служебное слово; | + | |
- | * N — номер файла, "открытого" оператором ''OPEN''. | + | |
- | Если оператор ''CLOSE'' задан без параметров, то закрываются все открытые с помощью оператора ''OPEN'' файлы. | + | |
- | + | ||
- | //Закрытие файла// означает, что все данные, оставшиеся в буфере, читаются, все операции вывода прекращаются и буфер освобождается. | + | |
- | + | ||
- | Заметим, что оператор ''END'' выполняет неявный вызов оператора ''CLOSE'' для всех файлов. | + | |
- | </WRAP> | + | |
- | + | ||
- | Таким образом, последовательность операторов при выводе текстовой или цифровой информации на графический экран может выглядеть, например, следующим образом: | + | |
- | + | ||
- | {{anchor:e058-01}} __//Пример 1//__. \\ {{.examples:058-01.bas|}} \\ [[+tab|wmsxbpge>058-01.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 2 'Можно и SCREEN 8 | + | |
- | 20 OPEN "GRP:" AS #1 | + | |
- | 30 PSET(20,20) 'Можно и PRESET(20,20) | + | |
- | 40 PRINT #1,PEEK(&HF3E9);PEEK(&HF3EA);PEEK(&HF3EB) | + | |
- | 50 CLOSE #1 | + | |
- | 60 GOTO 60 'Данная программа позволяет вывести на графический экран текущий цвет изображения, фона и бордюра | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e058-02}} __//Пример 2//__. \\ {{.examples:058-02.bas|}} \\ [[+tab|wmsxbpge>058-02.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,11,7:SCREEN 2:MAXFILES=2 | + | |
- | 20 OPEN "GRP:" FOR OUTPUT AS#1 | + | |
- | 30 PSET (69,80),11:PRINT #1,"РИС 9.1 ЦВЕТА" | + | |
- | 50 FOR I=1 TO 1000:NEXT I:CLOSE #1 | + | |
- | 60 SCREEN 3:OPEN "GRP:"FOR OUTPUT AS#2 | + | |
- | 80 PSET (50,80),11:PRINT #2,"БУКВЫ" | + | |
- | 100 FOR I=1 TO 1000:NEXT I:CLOSE #2 | + | |
- | </code> | + | |
- | + | ||
- | Обратите внимание на то, что первые операторы строк 30 и 80 указывают то место экрана, с которого начинается текст, т.к. текст позиционируется так, что первый символ размещается с верхней левой точки позиции графического курсора. | + | |
- | + | ||
- | Заметим, что предложенный способ позволяет выводить символы //только// фиксированного формата в блоках точек размером 8×8. Если требуется регулировать и __размер букв__, и расстояние между ними, то используйте оператор ''DRAW'' ! | + | |
- | В режимах ''SCREEN 2'', ''SCREEN 3'' и ''SCREEN 4'' символы при выводе "накладываются" на прежнее "содержимое" экрана (включая ранее выведенные символы). Поэтому, чтобы уничтожить строку символов, либо нарисуйте прямоугольник и закрасьте его цветом фона, либо выведите оператором ''PRINT#1, …'' ту же самую строку на прежнее место с помощью символов, имеющих цвет фона. | + | |
- | + | ||
- | {{anchor:e058-03}} __//Пример 3//__. \\ {{.examples:058-03.bas|}} \\ [[+tab|wmsxbpge>058-03.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,11,7:SCREEN2:OPEN "GRP:"FOR OUTPUT AS #1 | + | |
- | 30 PSET (69,80),11:PRINT #1,"Рис 9.1 ЦВЕТА":GOSUB 1000'──▶ | + | |
- | 55 LINE(69,80)-(100,87),11,BF 'Нарисован прямоугольник,внутренняя часть которого закрашена цветом фона. | + | |
- | 56 GOSUB 1000'──▶ | + | |
- | 60 COLOR 11,11,7:PSET (69,80),11:PRINT #1,"Рис 9.1 ЦВЕТА" | + | |
- | 68 GOSUB 1000'──▶ | + | |
- | 69 COLOR 1,11,7:PSET (69,80),11:PRINT #1,"БУКВЫ" | + | |
- | 100 FOR I=1 TO 1000:NEXT:CLOSE#1 | + | |
- | 110 END | + | |
- | 1000 FOR I=1 TO 1000:NEXT:RETURN '──▶ | + | |
- | </code> | + | |
- | + | ||
- | Вначале на экране появляется надпись | + | |
- | Рис 9.1 ЦВЕТА | + | |
- | затем | + | |
- | 9.1 ЦВЕТА | + | |
- | далее экран становится чистым, и после паузы возникает надпись | + | |
- | БУКВЫ | + | |
- | А в режимах ''SCREEN 5'', ''SCREEN 6'', ''SCREEN 7'' и ''SCREEN 8'' наложения символов не происходит! | + | |
- | + | ||
- | Попробуйте "прогнать" следующий пример при различных значениях N (2÷8): | + | |
- | + | ||
- | {{anchor:e058-04}} __//Пример 4//__. \\ {{.examples:058-04.bas|}} \\ [[+tab|wmsxbpge>058-04.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 INPUT "Режим экрана";N:SCREEN N:OPEN"GRP:" AS#1 | + | |
- | 20 PRESET(90,90):PRINT#1,"Мама мыла" | + | |
- | 30 FOR T=0 TO 500:NEXT 'Задержка | + | |
- | 40 PRESET(90,90):PRINT#1,"раму" | + | |
- | 50 GOTO 50 | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e058-05}} __//Пример 5//__. \\ {{.examples:058-05.bas|}} \\ [[+tab|wmsxbpge>058-05.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN2:OPEN"GRP:"AS#1:LINE(20,40)-(70,90),1 | + | |
- | 25 PRINT#1,"Дядя Миша";:A$=INPUT$(1):SCREEN0 | + | |
- | 40 PRINT PEEK(&HFCB7);PEEK(&HFCB9) | + | |
- | 50 PRINT PEEK(&HFCB3);PEEK(&HFCB5) | + | |
- | run | + | |
- | ·150··90 | + | |
- | ·70··90 | + | |
- | Ok | + | |
- | </code> | + | |
- | + | ||
- | Эта программа позволяет узнать координаты (X,Y) графического курсора и координаты (α,β) т.н. графического //аккумулятора//. Когда мы рисуем точку (или линию), графический курсор и графический аккумулятор совпадает. Различия возникают лишь при выводе текстовой информации. Графический курсор устанавливается в ту точку, которую мы вывели последний раз (оператором ''PSET'', ''LINE'', ''CIRCLE'', …). Графический аккумулятор устанавливается на то место, с которого должна быть напечатана очередная буква (уберите из строки 25 символ «;»). Как только после оператора ''PRINT#…'' мы рисуем точку (''PSET'', ''LINE'', …), графический курсор сразу же переходит в позицию графического аккумулятора, и далее они действуют совместно до нового оператора ''PRINT#''. | + | |
- | + | ||
- | {{anchor:e058-06}} __//Пример//__ [[bibliography#b76|[76]]]. Сочетание текста и иллюстраций. \\ {{.examples:058-06.bas|}} \\ [[+tab|wmsxbpge>058-06.bas]] | + | |
- | <code> | + | |
- | 40 COLOR 15,15,15:SCREEN 2:OPEN"GRP:"AS#1 | + | |
- | 70 LINE(0,0)-(255,191),1,B:LINE(120,0)-(120,191),1:PRESET(8,32) | + | |
- | 100 FOR I=1 TO 14 | + | |
- | 110 COLOR I:PRINT #1,"MSX COMPUTERS":PRESET STEP (8,0) | + | |
- | 140 NEXT I | + | |
- | 150 PRESET(164,16):COLOR 1:PRINT #1,"Круг" | + | |
- | 180 CIRCLE(188,64),30:PAINT(188,64) | + | |
- | 200 PRESET(128,112):COLOR 8:PRINT #1,"Квадрат" | + | |
- | 230 LINE(136,124)-STEP(40,40),8,BF | + | |
- | 240 PRESET(160,102):COLOR 4:PRINT #1,"Треугольник" | + | |
- | 270 LINE(208,118)-STEP(30,30):LINE-STEP(-30,0):LINE-STEP(0,-30) | + | |
- | 300 GOTO 300 | + | |
- | </code> | + | |
- | {{anchor:e058-07}} __//Пример//__ [[bibliography#b77|[77]]]. Ввод данных в графическом режиме. \\ {{.examples:058-07.bas|}} \\ [[+tab|wmsxbpge>058-07.bas]] | + | |
- | <code> | + | |
- | 40 COLOR 15,15,15:SCREEN 2,0,0:OPEN"GRP:"AS #1 | + | |
- | 70 LINE (0,0)-STEP(255,191),1,B | + | |
- | 80 PRESET (8,8):COLOR 1:PRINT #1,"Радиус:"; | + | |
- | 110 N$="" | + | |
- | 120 X=80 | + | |
- | 130 PRESET(X,8) | + | |
- | 140 A$=INPUT$(1) | + | |
- | 150 IF A$=CHR$(13) THEN GOTO 250 | + | |
- | 170 'Подтверждение ввода | + | |
- | 190 IF A$<"0" OR A$>"9" THEN PLAY"l24o2c":GOTO 130 | + | |
- | 200 PRINT #1,A$;:N$=N$+A$:X=X+8 | + | |
- | 210 GOTO 130 | + | |
- | 230 'Изображение о к р у ж н о с т и | + | |
- | 250 R=VAL(N$) | + | |
- | 260 IF R>80 THEN BEEP:GOTO 280 | + | |
- | 270 CIRCLE (128,100),R | + | |
- | 280 LINE (80,8)-STEP(56,8),15,BF | + | |
- | 290 GOTO 110 | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:screen4}} | + | |
- | ===== V.9. Режим SCREEN 4 (только для компьютера MSX 2) ===== | + | |
- | + | ||
- | Этот режим идентичен режиму ''SCREEN 2'' в том, что касается выбора цвета, графических операторов и отображения текста (см. [[#pict_05_06|рис.6]]). | + | |
- | + | ||
- | {{anchor:pict_05_06}} | + | |
- | <code> | + | |
- | 0 255 | + | |
- | 0┌───────────────────┐──▶X | + | |
- | │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ | + | |
- | │▨▨▨▨▨ SCREEN4 ▨▨▨▨▨│ | + | |
- | │▨▨▨ 256×192 точек▨▨│ | + | |
- | │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ | + | |
- | 191│─ ─ ─ ─ ─ ─ ─ ─ ─ ─┘ | + | |
- | ▼ | + | |
- | Y | + | |
- | </code> | + | |
- | __//Рис. 6//__ | + | |
- | + | ||
- | FIXME {{anchor:colorsprites}} Цветные спрайты | + | |
- | + | ||
- | В режиме ''SCREEN 4'', однако, имеются //новые// операторы для работы со спрайтами. | + | |
- | * <WRAP> {{anchor:colorsprite1}} A) Оператор ''COLOR SPRITE$'' предоставляет Вам возможность изображать //многоцветный// спрайт (один цвет на линию). | + | |
- | + | ||
- | В режиме ''SCREEN 2'' для получения такого же результата обычно накладываются несколько спрайтов (см. [[#V.6.2. Вывод спрайта на экран|раздел V.6.2.]]). | + | |
- | + | ||
- | Оператор, с которым мы хотим Вас познакомить, имеет следующий формат: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | COLOR SPRITE$(NS)=A$ | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''COLOR'', ''SPRITE'' — служебные слова; | + | |
- | * NS — арифметическое выражение, целая часть значения которого определяет номер сформированного в оперативной памяти спрайта; | + | |
- | * A$ — строковое выражение, причём значение А$ должно содержать не более 16 символов (LEN(A$)≤16). | + | |
- | Каждый символ значения строки A$ воздействует на одну линию спрайта (или как говорят, //спрайтовую// линию). | + | |
- | + | ||
- | Поэтому следует использовать 8 символов, когда образы спрайтов кодируются в 8 байтах (''SCREEN 4,0'' и ''SCREEN 4,1'') и 16 символов при кодировании образа спрайта в 32 байтах (''SCREEN 4,2'' и ''SCREEN 4,3''). | + | |
- | + | ||
- | Этот оператор рассматривает двоичную структуру, соответствующую коду ASCII каждого символа, и действует на каждую спрайтовую линию в соответствии со значением битов, составляющих эту структуру: | + | |
- | + | ||
- | - <WRAP> //биты// 0, 1, 2, 3. Четыре младших бита позволяют закодировать номер палитры (0÷15), присвоенный этой линии. | + | |
- | + | ||
- | {{anchor:e059-01}} __//Пример 1//__. Спрайт, у которого все 8 спрайтовых строк различного цвета. | + | |
- | \\ {{.examples:059-01.bas|}} \\ [[+tab|wmsxbpge>059-01.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 4,1:SPRITE$(0)=STRING$(8,255):PUT SPRITE 0,(128,96),8,0 | + | |
- | 40 COLOR SPRITE$(0)=CHR$(1)+CHR$(2)+CHR$(3)+CHR$(4)+CHR$(5)+CHR$(6)+CHR$(7)+CHR$(8) | + | |
- | 50 GOTO 50 | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | - //бит// 4. Этот бит не используется. | + | |
- | - <WRAP> //бит// 5. Если этот бит равен 1, то столкновение спрайтов (оператор ''[[#onspritegosub|ON SPRITE GOSUB]]'') не обнаруживается. | + | |
- | {{anchor:e059-02}} __//Пример 2//__. "Поведение" спрайтов в зависимости от значения пятого бита. | + | |
- | \\ {{.examples:059-02.bas|}} \\ [[+tab|wmsxbpge>059-02.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 15,4:SCREEN 4:SPRITE$(0)=STRING$(8,255) | + | |
- | 30 PUT SPRITE 0,(200,100),15,0 | + | |
- | 40 ON SPRITE GOSUB 100 │ Обратите внимание на этот бит! | + | |
- | 50 SPRITE ON ▼ | + | |
- | 55 COLOR SPRITE$(0)=STRING$(8,&B00100001) | + | |
- | 60 FOR X=0 TO 240:PUT SPRITE 1,(X,100),15,0:NEXT | + | |
- | 90 GOTO 60 | + | |
- | 100 SCREEN 0:RETURN 10 | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | - <WRAP> //бит// 6. Если этот бит равен 1, то пересечение спрайтовой линии спрайта с номером NS с другими спрайтами не будет обнаружено. Правило приоритета (если "накладываются" два спрайта, то спрайт с меньшим "экранным" номером перекрывает спрайт с большим "экранным" номером) более не соблюдается. Оказывается область пересечения спрайтов имеет цвет, определяемый результатом логической операции OR (ИЛИ), применённой к цветам "наложенных" спрайтов. | + | |
- | + | ||
- | Более того, спрайтовые линии, отмеченные в операторе ''[[#colorsprite1|COLOR SPRITE$]]'' и не "затронутые" пересечением, исчезают! | + | |
- | + | ||
- | {{anchor:e059-03}} __//Пример3//__. Пример, иллюстрирующий "работу" бита 6 спрайтовой линии. | + | |
- | \\ {{.examples:059-03.bas|}} \\ [[+tab|wmsxbpge>059-03.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 4,3 'Область пересечения спрайтов окрашена цве- | + | |
- | 20 SPRITE$(0)=STRING$(32,255)'том с номером 11, так как 9 OR 10 = 11 | + | |
- | 30 PUT SPRITE 0,(100,100),,0 'В спрайте 1 6-й бит установлен в единицу, | + | |
- | 40 PUT SPRITE 1,(120,120),,0 'поэтому линии, не пересекающиеся со | + | |
- | 45 A$=INKEY$:IF A$=""THEN 45 'спрайтом 2, исчезают! | + | |
- | 50 COLOR SPRITE$(0)=STRING$(16,&b00001001) | + | |
- | 60 COLOR SPRITE$(1)=STRING$(16,&b01001010) | + | |
- | 70 GOTO 70 ▲ | + | |
- | └── !!! | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | - <WRAP> //бит// 7 (крайний левый). Если этот бит равен 1, то спрайтовая линия отображается на 32 точки левее координаты Х, заданной в операторе ''[[#putsprite|PUT SPRITE]]''; | + | |
- | + | ||
- | {{anchor:e059-04}} __//Пример 4//__. Сдвиг двух верхних спрайтовых линий с изменением цвета. | + | |
- | \\ {{.examples:059-04.bas|}} \\ [[+tab|wmsxbpge>059-04.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15:SCREEN 4,1 | + | |
- | 20 SPRITE$(0)=STRING$(8,255) | + | |
- | 30 SC$=CHR$(&B10000011)+CHR$(&B10000001) | + | |
- | 40 PUT SPRITE 0,(120,85),13,0 | + | |
- | 50 IF INKEY$="" THEN 50 'Ожидание! | + | |
- | 60 COLOR SPRITE$(0)=SC$ | + | |
- | 70 GOTO 70 | + | |
- | </code> | + | |
- | + | ||
- | <code> | + | |
- | не используется | + | |
- | │ | + | |
- | ▼ | + | |
- | 1 0 0 0 0 0 1 1 | + | |
- | ▲ ────▲───── | + | |
- | │ │ | + | |
- | сдвиг номер | + | |
- | спрайтовой линии палитры | + | |
- | + | ||
- | </code> | + | |
- | Установите, что произойдёт при нажатии любой клавиши!? | + | |
- | </WRAP> | + | |
- | {{anchor:e059-05}} __//Пример 5//__. | + | |
- | \\ {{.examples:059-05.bas|}} \\ [[+tab|wmsxbpge>059-05.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 4,1 | + | |
- | 20 SPRITE$(0)=STRING$(8,255) | + | |
- | 30 SC$=CHR$(&b01000111)+CHR$(&b01000111)+CHR$(&b01000111) | + | |
- | 40 PUT SPRITE 0,(120,85),8,0:PUT SPRITE 1,(130,95),7,0 | + | |
- | 50 IF INKEY$="" THEN 50 | + | |
- | 60 COLOR SPRITE$(1)=SC$ | + | |
- | 70 GOTO 70 | + | |
- | </code> | + | |
- | <code> | + | |
- | не соблюдается | + | |
- | правило наложения | + | |
- | спрайтов | + | |
- | │ не используется | + | |
- | │ │ | + | |
- | ▼ ▼ | + | |
- | 0 1 0 0 0 1 1 1 | + | |
- | ▲ ────▲───── | + | |
- | │ │ | + | |
- | отсутствие сдвига номер | + | |
- | спрайтовой линии палитры | + | |
- | </code> | + | |
- | Спрайт 0 изображается красным цветом (8), а спрайт 1 — темно–синим (7). При нажатии любой клавиши, все линии спрайта 1, находящиеся "под" спрайтом 0, сохраняются, остальные "исчезают"(цвет пересечения — //белый//, так как 7 OR 8 = 15). \\ | + | |
- | Обратите внимание, что оператор ''COLOR SPRITE$'' в строке 60 "применяется" к спрайту с "экранным" номером 1. | + | |
- | + | ||
- | {{anchor:e059-06}} __//Пример 6//__. | + | |
- | \\ {{.examples:059-06.bas|}} \\ [[+tab|wmsxbpge>059-06.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 1,15:SCREEN 4,1 | + | |
- | 20 SPRITE$(0)=STRING$(8,255):SPRITE$(1)=STRING$(8,255) | + | |
- | 30 SC$=STRING$(8,&B11100100):T=255 | + | |
- | 40 FOR I=1 TO 190:PUT SPRITE 0,(I,95),1,0 | + | |
- | 45 IF T=I THEN COLOR SPRITE$(0)=SC$:FOR A=1 TO 300:NEXTA | + | |
- | 50 PUT SPRITE 1,(T,95),5,1:T=T-1:NEXTI | + | |
- | 60 GOTO 60 | + | |
- | </code> | + | |
- | Если исправить 30–ю строку следующим образом: | + | |
- | 30 SC$=STRING$(4,&B11100100):T=255 | + | |
- | то при столкновении двух спрайтов спрайт с меньшим "экранным" номером вначале уменьшится в два раза, а затем восстановит свои размеры. | + | |
- | + | ||
- | {{anchor:e059-07}} __//Пример 7//__. Уменьшение и увеличение "высоты" спрайта при нажатии любой клавиши. | + | |
- | \\ {{.examples:059-07.bas|}} \\ [[+tab|wmsxbpge>059-07.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 15,0,0:SCREEN 4,1 | + | |
- | 20 DATA 255,255,255,255,255,255,255,255 | + | |
- | 30 READ A:FOR I=0 TO 7:Y$=Y$+CHR$(A):NEXT | + | |
- | 40 SPRITE$(1)=Y$ | + | |
- | 50 PUT SPRITE 1,(110,80),13,1 | + | |
- | 60 E$="1" | + | |
- | 70 A$=INKEY$:IF A$="" THEN 70 | + | |
- | 80 COLOR SPRITE$(1)=E$ | + | |
- | 90 IF LEN(E$)<=8 THEN E$=E$+"0":GOTO 70 ELSE 50 | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | * <WRAP>{{anchor:colorsprite}} B) Оператор ''COLOR SPRITE'' очень похож на оператор ''[[#colorsprite1|COLOR SPRITE$]]'', но действует на всех спрайтовых линиях спрайта с номером NS. | + | |
- | Формат оператора: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | COLOR SPRITE(NS) = B | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''COLOR'', ''SPRITE'' — служебные слова; | + | |
- | * NS — арифметическое выражение, целая часть значения которого определяет номер сформированного в оперативной памяти спрайта; | + | |
- | * B — арифметическое выражение, целая часть значения которого должна лежать в пределах от 0 до 127. | + | |
- | Отметим, что если Вам необходимо передвинуть спрайт на 32 точки влево, то используйте только оператор ''[[#colorsprite1|COLOR SPRITE$]]'' ! | + | |
- | + | ||
- | Когда значение выражения B находится между 0 и 15, операторы: | + | |
- | * ''PUT SPRITE 0,(X,Y),B'' | + | |
- | * ''COLOR SPRITE$(0)=STRING$(8,B)'' | + | |
- | * ''COLOR SPRITE(0)=B'' | + | |
- | эквивалентны! | + | |
- | + | ||
- | {{anchor:e059-08}} __//Пример 8//__. Исчезновение спрайта с меньшим экранным номером при ''COLOR SPRITE(0)=127'' и изменение цвета области пересечения спрайтов при ''COLOR SPRITE(0)=63''. | + | |
- | \\ {{.examples:059-08.bas|}} \\ [[+tab|wmsxbpge>059-08.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 4,1:SPRITE$(0)=STRING$(8,255):T=255 | + | |
- | 40 FOR I=1 TO 155:PUT SPRITE 0,(I,95),1,0:A=I+1 | + | |
- | 50 IF T=I THEN COLOR SPRITE(0)=127:FOR A=1 TO 300:NEXTA | + | |
- | 60 PUT SPRITE 1,(T,95),7,0:T=T-1:NEXTI | + | |
- | 70 GOTO 70 | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e059-09}} __//Пример 9//__. | + | |
- | \\ {{.examples:059-09.bas|}} \\ [[+tab|wmsxbpge>059-09.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 15,4:SCREEN 4,1:SPRITE$(0)=STRING$(8,255) | + | |
- | 30 SC=&B01001111 'Замените на SC=&B00001111 | + | |
- | 40 PUT SPRITE 0,(120,85),13,0 ▲ | + | |
- | 50 IF INKEY$="" THEN 50 │ | + | |
- | 60 COLOR SPRITE(0)=SC Обратите внимание на нулевой шестой бит! | + | |
- | 70 GOTO 70 | + | |
- | </code> | + | |
- | Заметим, что когда значение B принадлежит отрезку [0,127], то операторы ''COLOR SPRITE$(0)=STRING(8,B)'' и ''COLOR SPRITE(0)=B'' //эквивалентны//, однако, если значение B находится в диапазоне от 128 до 255, или когда необходимо воздействовать на отдельные линии спрайта, следует воспользоваться первым оператором. | + | |
- | + | ||
- | {{anchor:e059-10}} __//Пример 10//__. Столкновение спрайтов для оператора ''COLOR SPRITE(NS)=B'' | + | |
- | \\ {{.examples:059-10.bas|}} \\ [[+tab|wmsxbpge>059-10.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 15,4:SCREEN 4:SPRITE$(0)=STRING$(8,255) | + | |
- | 30 PUT SPRITE 0,(200,100),15,0 | + | |
- | 40 ON SPRITE GOSUB 100:SPRITEON' Включен режим прерываний по столкнове- | + | |
- | 55 COLOR SPRITE(0)=&B00100001' нию спрайтов! | + | |
- | 60 FOR X=0 TO 240:PUT SPRITE 1,(X,100),15,0:NEXT ▲ | + | |
- | 90 GOTO 60 '──▶ │ | + | |
- | 100 SCREEN 0:RETURN 10 Обратите внимание на единичный пятый бит! | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | + | ||
- | {{anchor:screen5}} | + | |
- | ===== V.10. Режим SCREEN 5 (только для компьютера MSX 2) ===== | + | |
- | + | ||
- | Этот режим предлагает те же возможности работы со спрайтами, что и режим ''SCREEN 4''. Он отличается от режима ''SCREEN 4'' в двух пунктах: | + | |
- | * <WRAP> α) //разрешение и выбор цвета//. | + | |
- | + | ||
- | Экран разделен на 212 строк по 256 точек (см. [[#pict_05_07|рис.7]]). | + | |
- | {{anchor:pict_05_07}} | + | |
- | <code> | + | |
- | 0 255 | + | |
- | 0┌───────────────────┐──▶X | + | |
- | │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ | + | |
- | │▨▨▨▨▨ SCREEN5 ▨▨▨▨▨│ | + | |
- | │▨▨▨ 256×212 точек▨▨│ | + | |
- | │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ | + | |
- | 211│─ ─ ─ ─ ─ ─ ─ ─ ─ ─┘ | + | |
- | ▼ | + | |
- | Y | + | |
- | </code> | + | |
- | __//Рис. 7//__ | + | |
- | + | ||
- | Цвет присваивается каждой точке, причём допустимых палитр — 16. | + | |
- | </WRAP> | + | |
- | * <WRAP> β) //экранные страницы//. | + | |
- | + | ||
- | В режиме ''SCREEN 5'' в Вашем распоряжении имеется несколько так называемых //экранных страниц//. Их количество зависит от объёма видеопамяти, причём, если видеопамять имеет объем 64 Kбайт, то в Вашем распоряжении 2 страницы (с номерами 0 и 1); если же — 128 Кбайт, то — 4 страницы (с номерами от 0 до 3). | + | |
- | </WRAP> | + | |
- | + | ||
- | {{anchor:setpage}} | + | |
- | Рассмотрим оператор ''SET PAGE'', посредством которого можно определять: | + | |
- | - страницу для //отображения// на экране и | + | |
- | - страницу для //воздействия// (//активную// страницу). | + | |
- | На активной странице можно "рисовать" с помощью графических операторов. | + | |
- | + | ||
- | Формат этого интересного оператора: | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | SET PAGE [M],[N] | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''SET'', ''PAGE'' — служебные слова; | + | |
- | * M, N — арифметические выражения, целые части значения которых принадлежат отрезку [0,3]. Первый аргумент SET PAGE указывает номер отображаемой страницы, а второй — номер активной страницы. | + | |
- | + | ||
- | {{anchor:e0510-01}} __//Пример 1//__. | + | |
- | \\ {{.examples:0510-01.bas|}} \\ [[+tab|wmsxbpge>0510-01.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 5:OPEN "GRP:" AS #1 | + | |
- | 30 SET PAGE 0,0:CLS:PSET(100,100):PRINT #1,"ABCD" 'Страница 0 отображается и активизируется (ситуация - по умолчанию). На страницу 0 записывается небольшой текст. | + | |
- | 50 FOR I=1 TO 1000:NEXT:SET PAGE 1,1:CLS 'Страница 1 отображается и активизируется; рисуются 8 линий. | + | |
- | 60 FOR I=0 TO 7:FOR J=0 TO 127 | + | |
- | 70 PSET(2*J,I+108),I+2:PSET STEP(1,0),I+3:NEXTJ,I: P=1 | + | |
- | 90 IF INKEY$="" THEN 90 ' Ожидание нажатия клавиши! Если клавиша нажата,то номер (P) отображенной страницы изменяется оператором XOR | + | |
- | 100 P=P XOR 1:SET PAGE P,P 'Листание страниц! | + | |
- | 120 GOTO 90 '──▶ | + | |
- | </code> | + | |
- | Напомним Вам диаграмму Вейча (таблицу истинности функции XOR): | + | |
- | ^ X | 0 | 1 | 0 | 1 | | + | |
- | ^ Y | 0 | 0 | 1 | 1 | | + | |
- | ^ X XOR Y | 0 | 1 | 1 | 0 | | + | |
- | + | ||
- | {{anchor:e0510-02}} __//Пример 2//__. | + | |
- | \\ {{.examples:0510-02.bas|}} \\ [[+tab|wmsxbpge>0510-02.bas]] | + | |
- | <code> | + | |
- | Ok | + | |
- | 10 SCREEN 5 | + | |
- | 20 FOR M=0 TO 3:SET PAGE M,M:CLS:NEXT | + | |
- | 30 FOR K=0 TO 160 STEP 10:FOR Q=0 TO 5 | + | |
- | 50 SET PAGE 0,0:CIRCLE(127,106),K+Q,15 | + | |
- | 60 SET PAGE 1,1:CIRCLE(127,106),K+Q+2,15 | + | |
- | 70 SET PAGE 2,2:CIRCLE(127,106),K+Q+5,15 | + | |
- | 80 SET PAGE 3,3:CIRCLE(127,106),K+Q+7,15 | + | |
- | 90 NEXT:NEXT | + | |
- | 100 FOR K=0 TO 3:SET PAGE K,K:NEXT:GOTO 100 | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e0510-03}} __//Пример 3//__. Бегущий человечек. | + | |
- | \\ {{.examples:0510-03.bas|}} \\ [[+tab|wmsxbpge>0510-03.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 5 | + | |
- | 20 SET PAGE 0,0:CLS | + | |
- | 30 DRAW"bm100,100 c11 d5 r1 d2 r1 bm100,104 l2 d1 l2 d1 bm99,103 u1 l2 d1 l1 bm100,103 r2 u1 bm101,100 d1" | + | |
- | 40 SET PAGE 0,1:CLS | + | |
- | 50 DRAW"bm100,100 c11 r1 d1 l1 d4 l1 d1 g1 e1 u4 l1 g1 e1 r2 d1 r1 l1 d2 r1 d1 g1" | + | |
- | 60 SET PAGE 0,2:CLS | + | |
- | 70 DRAW"bm100,100 r1 d1 l1 d6 l1 u1 l2 r3 u1 r1 l1 u1 l1 u2 d1 l1" | + | |
- | 90 SET PAGE 0,3:CLS | + | |
- | 100 DRAW"bm100,100 r1 d1 l1 d4 f1 g1 h1 g1 e1 u4 l1 g1 d1 bm100,100 d3 r1" | + | |
- | 110 FOR I=0 TO 3:SET PAGE I,I | + | |
- | 120 FOR T=0 TO 100:NEXT:NEXT | + | |
- | 140 GOTO 110 '──▶ | + | |
- | </code> | + | |
- | + | ||
- | Любопытную возможность для работы с экранными страницами предоставляет оператор ''SCREEN,,,,,N'' (пять запятых!). Целая часть выражения, задающего параметр N, должна принадлежать интервалу [0,3] и по умолчанию равна нулю. | + | |
- | Этот аргумент определяет: | + | |
- | - форму развёртки изображения. Если N=0 или 2, то изображение стабильное. Если же N=1 или 3, то экран "дрожит", как у ПЭВМ типа "Wang–2200"; | + | |
- | - быстрый поочерёдный показ двух экранных страниц. Если N=0 или 1, то ничего нового не наблюдается. Если N=2 или 3, то происходит следующее: \\ на экранной странице с номером 1 происходит быстрое чередование изображения нулевой и первой страниц, сливающееся в одну дрожащую картинку. Одновременно с этим происходит аналогичный процесс на странице с номером 3 (в этом случае на страницу с номером 3 накладывается изображение 2–й страницы). | + | |
- | + | ||
- | Взгляните на следующий пример: | + | |
- | + | ||
- | {{anchor:e0510-04}} __//Пример 4//__. | + | |
- | \\ {{.examples:0510-04.bas|}} \\ [[+tab|wmsxbpge>0510-04.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 5,,,,,0:SET PAGE 1,0:CLS:CIRCLE(120,100),10 | + | |
- | 20 SET PAGE 1,1:CLS:CIRCLE(120,100),50 | + | |
- | 30 A$=INPUT$(1) 'Задержка до нажатия клавиши | + | |
- | 40 SCREEN ,,,,,2 'Обратите внимание на величину последнего параметра! | + | |
- | 50 A$=INPUT$(1) | + | |
- | </code> | + | |
- | + | ||
- | Обратим Ваше внимание на то, как можно осуществить //копирование// изображения из одной области экрана в другую на компьютерах серии [[msx:msx_1]]. | + | |
- | + | ||
- | Для этого нужен двухмерный массив. Первый этап работы состоит в определении размеров копируемой области и создании массива требуемой размерности. В этом массиве хранятся значения цветов каждой точки копируемого изображения, которые находятся с помощью функции ''POINT''. Затем эти данные используются в операторе ''PSET'' для переноса отмеченных точек в другое место экрана. | + | |
- | + | ||
- | {{anchor:e0510-05}} __//Пример 5//__ [[bibliography#b76|[76]]]. Копирование участка экрана | + | |
- | \\ {{.examples:0510-05.bas|}} \\ [[+tab|wmsxbpge>0510-05.bas]] | + | |
- | <code> | + | |
- | 20 CLEAR:DEFINT A-Z | + | |
- | 40 'Массив для графических данных | + | |
- | 50 DIM A(50,50):BC=1:SC=15:COLOR 15,1,1:SCREEN 2 | + | |
- | 90 ON INTERVAL=100 GOSUB 490 | + | |
- | 100 OPEN"GRP:"AS #1 | + | |
- | 110 LINE (60,0)-STEP(150,10),15,BF:PSET(65,1):COLOR 1 | + | |
- | 130 PRINT #1,"Копирование экрана" | + | |
- | 140 COLOR 15 | + | |
- | 150 'Изображение | + | |
- | 160 LINE(80,80)-(130,130),15,BF:LINE(82,82)-(128,128),1,B | + | |
- | 180 FOR I=2 TO 12 STEP 2 | + | |
- | 190 CIRCLE(105,105),20,1,,,12/I:CIRCLE(105,105),20,1,,,I/12 | + | |
- | 210 NEXT I | + | |
- | 220 'Заполнение массива | + | |
- | 230 INTERVAL ON | + | |
- | 240 FOR I=1 TO 50:FOR J=1 TO 50 | + | |
- | 260 A(I,J)=POINT(80+I,80+J) | + | |
- | 270 NEXT J:NEXT I | + | |
- | 290 INTERVAL OFF | + | |
- | 300 COLOR ,,1 | + | |
- | 310 'Получение копий | + | |
- | 320 FOR I=1 TO 2 | + | |
- | 330 READ X,Y | + | |
- | 340 FOR J=1 TO 50:FOR K=1 TO 50 | + | |
- | 360 PSET (X+J,Y+K),A(J,K) | + | |
- | 370 NEXT K:NEXT J | + | |
- | 390 NEXT I | + | |
- | 400 'Перевернутое изображение | + | |
- | 410 FOR I=1 TO 50:FOR J=1 TO 50 | + | |
- | 430 IF A(I,J)=1 THEN C=15 ELSE C=1 | + | |
- | 440 PSET(29+I,80+J),C | + | |
- | 450 NEXT J:NEXT I | + | |
- | 470 GOTO 470 | + | |
- | 480 'Подпрограмма интервалов | + | |
- | 490 PLAY"T255L64SM1000O4CO5C" | + | |
- | 500 SWAP BC,SC:COLOR ,,SC | + | |
- | 510 RETURN | + | |
- | 520 'Значения координат | + | |
- | 530 DATA 30,28,80,28 | + | |
- | </code> | + | |
- | Заметим, что в массиве чтение и запись данных выполняются невыносимо медленно, поэтому нужно запастись терпением! | + | |
- | + | ||
- | Ниже мы познакомим Вас ещё с одним весьма мощным оператором [[msx:basic:]] — оператором ''COPY'', который пересылает блок экрана в другое место экрана (на этой же или другой странице). | + | |
- | + | ||
- | Фактически, имеется //шесть// вариантов этого оператора. | + | |
- | + | ||
- | * <WRAP> //Вариант 1// | + | |
- | <code> | + | |
- | ⎧ [T]XOR | + | |
- | ⎪ [T]OR | + | |
- | COPY (X1,Y1)-(X2,Y2),[stri] TO (X3,Y3),[strpr], ⎨ [T]AND , | + | |
- | ⎪ [T]PSET | + | |
- | ⎩ [T]PRESET | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''COPY'', ''TO'', ''XOR'', ''OR'', ''AND'', ''PSET'', ''PRESET'' — служебные слова; | + | |
- | * (X1,Y1)-(X2,Y2) — параметры, указывающие местоположение копируемого блока и "работающие" точно так же, как в операторе | + | |
- | LINE (X1,Y1)-(X2,Y2),C,B | + | |
- | (наличие этих параметров обязательно). | + | |
- | + | ||
- | Прямоугольная область экрана (//блок//), раскраска которой должна запоминаться при выполнении оператора ''COPY'', может располагаться в любом месте экрана. Форма, размер, местоположение прямоугольной области задаются координатами двух её противоположных вершин, т.е. точно так же, как в операторе ''LINE'' с параметром B задаётся подлежащий построению прямоугольник; | + | |
- | * stri — арифметическое выражение, указывающее на номер копируемой страницы (страницы — //источника//); значение stri должно принадлежать [0,3]. По умолчанию используется активная страница; | + | |
- | * (X3,Y3) — координаты верхнего левого угла места, в которое будет скопирован блок (наличие этого параметра обязательно!); | + | |
- | * strp — арифметическое выражение, указывающее на номер страницы — //приёмника//; значение strp должно принадлежать [0,3]. По умолчанию используется страница–источник; | + | |
- | * T — префикс, который //может// предшествовать ключевым словам. | + | |
- | В этом случае если копируемый блок имеет цвет 0, то блок–результат копирования не отображается на экране; \\ ''XOR'', ''OR'', ''AND'', ''PSET'', ''PRESET'' — служебные слова для определения результата комбинации цвета экрана с цветом точек копируемого блока посредством логических операций, определяемых в следующей таблице: | + | |
- | | XOR | SC = C XOR S | | + | |
- | | OR | SC = C OR S | | + | |
- | | AND | SC = C AND S | | + | |
- | | PSET | SC = C | | + | |
- | | PRESET | SC = 16+(NOT C) | | + | |
- | где S, SC, C — арифметические выражения, целые части значений которых определяют: | + | |
- | * S — цвет изображения или фона до копирования; | + | |
- | * SC — цвет изображения или фона после копирования; | + | |
- | * C — цвет копируемого рисунка. | + | |
- | По умолчанию установлен режим ''PSET''. | + | |
- | + | ||
- | Дело в том, что при выполнении оператора ''COPY'' на экране в общем случае появляются не те цвета, номера которых хранятся в заданном для этого оператора числовом массиве, а цвета, представляющие собой результат взаимодействия заданных с текущей раскраской рассматриваемой области экрана. | + | |
- | + | ||
- | Итак, существуют пять способов взаимодействия изображения, воспроизводимого оператором ''COPY'', с текущим изображением на экране дисплея. Конкретный способ выбирается путём задания в операторе ''COPY'' одного из //пяти// служебных слов: ''PSET'', ''PRESET'', ''AND'', ''OR'' или ''XOR''. | + | |
- | + | ||
- | Параметры ''AND'', ''OR'' и ''XOR'' определяют три различных набора правил, в соответствии с которыми происходит слияние заданных в операторе ''COPY'' цветов с текущей расцветкой экрана. Например, изучите следующие таблицы: | + | |
- | + | ||
- | ^ Номер\\ цвета\\ изображения ^ Цвет экрана (наличие параметра XOR) ^^^^^^^^^^^^^^^^ | + | |
- | ^:::^ 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 ^ 8 ^ 9 ^ 10 ^ 11 ^ 12 ^ 13 ^ 14 ^ 15 ^ | + | |
- | ^ 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | | + | |
- | ^ 1 | 1 | 0 | 3 | 2 | 5 | 4 | 7 | 6 | 9 | 8 | 11 | 10 | 13 | 12 | 15 | 14 | | + | |
- | ^ 2 | 2 | 3 | 0 | 1 | 6 | 7 | 4 | 5 | 10 | 11 | 8 | 9 | 14 | 15 | 12 | 13 | | + | |
- | ^ 3 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 11 | 10 | 9 | 8 | 15 | 14 | 13 | 12 | | + | |
- | ^ 4 | 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3 | 12 | 13 | 14 | 15 | 8 | 9 | 10 | 11 | | + | |
- | ^ 5 | 5 | 4 | 7 | 6 | 1 | 0 | 3 | 2 | 13 | 12 | 15 | 14 | 9 | 8 | 11 | 10 | | + | |
- | ^ 6 | 6 | 7 | 4 | 5 | 2 | 3 | 0 | 1 | 14 | 15 | 12 | 13 | 10 | 11 | 8 | 9 | | + | |
- | ^ 7 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | | + | |
- | ^ 8 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | + | |
- | ^ 9 | 9 | 8 | 11 | 10 | 13 | 12 | 15 | 14 | 1 | 0 | 3 | 2 | 5 | 4 | 7 | 6 | | + | |
- | ^ 10 | 10 | 11 | 8 | 9 | 14 | 15 | 12 | 13 | 2 | 3 | 0 | 1 | 6 | 7 | 4 | 5 | | + | |
- | ^ 11 | 11 | 10 | 9 | 8 | 15 | 14 | 13 | 12 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | | + | |
- | ^ 12 | 12 | 13 | 14 | 15 | 8 | 9 | 10 | 11 | 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3 | | + | |
- | ^ 13 | 13 | 12 | 15 | 14 | 9 | 8 | 11 | 10 | 5 | 4 | 7 | 6 | 1 | 0 | 3 | 2 | | + | |
- | ^ 14 | 14 | 15 | 12 | 13 | 10 | 11 | 8 | 9 | 6 | 7 | 4 | 5 | 2 | 3 | 0 | 1 | | + | |
- | ^ 15 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | | + | |
- | + | ||
- | ^ Номер\\ цвета\\ изображения ^ Цвет экрана (наличие параметра OR) ^^^^^^^^^^^^^^^^ | + | |
- | ^:::^ 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 ^ 8 ^ 9 ^ 10 ^ 11 ^ 12 ^ 13 ^ 14 ^ 15 ^ | + | |
- | ^ 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | | + | |
- | ^ 1 | 1 | 1 | 3 | 3 | 5 | 5 | 7 | 7 | 9 | 9 | 11 | 11 | 13 | 13 | 15 | 15 | | + | |
- | ^ 2 | 2 | 3 | 2 | 3 | 6 | 7 | 6 | 7 | 10 | 11 | 10 | 11 | 14 | 15 | 14 | 15 | | + | |
- | ^ 3 | 3 | 3 | 3 | 3 | 7 | 7 | 7 | 7 | 11 | 11 | 11 | 11 | 15 | 15 | 15 | 15 | | + | |
- | ^ 4 | 4 | 5 | 6 | 7 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | 12 | 13 | 14 | 15 | | + | |
- | ^ 5 | 5 | 5 | 7 | 7 | 5 | 5 | 7 | 7 | 13 | 13 | 15 | 15 | 13 | 13 | 15 | 15 | | + | |
- | ^ 6 | 6 | 7 | 6 | 7 | 6 | 7 | 6 | 7 | 14 | 15 | 14 | 15 | 14 | 15 | 14 | 15 | | + | |
- | ^ 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | | + | |
- | ^ 8 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | | + | |
- | ^ 9 | 9 | 9 | 11 | 11 | 13 | 13 | 15 | 15 | 9 | 9 | 11 | 11 | 13 | 13 | 15 | 15 | | + | |
- | ^ 10 | 10 | 11 | 10 | 11 | 14 | 15 | 14 | 15 | 10 | 11 | 10 | 11 | 14 | 15 | 14 |15 | | + | |
- | ^ 11 | 11 | 11 | 11 | 11 | 15 | 15 | 15 | 15 | 11 | 11 | 11 | 11 | 15 | 15 | 15 |15 | | + | |
- | ^ 12 | 12 | 13 | 14 | 15 | 12 | 13 | 14 | 15 | 12 | 13 | 14 | 15 | 12 | 13 | 14 |15 | | + | |
- | ^ 13 | 13 | 13 | 15 | 15 | 13 | 13 | 15 | 15 | 13 | 13 | 15 | 15 | 13 | 13 | 15 |15 | | + | |
- | ^ 14 | 14 | 15 | 14 | 15 | 14 | 15 | 14 | 15 | 14 | 15 | 14 | 15 | 14 | 15 | 14 |15 | | + | |
- | ^ 15 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 15 |15 | | + | |
- | + | ||
- | ^ Номер\\ цвета\\ изображения ^ Цвет экрана (наличие параметра AND) ^^^^^^^^^^^^^^^^ | + | |
- | ^:::^ 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 ^ 8 ^ 9 ^ 10 ^ 11 ^ 12 ^ 13 ^ 14 ^ 15 ^ | + | |
- | ^ 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | + | |
- | ^ 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | | + | |
- | ^ 2 | 0 | 0 | 2 | 2 | 0 | 0 | 2 | 2 | 0 | 0 | 2 | 2 | 0 | 0 | 2 | 2 | | + | |
- | ^ 3 | 0 | 1 | 2 | 3 | 0 | 1 | 2 | 3 | 0 | 1 | 2 | 3 | 0 | 1 | 2 | 3 | | + | |
- | ^ 4 | 0 | 0 | 0 | 0 | 4 | 4 | 4 | 4 | 0 | 0 | 0 | 0 | 4 | 4 | 4 | 4 | | + | |
- | ^ 5 | 0 | 1 | 0 | 1 | 4 | 5 | 4 | 5 | 0 | 1 | 0 | 1 | 4 | 5 | 4 | 5 | | + | |
- | ^ 6 | 0 | 0 | 2 | 2 | 4 | 4 | 6 | 6 | 0 | 0 | 2 | 2 | 4 | 4 | 6 | 6 | | + | |
- | ^ 7 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | + | |
- | ^ 8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | | + | |
- | ^ 9 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 8 | 9 | 8 | 9 | 8 | 9 | 8 | 9 | | + | |
- | ^ 10 | 0 | 0 | 2 | 2 | 0 | 0 | 2 | 2 | 8 | 8 | 10 | 10 | 8 | 8 | 10 | 10 | | + | |
- | ^ 11 | 0 | 1 | 2 | 3 | 0 | 1 | 2 | 3 | 8 | 9 | 10 | 11 | 8 | 9 | 10 | 11 | | + | |
- | ^ 12 | 0 | 0 | 0 | 0 | 4 | 4 | 4 | 4 | 8 | 8 | 8 | 8 | 12 | 12 | 12 | 12 | | + | |
- | ^ 13 | 0 | 1 | 0 | 1 | 4 | 5 | 4 | 5 | 8 | 9 | 8 | 9 | 12 | 13 | 12 | 13 | | + | |
- | ^ 14 | 0 | 0 | 2 | 2 | 4 | 4 | 6 | 6 | 8 | 8 | 10 | 10 | 12 | 12 | 14 | 14 | | + | |
- | ^ 15 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | | + | |
- | + | ||
- | ^ Номер\\ цвета\\ изображения ^ Цвет экрана (наличие параметра PRESET) ^^^^^^^^^^^^^^^^ | + | |
- | ^:::^ 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 ^ 8 ^ 9 ^ 10 ^ 11 ^ 12 ^ 13 ^ 14 ^ 15 ^ | + | |
- | ^ Номер цвета\\ экрана | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | | + | |
- | + | ||
- | При выполнении оператора ''COPY'' с параметром ''PSET'' каждая точка копируемого прямоугольника окрашивается в тот цвет, который она имела до копирования, а при выполнении оператора ''COPY'' с параметром ''PRESET'' каждая точка копируемого прямоугольника окрашивается в "противоположный" цвет. | + | |
- | + | ||
- | __//Примеры//__: | + | |
- | * <WRAP> {{anchor:e0510-01}} 6) | + | |
- | \\ {{.examples:0510-06.bas|}} \\ [[+tab|wmsxbpge>0510-06.bas]] <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR15,3:SCREEN5 | + | |
- | 20 OPEN"GRP:"AS#1:SET PAGE 0,0 | + | |
- | 30 LINE (100,0)-(130,30),7,BF | + | |
- | 40 LINE (100,40)-(130,70),6,BF | + | |
- | 50 IF INKEY$="" THEN 50 | + | |
- | 60 SETPAGE 0,1:CLS:SETPAGE 1,1 | + | |
- | 70 COPY (0,0)-(255,100),0 TO (100,0),1,PSET | + | |
- | 80 PSET(205,10),1:?#1,POINT(210,5) | + | |
- | 90 PSET(205,50),1:?#1,POINT(210,45) | + | |
- | 100 GOTO 100 | + | |
- | </code> | + | |
- | При нажатии на любую клавишу Вы получите изображение другой экранной страницы. | + | |
- | </WRAP> | + | |
- | * <WRAP> {{anchor:e0510-07}} 7) | + | |
- | \\ {{.examples:0510-07.bas|}} \\ [[+tab|wmsxbpge>0510-07.bas]] <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 5:SET PAGE 0,0 | + | |
- | 30 FOR K=0 TO 50:CIRCLE(127,106),K,K/4:NEXT | + | |
- | 40 COPY(77,56)-(177,156),0 TO (10,10),1,PRESET:L$=INPUT$(1) | + | |
- | 50 SET PAGE 1,1:L$=INPUT$(1) | + | |
- | 60 SET PAGE 0,0:L$=INPUT$(1) | + | |
- | 70 GOTO 50 | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | * <WRAP> {{anchor:e0510-08}} 8) Испытайте логические операции ''PRESET'', ''AND'', ''OR'', ''XOR'', изменяя последний параметр в строке 70. | + | |
- | \\ {{.examples:0510-08.bas|}} \\ [[+tab|wmsxbpge>0510-08.bas]] <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 15,3,4:SCREEN 5:OPEN"GRP:"AS#1:SET PAGE 0,0 | + | |
- | 30 LINE(100,0)-(130,30),0,BF:LINE(100,40)-(130,70),2,BF | + | |
- | 50 IF INKEY$="" THEN 50 | + | |
- | 60 SET PAGE 0,1:CLS:SET PAGE 1,1 | + | |
- | 70 COPY (0,0)-(255,100),0 TO (100,0),1,TPSET 'Подставьте TAND! | + | |
- | 80 PSET(205,10),1:PRINT#1,POINT(210,5) | + | |
- | 90 PSET(205,50),1:PRINT#1,POINT(210,45) | + | |
- | 100 A$=INPUT$(1) | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | * <WRAP> {{anchor:e0510-09}} 9) | + | |
- | \\ {{.examples:0510-09.bas|}} \\ [[+tab|wmsxbpge>0510-09.bas]] <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 5 OPEN"grp:"AS#1 | + | |
- | 10 COLOR 15,4,15 ' Начальная установка | + | |
- | 20 SCREEN 5 ' экрана | + | |
- | 30 LINE(40,60)-(80,110),3,BF ' Рисуем прямоугольник | + | |
- | 40 COPY (40,60)-(80,110) TO (100,60),,TAND ' Копия прямоугольника | + | |
- | 50 Y=POINT (110,70) ' Цвет точки из копии | + | |
- | 60 I$=INPUT$(1) ' | + | |
- | 70 PRESET(90,120):PRINT #1,"Цвет копии равен ";Y 'Вывод цвета копии | + | |
- | 80 I$=INPUT$(1) | + | |
- | </code> | + | |
- | С помощью оператора ''COPY'', изменяя координаты (X3,Y3), можно перемещать изображение в любое место экрана. Это позволяет имитировать на экране дисплея движение объектов. | + | |
- | + | ||
- | Для имитации движения необходимо выполнить следующие действия: | + | |
- | - поместить изображение объекта на экран с помощью оператора ''COPY''; | + | |
- | - вывести изображение объекта в новом месте. | + | |
- | Если эти действия повторять, то будет создаваться иллюзия движения;чем быстрее осуществляется смена изображений и чем меньше расстояние между двумя "кадрами", тем эта иллюзия полнее. Если осуществлять смену кадров с достаточно высокой скоростью, то можно добиться исчезновения эффекта мигания изображения. Однако, учтите, что скорость смены кадров ограничена производительностью компьютера. | + | |
- | + | ||
- | {{anchor:e0510-10}} __//Пример 10//__. | + | |
- | \\ {{.examples:0510-10.bas|}} \\ [[+tab|wmsxbpge>0510-10.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 COLOR 15,0,0 | + | |
- | 20 SCREEN 5:DIM A(1000):VDP(1)=VDP(1)XOR64 'Отключение экрана | + | |
- | 30 CIRCLE (80,80),3,13:PAINT (80,80),13 | + | |
- | 40 COPY (74,74)-(86,86) TO A:CLS:VDP(1)=VDP(1)XOR64'Включение экрана | + | |
- | 50 FOR I=0 TO 256 ' Попробуйте оператор FOR I=0 TO 256 STEP 4 | + | |
- | 60 COPY A TO (I,80) | + | |
- | 70 NEXT:GOTO 50 | + | |
- | </code> | + | |
- | + | ||
- | __//Замечание//__. Эти же параметры (XOR, OR, AND, PSET, PRESET) могут использоваться в операторах ''PSET'', ''PRESET'' и ''LINE'' в режимах ''SCREEN 5'', ''SCREEN 6'', ''SCREEN 7'' и ''SCREEN 8''. Они имеют тот же смысл, что и в операторе ''COPY''. | + | |
- | + | ||
- | {{anchor:e0510-11}} __//Пример 11//__. | + | |
- | \\ {{.examples:0510-11.bas|}} \\ [[+tab|wmsxbpge>0510-11.bas]] <code> | + | |
- | 10 OPEN "GRP:"AS#1:COLOR 1,3,4:SCREEN 7:PSET (73,63),13,XOR | + | |
- | 20 PRINT #1,POINT(73,63) ─▲─ | + | |
- | 30 GOTO 30 │ | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e0510-12}} __//Пример 12//__. | + | |
- | \\ {{.examples:0510-12.bas|}} \\ [[+tab|wmsxbpge>0510-12.bas]] <code> | + | |
- | 10 OPEN "GRP:"AS#1:COLOR 1,3,4:SCREEN 7 | + | |
- | 20 LINE (73,63)-(100,100),13,,XOR | + | |
- | 30 PRINT #1,POINT(73,63) | + | |
- | 40 GOTO 40 | + | |
- | </code> | + | |
- | + | ||
- | Отметим, что наличие префикса ''T'' перед параметрами ''XOR'', ''OR'', ''AND'', ''PSET'', ''PRESET'' никак не влияет на выполнение логических операций над кодом цвета! | + | |
- | + | ||
- | {{anchor:e0510-13}} __//Пример 13//__. | + | |
- | \\ {{.examples:0510-13.bas|}} \\ [[+tab|wmsxbpge>0510-13.bas]] <code> | + | |
- | 5 OPEN"grp:"AS#1 | + | |
- | 10 COLOR 15,4,15 ' Начальная установка | + | |
- | 20 SCREEN 5 ' экрана | + | |
- | 30 LINE(40,60)-(80,110),3,BF,TAND ' Рисуем прямоугольник | + | |
- | 50 Y=POINT (50,70) ' Цвет точки | + | |
- | 60 I$=INPUT$(1) ' | + | |
- | 70 PRESET(90,120):PRINT #1,"Цвет прямоуг. :";Y ' Вывод цвета | + | |
- | 80 I$=INPUT$(1) | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | * <WRAP> //Вариант 2// | + | |
- | + | ||
- | Этот оператор позволяет запоминать цвета всех точек заданной прямоугольной области экрана дисплея и хранить их номера в виде числового массива (или в файле данных); далее этот оператор по Вашему желанию может | + | |
- | повторно воспроизвести эти цвета на экране. Причём с помощью оператора ''COPY'' изображение воспроизводится достаточно быстро для того, чтобы можно было синтезировать движение объектов на экране. | + | |
- | + | ||
- | Формат оператора: | + | |
- | <code> | + | |
- | ⎧ Имя массива | + | |
- | COPY (X1,Y1)-(X2,Y2), stri ТО ⎨ , | + | |
- | ⎩ Имя файла | + | |
- | </code> | + | |
- | где: | + | |
- | * (X1,Y1)-(X2,Y2) — параметры, указывающие позицию копируемого блока и "работающие" точно так же, как в операторе ''LINE (X1,Y1)-(X2,Y2),C,BF'' (наличие этих параметров обязательно); | + | |
- | * stri — арифметическое выражение,указывающее на номер копируемой страницы; значение stri должно принадлежать [0,3]. По умолчанию используется активная страница; | + | |
- | //Имя// массива (//Имя// файла) — который позволяет Вам копировать блок изображения в цифровой форме в массив заданного размера или в указанный файл на дискете. | + | |
- | + | ||
- | Для выполнения оператора ''COPY'' необходимо задать достаточно большой одномерный числовой массив для того, чтобы вместить данные о расцветке всех точек рассматриваемой области экрана. | + | |
- | + | ||
- | Количество элементов массива в режиме ''SCREEN 5'' определяется формулой: | + | |
- | + | ||
- | <m>delim{[}{ ((4*delim{|}{X1-X2}{|}+1)*(delim{|}{Y1-Y2}{|}+1)+7)/8 }{]}+4</m>, где <m>delim{[}{ }{]}</m> — символ операции выделения целой части. | + | |
- | + | ||
- | На языке [[msx:basic:]] это "звучит" как | + | |
- | INT( (4* (ABS(X1-X2)+1) * (ABS(Y1-Y2)+1) +7)/8 )+4 | + | |
- | Используя операторы ''COPY'' и ''DATA'', можно воспроизводить изображения, которые закодированы в форме последовательности чисел. Значение числового массива, хранящего изображение, может быть выведено на экран или память, а затем вставлено в //другую// программу при помощи операторов ''DATA''. | + | |
- | + | ||
- | {{anchor:e0510-14}} __//Пример 14//__. | + | |
- | \\ {{.examples:0510-14.bas|}} \\ [[+tab|wmsxbpge>0510-14.bas]] <code> | + | |
- | Ok | + | |
- | 10 SCREEN 5 | + | |
- | 20 FOR I=1 TO 10:CIRCLE (125,95),10+I,I:NEXT | + | |
- | 30 COPY (40,40)-(180,180),0 TO "OKR" 'Изображение записывается | + | |
- | 40 GOTO 40 'на дискету под именем "ОКR". | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | * <WRAP> //Вариант 3// | + | |
- | <code> | + | |
- | ⎧ [T]XOR | + | |
- | ⎧ Имя массива ⎪ [T]OR | + | |
- | COPY ⎨ [,napr] ТО (X3,Y3), strp, ⎨ [T]AND , | + | |
- | ⎩ Имя файла ⎪ [T]PSET | + | |
- | ⎩ [T]PRESET | + | |
- | </code> | + | |
- | где: | + | |
- | * napr — необязательный параметр, дающий возможность "поворачивать" блок изображения. Он может принимать следующие значения: | + | |
- | * 0 — преобразование симметрии отсутствует (по умолчанию); | + | |
- | * 1 — преобразование симметрии относительно прямой, проходящей через точку (X3,Y3) и параллельной оси Oy; | + | |
- | * 2 — преобразование симметрии относительно прямой, проходящей через точку (X3,Y3) и параллельной оси Ox; | + | |
- | * 3 — //центральная// симметрия относительно точки (X3,Y3). | + | |
- | * strp — арифметическое выражение, указывающее на номер копируемой страницы; значение strp должно принадлежать [0,3]. По умолчанию используется страница–источник; | + | |
- | + | ||
- | //Имя// массива (//Имя// файла) — даёт возможность копировать блок изображения в цифровой форме в массив заданного размера или в указанный файл на дискете; | + | |
- | * (X3,Y3) — координаты верхнего левого угла места, в которое будет скопирован блок (наличие этого параметра обязательно!); | + | |
- | + | ||
- | Размер массива в режиме ''SCREEN 5'' определяется следующей формулой: | + | |
- | + | ||
- | <m>delim{[}{ ((4*delim{|}{X1-X2}{|}+1)*(delim{|}{Y1-Y2}{|}+1)+7)/8 }{]}+4</m>, где <m>delim{[}{ }{]}</m> — символ операции выделения целой части. | + | |
- | + | ||
- | На языке [[msx:basic:]] это "звучит" как | + | |
- | <code> | + | |
- | INT( (4* (ABS(X1-X2)+1) * (ABS(Y1-Y2)+1) +7)/8 )+4 | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e0510-15}} __//Пример 15//__. | + | |
- | \\ {{.examples:0510-15.bas|}} \\ [[+tab|wmsxbpge>0510-15.bas]] <code> | + | |
- | Ok | + | |
- | 10 SCREEN 5:DIM A%(2900) | + | |
- | 20 FOR K=0 TO 50:CIRCLE(127,106),K,15:NEXT K | + | |
- | 30 COPY (77,56)-(177,156),0 TO A% | + | |
- | 35 SCREEN 0:FOR I=1 TO 150:PRINT A%(I);:NEXT | + | |
- | 40 PRINT"Изображение записано":L$=INPUT$(1) | + | |
- | 50 SCREEN 5:COPY A% TO (77,56),0:L$=INPUT$(1) | + | |
- | </code> | + | |
- | После выполнения программы наберите команду ''goto 50'' и нажмите клавишу <key>'Ввод '⏎</key>… Пожалуйста, проанализируйте полученный результат! | + | |
- | + | ||
- | {{anchor:e0510-16}} __//Пример 16//__. | + | |
- | \\ {{.examples:0510-16.bas|}} \\ [[+tab|wmsxbpge>0510-16.bas]] <code> | + | |
- | Ok | + | |
- | 10 SCREEN 5 | + | |
- | 20 COPY "okr" TO (25,30),0 'Вывод информации с диска на экран | + | |
- | 30 GOTO 30 | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e0510-17}} __//Пример 17//__. Пример копирования изображения на экране дисплея в массив, а из массива — в новое место экрана. | + | |
- | \\ {{.examples:0510-17.bas|}} \\ [[+tab|wmsxbpge>0510-17.bas]] <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 DIM AK(INT((4*(ABS(41-71)+1)*(ABS(41-71)+1)+7)/8)+4) | + | |
- | 20 SCREEN 5:SET PAGE 0,0 | + | |
- | 30 LINE(40,40)-(70,70),15,BF | + | |
- | 35 COPY(41,41)-(71,71),0 TO AK 'Скопировали изображение в массив AK | + | |
- | 40 A$=INKEY$:IF A$="" THEN 40 | + | |
- | 50 COPY AK,0 TO (150,150),0 | + | |
- | 70 A$=INKEY$:IF A$="" THEN 70 | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e0510-18}} __//Пример 18//__. Иллюстрация действия параметра PRESET | + | |
- | \\ {{.examples:0510-18.bas|}} \\ [[+tab|wmsxbpge>0510-18.bas]] <code> | + | |
- | Ok | + | |
- | 10 SCREEN 5 | + | |
- | 20 LINE(100,100)-(110,110),8,BF | + | |
- | 30 LINE(120,120)-(190,130),3,BF │ | + | |
- | 35 A$=INPUT$(1) ▼ | + | |
- | 40 COPY(100,100)-(190,130) TO (100,0),,PRESET | + | |
- | 50 GOTO 50 | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e0510-19}} __//Пример 19//__. | + | |
- | \\ {{.examples:0510-19.bas|}} \\ [[+tab|wmsxbpge>0510-19.bas]] <code> | + | |
- | Ok | + | |
- | 10 SCREEN 5:DIM A(INT((4*(ABS(100-190)+1)*(ABS(100-130)+1)+7)/8)+4) | + | |
- | 20 LINE(100,100)-(110,110),8,BF | + | |
- | 30 LINE(120,120)-(190,130),3,BF !!! | + | |
- | 40 COPY(100,100)-(190,130) TO A │ | + | |
- | 50 A$=INPUT$(1):CLS ▼ | + | |
- | 60 COPY A,3 TO (100,100) | + | |
- | 65 A$=INPUT$(1):CLS | + | |
- | 70 COPY A TO (100,100) | + | |
- | 80 GOTO 50 | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | * <WRAP> //Вариант 4// | + | |
- | <code> | + | |
- | COPY имя массива ТО имя файла | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | * <WRAP> //Вариант 5// | + | |
- | <code> | + | |
- | COPY имя файла ТО имя массива | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e0510-20}} __//Пример 20//__. | + | |
- | \\ {{.examples:0510-20.bas|}} \\ [[+tab|wmsxbpge>0510-20.bas]] <code> | + | |
- | Ok | + | |
- | 10 DIM AK(INT((4*(ABS(41-71)+1)*(ABS(41-71)+1)+7)/8)+4) | + | |
- | 20 SCREEN 5:SET PAGE 0,0 | + | |
- | 30 LINE(40,40)-(70,70),15,BF | + | |
- | 35 COPY(41,41)-(71,71),0 TO AK | + | |
- | 40 COPY AK TO "Dima" | + | |
- | 50 CLS:DIM AB(485) | + | |
- | 60 COPY "Dima" TO AB:COPY AB TO (40,40) | + | |
- | 70 GOTO 70 | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | * <WRAP> //Вариант 6// | + | |
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | Давайте все–таки обсуждать вкус ананаса с теми, кто его не ел! | + | |
- | <WRAP rightalign> | + | |
- | —//Почти по М.Жванецкому// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | Этот оператор применяется на компьютерах [[msx:msx_2]], оснащённых видеоинтерфейсом: | + | |
- | COPY SCREEN [ режим 1] [, режим 2] | + | |
- | Это позволяет преобразовать изображение, полученное с внешнего источника видеосигнала, в цифровые данные, записанные на экранной странице. | + | |
- | + | ||
- | Параметры //режим 1//, //режим 2// могут принимать два значения: | + | |
- | * 0: (по умолчанию) кадр записывается на отображённой экранной странице; | + | |
- | * 1: кадр записывается на странице, номер которой равен номеру отображённой минус 1. В этом случае номер отображённой страницы должен быть нечётным. | + | |
- | Предполагается, что экран подготовлен к работе с изображением, приходящим от внешнего источника видеосигнала. | + | |
- | + | ||
- | Для этой цели имеется оператор | + | |
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code> | + | |
- | SET VIDEO R,Y,C,S,A,V,R | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | <WRAP half column> | + | |
- | , | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | где: | + | |
- | * ''SET'', ''VIDEO'' — служебные слова; | + | |
- | * R — числовой параметр, значение которого определяет источник видео сигнала: | + | |
- | * 0 — (по умолчанию) изображение от компьютера; | + | |
- | * 1 — изображение от компьютера; | + | |
- | * 2 — смешивание изображения от компьютера и ТВ–сигнала; | + | |
- | * 3 — на дисплей поступает ТВ–сигнал; | + | |
- | * Y — числовой параметр, который управляет интенсивностью изображения от источника видеосигнала: | + | |
- | * 0 — (по умолчанию) нормальная интенсивность; | + | |
- | * 1 — интенсивность ТВ–сигнала уменьшена наполовину; | + | |
- | * C — числовой параметр, который определяет направление передачи данных о цветности: | + | |
- | * 0 — (по умолчанию) вывод цветных данных на видеомагнитофон; | + | |
- | * 1 — ввод цветных данных от внешнего источника; | + | |
- | * S — числовой параметр, который определяет происхождение сигнала синхронизации: | + | |
- | * 0 — (по умолчанию) внутренняя синхронизация; | + | |
- | * 1 — внешняя синхронизация (невозможна, когда R=0); | + | |
- | * A — числовой параметр, который позволяет смешивать AUDIO–сигнал компьютера и сигнал от внешнего источника видеосигнала: | + | |
- | * 0 — (0 по умолчанию) звук только от компьютера; | + | |
- | * 1 — смешивание с внешним сигналом (правый канал); | + | |
- | * 2 — смешивание с внешним сигналом (левый канал); | + | |
- | * 3 — смешивание по обоим каналам; | + | |
- | * V — числовой параметр, указывающий тип разъёма для ввода внешнего видеосигнала: | + | |
- | * 0 — (по умолчанию) разъём RGB; | + | |
- | * 1 — разъём RCA; | + | |
- | * R — числовой параметр, описывающий состояние сигнала управления AV на разъёме RGB: | + | |
- | * 0 — выхода через разъём RGB нет; | + | |
- | * 1 — выход через разъём RGB разрешён. | + | |
- | + | ||
- | <WRAP centeralign>Отметим, что оператор ''COPY'' можно использовать в режимах ''SCREEN 5'', ''SCREEN 6'', ''SCREEN 7'', ''SCREEN 8''.</WRAP> | + | |
- | + | ||
- | {{anchor:e0510-21}} __//Пример 21//__. | + | |
- | \\ {{.examples:0510-21.bas|}} \\ [[+tab|wmsxbpge>0510-21.bas]] <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 6 | + | |
- | 20 LINE(20,70)-(30,80),15,BF:LINE(40,20)-(100,90),3,BF | + | |
- | 30 FOR I=1 TO 1000:NEXT:COPY(20,70)-(110,90) TO (130,70) | + | |
- | 40 GOTO 40 | + | |
- | </code> | + | |
- | Меняя в 10–й строке номера экранов, Вы можете в этом убедиться! | + | |
- | </WRAP> | + | |
- | + | ||
- | Отметим, что в версии BASIC, называемой Advanced BASIC, для профессиональных компьютеров IBM PC/XT (XT — от "eXTended" — "развитый, расширенный") и IBM PC/AT (AT — от "Advanced Technology" — "передовая техника и технология"), используются два оператора, действия которых аналогичны действию оператора ''COPY'' версии [[msx:basic:]]: | + | |
- | <code> | + | |
- | GET(X1,Y1)-(X2,Y2),A | + | |
- | </code> | + | |
- | Данный оператор "считывает" в массив A характеристики точек экрана, расположенных в заданной прямоугольной области; | + | |
- | <code> | + | |
- | PUT(X,Y),A, способ | + | |
- | </code> | + | |
- | Оператор "накладывает" массив точек на прямоугольную область экрана с управляемым способом формирования цветности (задаваемым параметром //способ//). | + | |
- | + | ||
- | {{anchor:screen6}} | + | |
- | ===== V.11. Режим SCREEN 6 (только для компьютера MSX 2) ===== | + | |
- | FIXME | + | |
- | + | ||
- | Экран в режиме ''SCREEN 6'' такой же, как и в режиме ''SCREEN 5'' (см.[[#pict_05_07|рис.7]]), но могут использоваться только 4 цвета. | + | |
- | {{anchor:pict_05_08}} | + | |
- | <code> | + | |
- | 0 511 | + | |
- | 0┌───────────────────┐──▶X | + | |
- | │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ | + | |
- | │▨▨▨▨▨ SCREEN6 ▨▨▨▨▨│ | + | |
- | │▨▨▨ 512×212 точек▨▨│ | + | |
- | │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ | + | |
- | 211│─ ─ ─ ─ ─ ─ ─ ─ ─ ─┘ | + | |
- | ▼ | + | |
- | Y | + | |
- | </code> | + | |
- | __//Рис. 8//__ | + | |
- | + | ||
- | ''CLS'' устанавливает цвет //фона//, имеющий номер 0 (прозрачный). | + | |
- | + | ||
- | Для установления цветов можно выбирать номер, лежащий в пределах от 0 до 31 (хотя используется только 4 палитры). Именно поэтому оператор ''COLOR'' должен быть выполнен после оператора ''SCREEN 6'' ! | + | |
- | + | ||
- | Цвет задаётся значением двух младших битов номера палитры, введённого оператором ''COLOR''. (Например, число 23=&b00010111 подразумевает использование цвета 3=&b11). Если номер палитры принадлежит [16,31], то для бордюра | + | |
- | принимаются в расчёт уже четыре младших бита. (Первые два определяют цвет точек с чётными координатами, а два последних — точек с нечётными координатами. В итоге бордюр будет покрыт мелкой сеткой из точек двух цветов.) | + | |
- | + | ||
- | Все графические операторы работают так же, как и в режиме ''SCREEN 3''. | + | |
- | + | ||
- | {{anchor:e0511-01}} __//Пример//__. | + | |
- | \\ {{.examples:0511-01.bas|}} \\ [[+tab|wmsxbpge>0511-01.bas]] | + | |
- | <code> | + | |
- | Ok | + | |
- | 10 SCREEN 6:COLOR 15,17,1:CIRCLE(255,106),100,3:PAINT STEP(0,0),2,3 | + | |
- | 20 GOTO 20 | + | |
- | </code> | + | |
- | Получается окружность! Радиус по вертикали (автоматически) сжимается для соответствия разнице масштаба между абсциссой и ординатой. | + | |
- | + | ||
- | Работа с экранными страницами и внешним видеосигналом такая же, как в ''SCREEN 5''. | + | |
- | + | ||
- | Учтите лишь следующий момент: формула, дающая размер массива переменных, копирующего блок экрана, теперь выглядит так: | + | |
- | <m> | + | |
- | delim{[}{ ((2*delim{|}{X1-X2}{|}+1)*(delim{|}{Y1-Y2}{|}+1)+7)/2 }{]}+4 | + | |
- | </m>, где <m>delim{[}{ }{]}</m> — символ операции выделения целой части. | + | |
- | + | ||
- | {{anchor:screen7}} | + | |
- | ===== V.12. Режим SCREEN 7 (только для компьютера MSX 2 с видеопамятью 128 Кбайт) ===== | + | |
- | + | ||
- | <WRAP centeralign>Этот режим максимально удобен для многоцветных рисунков!</WRAP> | + | |
- | + | ||
- | {{anchor:pict_05_09}} | + | |
- | <code> | + | |
- | 0 511 | + | |
- | 0┌───────────────────┐──▶X | + | |
- | │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ | + | |
- | │▨▨▨▨▨ SCREEN7 ▨▨▨▨▨│ | + | |
- | │▨▨▨ 512×212 точек▨▨│ | + | |
- | │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ | + | |
- | 211│─ ─ ─ ─ ─ ─ ─ ─ ─ ─┘ | + | |
- | ▼ | + | |
- | Y | + | |
- | </code> | + | |
- | __//Рис. 9//__ | + | |
- | + | ||
- | Этот режим похож на режим ''SCREEN 6'', но: | + | |
- | - экранные страницы нумеруются от 0 до 1; | + | |
- | - допускается одновременное использование 16 цветов. | + | |
- | Формула, необходимая для вычисления размера массива, принимающего данные блока экрана, та же, что и в ''SCREEN 5'': | + | |
- | + | ||
- | <m>delim{[}{ ((4*delim{|}{X1-X2}{|}+1)*(delim{|}{Y1-Y2}{|}+1)+7)/8 }{]}+4</m>, где <m>delim{[}{ }{]}</m> — символ операции выделения целой части. | + | |
- | + | ||
- | {{anchor:screen8}} | + | |
- | ===== V.13. Режим SCREEN 8 (только для компьютера MSX 2 с видеопамятью 128 Кбайт) ===== | + | |
- | + | ||
- | Экран содержит 212 строк по 256 точек, как в ''SCREEN 5''. | + | |
- | + | ||
- | {{anchor:pict_05_10}} | + | |
- | <code> | + | |
- | 0 255 | + | |
- | 0┌───────────────────┐──▶X | + | |
- | │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ | + | |
- | │▨▨▨▨▨ SCREEN8 ▨▨▨▨▨│ | + | |
- | │▨▨▨ 256×212 точек▨▨│ | + | |
- | │▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨▨│ | + | |
- | 211│─ ─ ─ ─ ─ ─ ─ ─ ─ ─┘ | + | |
- | ▼ | + | |
- | Y | + | |
- | </code> | + | |
- | __//Рис. 10//__ | + | |
- | + | ||
- | Этот режим характеризуется количеством цветов, которые могут выводиться одновременно. Цвет каждой точки кодируется в одном байте, и следовательно, имеет значения, лежащие в пределах от 0 до 255. Они кодируются | + | |
- | следующим образом: | + | |
- | Байт цвета = GGGRRRBB | + | |
- | Первые три бита (G) представляют значения от 0 до 7 и определяют интенсивность //зелёного// цвета ("Green" — "зелёный"). | + | |
- | + | ||
- | Следующие три бита (R) устанавливают интенсивность //красного// ("Red" — "красный"), и последние два (B) — интенсивность //синего// ("Blue" — "синий") цвета. | + | |
- | + | ||
- | {{anchor:e0513-01}} Например, | + | |
- | \\ {{.examples:0513-01.bas|}} \\ [[+tab|wmsxbpge>0513-01.bas]] | + | |
- | <code> | + | |
- | 10 SCREEN 8 | + | |
- | 20 PSET(3,0),&B11100000:PSET(5,10),&B00000011 | + | |
- | 30 GOTO 30 | + | |
- | </code> | + | |
- | Цвета изображения, фона и бордюра определяются как в режиме ''SCREEN 2'' посредством оператора ''COLOR'' (или графических операторов для цвета текста), но значения лежат в пределах от 0 до 255. | + | |
- | + | ||
- | Введённое значение и пропорции цвета соотносятся следующим образом: | + | |
- | цвет = 32*G+4*R+B | + | |
- | + | ||
- | В ''SCREEN 8'' палитры не используются: желаемые оттенки задаются непосредственно. | + | |
- | + | ||
- | {{anchor:e0513-02}} __//Пример//__. | + | |
- | \\ {{.examples:0513-02.bas|}} \\ [[+tab|wmsxbpge>0513-02.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 SCREEN 8:FOR I=0 TO 255:COLOR,I:CLS | + | |
- | 40 FOR J=0 TO 300:NEXT J,I | + | |
- | </code> | + | |
- | + | ||
- | Имеются только //две// экранные страницы, как и в режиме ''SCREEN 7''. | + | |
- | + | ||
- | Формула, необходимая для вычисления размера массива, принимающего копию блока экрана, имеет следующий вид: | + | |
- | + | ||
- | <m>delim{[}{ ((8*delim{|}{X1-X2}{|}+1)*(delim{|}{Y1-Y2}{|}+1)+7)/8 }{]}</m>, где <m>delim{[}{ }{]}</m> — символ операции выделения целой части. | + | |
- | + | ||
- | Разумеется, запись этого выражения на языке [[msx:basic:]] очевидна: | + | |
- | INT( (8* (ABS(X1-X2)+1) * (ABS(Y1-Y2)+1) +7)/8 ) | + | |
- | + | ||
- | Вспомним, что для выполнения оператора ''COPY'' необходимо задать числовой массив достаточно большой для того, чтобы вместить данные о расцветке всех точек рассматриваемой области экрана. | + | |
- | + | ||
- | Приведём простую программу, подсчитывающую минимальное количество элементов для такого массива числовых значений. В начале работы программа выдаёт запрос на ввод координат, которые будут задаваться в операторе ''COPY'', | + | |
- | а также просит указать, какой режим графического вывода будет использоваться. | + | |
- | + | ||
- | {{anchor:e0513-03}} __//Пример//__. | + | |
- | \\ {{.examples:0513-03.bas|}} \\ [[+tab|wmsxbpge>0513-03.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 INPUT"Введите номер режима экрана (5,6,7 или 8)";I | + | |
- | 20 INPUT"Введите координаты первой точки (X1,Y1)";X1,Y1 | + | |
- | 30 INPUT"Введите координаты второй точки (X2,Y2)";X2,Y2 | + | |
- | 40 S=4:C=8:IF I=6 THEN S=2:C=2 ELSE IF I=8 THEN 60 | + | |
- | 50 M=INT((S*(ABS(X1-X2)+1)*(ABS(Y1-Y2)+1)+7)/C)+4:GOTO 70 | + | |
- | 60 M=INT((8*ABS(X1-X2)+1)*(ABS(Y1-Y2)+1)+7/8) | + | |
- | 70 PRINT "SCREEN"I:PRINT "X1-"X1,"Y1-"Y1:PRINT "X2-"X2,"Y2-"Y2 | + | |
- | 80 PRINT "Размерность массива- "M:END | + | |
- | run | + | |
- | Введите номер режима экрана (5,6,7 или 8) ? 5 | + | |
- | Введите координаты первой точки (X1,Y1) ? 50,50 | + | |
- | Введите координаты второй точки (Х2,Y2) ? 71,85 | + | |
- | SCREEN 5 | + | |
- | X1- 50 Y1- 50 | + | |
- | X2- 71 Y2- 85 | + | |
- | Размерность массива- 400 | + | |
- | Ok | + | |
- | </code> | + | |
- | + | ||
- | ===== V.14. Дополнение ===== | + | |
- | + | ||
- | {{anchor:e0514-01}} 1. __//Пример//__ простейшего //графического// редактора [[bibliography#b22|[22]]]. | + | |
- | Редактор позволяет не только рисовать стрелками, но и включать–отключать цвет пера нажатием на пробел. Вокруг точки, в которой в данный момент находится перо, можно построить окружность или звезду. Для построения окружности нужно нажать на клавишу <key>О</key>, после чего ввести значение радиуса (окончание ввода — нажатие на клавишу <key>'Ввод '⏎</key>). Нажатие на <key>Z</key> и ввод величин R (радиус окружности, проходящей через вершины звезды), N (количество вершин) и M=2 позволяет построить звезду. Для ввода чисел используется подпрограмма "ВВОД". | + | |
- | \\ {{.examples:0514-01.bas|}} \\ [[+tab|wmsxbpge>0514-01.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 DIM PR(2),PD$(2) | + | |
- | 20 PD$(0)="R=":PD$(1)="N=":PD$(2)="M=":PI=4*ATN(1) | + | |
- | 30 SCREEN 2:OPEN"GRP:"AS#1 | + | |
- | 40 X=128:Y=96:C=4 | + | |
- | 50 PSET(X,Y),C | + | |
- | 60 S=STICK(0) | + | |
- | 70 P$=INKEY$ | + | |
- | 80 IF S=1 OR S=2 OR S=8 THEN Y=Y-1 | + | |
- | 90 IF S=2 OR S=3 OR S=4 THEN X=X+1 | + | |
- | 100 IF S=4 OR S=5 OR S=6 THEN Y=Y+1 | + | |
- | 110 IF S=6 OR S=7 OR S=8 THEN X=X-1 | + | |
- | 120 IF P$=" " AND C=15 THEN C=4:GOTO 160 '──▶ | + | |
- | 130 IF P$=" " AND C=4 THEN C=15 | + | |
- | 140 IF P$="O" OR P$="o" THEN GOSUB 500 '──▶ | + | |
- | 150 IF P$="Z" OR P$="z" THEN GOSUB 1000 '──▶ | + | |
- | 160 PSET(X,Y) | + | |
- | 170 GOTO 50 '──▶ | + | |
- | 500 'О к р у ж н о с т ь | + | |
- | 510 K=0:GOSUB 1500 | + | |
- | 520 CIRCLE(X,Y),PR(0) | + | |
- | 530 RETURN | + | |
- | 1000 ' З в е з д а | + | |
- | 1010 K=2:GOSUB 1500 | + | |
- | 1020 R=PR(0):N=PR(1):M=PR(2) | + | |
- | 1030 PSET(X,Y-R) | + | |
- | 1040 FOR I=1 TO N | + | |
- | 1050 U=I*2*PI*M/N+PI/2 | + | |
- | 1060 X1=X+R*COS(U):Y1=Y-R*SIN(U) | + | |
- | 1070 LINE-(X1,Y1) | + | |
- | 1080 NEXTI | + | |
- | 1090 RETURN | + | |
- | 1500 ' В в о д | + | |
- | 1510 FOR J=0 TO K | + | |
- | 1520 F$="" | + | |
- | 1530 LINE(0,0)-(255,10),4,BF | + | |
- | 1540 PSET(0,0),4:PRINT #1,PD$(J); | + | |
- | 1550 C$=INPUT$(1):PRINT #1,C$; | + | |
- | 1560 IF ASC(C$)=13 THEN 1580 | + | |
- | 1570 F$=F$+C$:GOTO 1550 | + | |
- | 1580 PR(J)=VAL(F$) | + | |
- | 1590 NEXT J | + | |
- | 1600 LINE(0,0)-(255,10),4,BF:RETURN | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e0514-02}} 2. __//Пример//__ простейшего редактора //спрайтов// [[bibliography#b22|[22]]]. | + | |
- | Программа предназначена для создания спрайтов размером 8×8. По решётке клавишами управления курсором перемещается двухцветный указатель(он виден и на фоне цвета 4, и на фоне цвета 15). При нажатии на клавишу <key>INS</key> в соответствующую клетку вставляется квадратик цвета 15. Такие квадратики образуют изображение спрайта. Для удаления квадратика нужно нажать клавишу <key>DEL</key>. Справа от решётки отображается вид спрайта, сформированный к данному моменту. После нажатия на клавишу <key>Пробел</key> производится переключение в режим ''SCREEN 1'', в котором печатаются десятичные коды, необходимые для создания спрайта и сам спрайт. После этого программа завершает свою работу. | + | |
- | \\ {{.examples:0514-02.bas|}} \\ [[+tab|wmsxbpge>0514-02.bas]] | + | |
- | <code> | + | |
- | NEW | + | |
- | Ok | + | |
- | 10 DIM A(7) | + | |
- | 20 SCREEN 2,1 | + | |
- | 30 SPRITE$(2)=CHR$(192)+CHR$(128)+CHR$(128)+CHR$(192) | + | |
- | 35 SPRITE$(3)=CHR$(48)+CHR$(16)+CHR$(16)+CHR$(48) | + | |
- | 40 FOR X=0 TO 140 STEP 20 | + | |
- | 50 FOR Y=0 TO 140 STEP 20 | + | |
- | 60 LINE(X,Y)-(X+20,Y+20),,B | + | |
- | 70 NEXT Y,X | + | |
- | 80 X=10:Y=10:I=7:J=0 | + | |
- | 90 PUT SPRITE 2,(X-4,Y-5),15,2 | + | |
- | 95 PUT SPRITE 3,(X-4,Y-5),4,3 | + | |
- | 100 PUT SPRITE 1,(200,50),,1 | + | |
- | 110 S=STICK(0) | + | |
- | 120 IF S<> 0 THEN GOSUB 500:'Перемещение | + | |
- | 130 P$=INKEY$ | + | |
- | 140 IF P$=" "THEN 200 | + | |
- | 150 IF P$<>""THEN GOSUB 1000:'Удаление,вставка | + | |
- | 160 GOTO 90 | + | |
- | 200 SCREEN 1 | + | |
- | 210 PRINT"СПРАЙТ" | + | |
- | 220 PRINT:PRINT"DATA":PRINT | + | |
- | 230 FOR K=0 TO 7 | + | |
- | 240 PRINT A(K); | + | |
- | 250 IF K<>7 THEN PRINT","; | + | |
- | 260 NEXTK | + | |
- | 270 PRINT:PRINT | + | |
- | 280 PUT SPRITE 0,(120,130),,1 | + | |
- | 290 END | + | |
- | 500 'Управление стрелками | + | |
- | 510 IF (S=1 OR S=2 OR S=8) AND Y> 10 THEN Y=Y-20:J=J-1 | + | |
- | 520 IF (S=2 OR S=3 OR S=4) AND X<150 THEN X=X+20:I=I-1 | + | |
- | 530 IF (S=4 OR S=5 OR S=6) AND Y<150 THEN Y=Y+20:J=J+1 | + | |
- | 540 IF (S=6 OR S=7 OR S=8) AND X> 10 THEN X=X-20:I=I+1 | + | |
- | 550 RETURN | + | |
- | 1000 'Удаление и вставка | + | |
- | 1010 IF ASC(P$)=18 AND POINT(X,Y)=4 THEN LINE (X-4,Y-4)-(X+4,Y+4),,BF:A(J)=A(J)+2^I | + | |
- | 1020 IF ASC(P$)=127 AND POINT(X,Y)=15 THEN LINE (X-4,Y-4)-(X+4,Y+4),4,BF:A(J)=A(J)-2^I | + | |
- | 1030 S$="" | + | |
- | 1040 FOR K=0 TO 7 | + | |
- | 1050 S$=S$+CHR$(A(K)) | + | |
- | 1060 NEXT K | + | |
- | 1070 SPRITE$(1)=S$ | + | |
- | 1080 RETURN | + | |
- | </code> | + | |
- | + | ||
- | {{anchor:e0514-03}} 3. __//Пример//__ программы, обеспечивающей //движение// фона. | + | |
- | \\ {{.examples:0514-03.bas|}} \\ [[+tab|wmsxbpge>0514-03.bas]] | + | |
- | <code> | + | |
- | 10 'А в т о р: Высотков Д.М. | + | |
- | 20 COLOR 15,1,1:SCREEN 1,3:KEY OFF:WIDTH 32:VDP(1)=VDP(1)XOR64 | + | |
- | 30 SPRITE$(0)=STRING$(8,255):FC=2 'Этот спрайт будет двигаться! | + | |
- | 40 DATA 8142241818244281,4224181824428181,2418182442818142,1818244281814224,1824428181422418,2442818142241818,4281814224181824,8181422418182442 'Данные для формирования символов движущегося фона ("вверх-вниз") | + | |
- | 50 DATA 0142241010244201,4224101024420101,2410102442010142,1010244201014224,1024420101422410,2442010142241010,4201014224101024,0101422410102442 'Данные для формирования символов движущегося фона("вправо-влево") | + | |
- | 60 FOR I=33 TO 48:READ A$:FOR T=2 TO 16 STEP 2 'Формирование | + | |
- | 70 VPOKE 8*I+T/2-1,VAL("&H"+MID$(A$,T-1,2)):NEXT:NEXT ' символов 80 W$=STRING$(32,CHR$(255)) | + | |
- | 90 FOR Y=0 TO 22:PRINT W$; 'Заполнение экрана строками W$ | + | |
- | 100 NEXT:LOCATE 0,22:FOR I=33 TO 40 | + | |
- | 110 J$(1)=J$(1)+CHR$(I):NEXT:FOR I=41 TO 40:J$(2)=J$(2)+CHR$(I):NEXT | + | |
- | 120 FOR I=48 TO 41 STEP 1:J$(4)=J$(4)+CHR$(I):NEXT | + | |
- | 130 FOR I=40 TO 33 STEP 1:J$(3)=J$(3)+CHR$(I):NEXT | + | |
- | 140 LOCATE0,22:PRINT SPACE$(32) | + | |
- | 150 LOCATE0,22:PRINTJ$(1) | + | |
- | 160 PUT SPRITE 9,(100,63),1,0 | + | |
- | 170 FOR Q=0 TO 64 STEP 16:M=M+1 ' Стирание "бяки", возникающей | + | |
- | 180 PUT SPRITE M,(Q,175),1,0 ' на экране | + | |
- | 190 NEXT:VDP(1)=VDP(1) XOR 64 ' Включение экрана | + | |
- | 200 FOR I=0 TO 7:LOCATE I,22,1 | + | |
- | 210 NEXT:YW=YW+1 | + | |
- | 220 IF YW=20 THEN LOCATE 0,22:PRINT J$(FC):FC=FC+1:YW=0 'Замена "бяки" | + | |
- | 230 IF FC=5 THEN FC=1 | + | |
- | 240 GOTO 200 | + | |
- | </code> | + | |
- | + | ||
- | <WRAP group 99%> | + | |
- | <WRAP half column> \\ </WRAP> | + | |
- | <WRAP half column><WRAP justify> | + | |
- | //Кана// — слоговая азбука японского письма (результат графического сокращения иероглифов). Существует (с.18 в.) в двух вариантах: катакана (используется для записи заимствованных слов) и хирагана (используется для собственно японских слов). | + | |
- | <WRAP rightalign> | + | |
- | —//Советский Энциклопедический словарь// | + | |
- | </WRAP></WRAP> | + | |
- | </WRAP></WRAP> | + | |
- | + | ||
- | {{anchor:e0514-04}} 4. А теперь о "загадочном" операторе | + | |
- | PUT KANJI | + | |
- | Приведём небольшой пример: | + | |
- | \\ {{.examples:0514-04.bas|}} \\ [[+tab|wmsxbpge>0514-04.bas]] | + | |
- | <code> | + | |
- | 10 SCREEN 5:COLOR 15,0,0 | + | |
- | 20 M$="National":M=LEN(M$) | + | |
- | 30 FOR X=1 TO M | + | |
- | 40 CD=&H2300+ASC(MID$(M$,X,1)) 'Видимо, &H2300 - адрес?! | + | |
- | 50 PUT KANJI (X*16-5,20),CD,11 | + | |
- | 55 PUT KANJI (X*16-5,70),CD,11 | + | |
- | 57 PUT KANJI (X*16-8,90),CD,11 | + | |
- | 60 NEXT:A$=INPUT$(1):SCREEN 0:LIST | + | |
- | </code> | + | |
- | Выполнив эту программу на компьютере, Вы получите на экране дисплея окрашенные горизонтальные полосы. Видимо (это всего лишь наше предположение!), оператор ''PUT KANJI'' позволяет выводить на экран японские иероглифы, | + | |
- | изображённые на прямоугольном фоне заданного цвета (в программе код цвета — 11). Но информации о иероглифах в памяти (а может быть в видеопамяти) компьютера почему–то уже нет?! А полосы (фон) остались! | + | |
- | + | ||
- | Кстати, оператор ''PUT KANJI'' может содержать необязательный параметр типа ''OR'', ''AND'', ''XOR'', ''PSET'', ''PRESET'', ''TOR'', ''TAND'', ''TXOR'', ''TPSET'', ''TPRESET'', расположенный после указания цвета через запятую. | + | |
- | + | ||
- | ====== Диски с примерами ====== | + | |
- | + | ||
- | Диск 1 (до [[#V.5. Графический макроязык GML]] включительно) | + | |
- | + | ||
- | {{.examples:examples051.dsk|Загрузить образ диска}} | + | |
- | + | ||
- | [[+tab|wmsxbpged>examples051.dsk|Открыть диск в WebMSX]] | + | |
- | + | ||
- | + | ||
- | Диск 2 (с [[#V.6. Спрайты]] до конца) | + | |
- | + | ||
- | {{.examples:examples052.dsk|Загрузить образ диска}} | + | |
- | + | ||
- | [[+tab|wmsxbpged>examples052.dsk|Открыть диск в WebMSX]] | + | |
- | + | ||
- | ---- | + | |
- | + | ||
- | [<>] | + | |
- | + | ||
- | + | ||
- | {{tag>MSX BASIC Book_msxbpg}} | + |