КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Буфер клавиатурыПри первом прочтении этот параграф можно пропустить. Компьютер работает с клавиатурой сложнее, чем нам кажется. Причина сложности вот в чем. Предположим, вы играете в игру, где с клавиатуры управляете движением самолета. Чтобы избежать попадания вражеского снаряда, вы должны бросить самолет вверх и направо, то есть очень быстро нажать клавишу и сразу затем клавишу ®. Как только вы нажали на , компьютер несколько долей секунды обрабатывает это нажатие, то есть соображает, что теперь ваш самолет нужно бросить вверх, и наконец действительно так и делает. Если вы успели нажать на клавишу ® до того, как он это сообразил, то компьютер, не имеющий буфера клавиатуры, просто не обратит внимания на это нажатие, потому что занят мыслительной работой. А это плохо, так как вы совершенно не обязаны во время игры думать о том, успевает ли компьютер за вашими пальцами. Чтобы исправить ситуацию, нужно дать компьютеру возможность в случае занятости не игнорировать нажатия на клавиши, а запоминать их, чтобы обработать, как только освободится. Для этого и служит буфер клавиатуры- место в оперативной памяти, в котором и запоминаются эти нажатия. Вы можете, пока компьютер занят, нажать на клавиши до 16 раз - и буфер клавиатуры запомнит все 16 клавиш в том порядке, в котором они нажимались. Вот как можно изобразить процесс ввода в компьютер текста «Привет недоверчивым!», когда процессор занят: На клавиши пока не нажимали:
Нажали на клавишу П:
Нажали еще на одну клавишу - р:
Нажали еще на несколько клавиш:
Нажали на клавиши в 15-й и 16-й раз:
Нажали на клавишу в 17-й раз – раздается предупреждающий писк компьютера, буква в в буфер не записывается:
Пока мы буфер клавиатуры только заполняли. А кто его опорожнит? Процессор. Процессор, выполняющий программу на Паскале, берет что-то из буфера клавиатуры только в тот момент, когда выполняет процедуру ReadLn, функцию ReadKey и еще кое-что. В остальное время он для буфера клавиатуры занят. Посмотрим, как он берет информацию из буфера, выполняя ReadKey. Пусть перед выполнением ReadKey в буфере была такая информация:
При выполнении ReadKey первая из введенных в буфер букв – П – отправляется на обработку:
Еще одно выполнение ReadKey:
Помните, что если вы нажали на какую-нибудь клавишу и не отпускаете ее, то это равносильно частому-частому нажатию на эту клавишу. Если процессор в это время не занят выполнением процедуры ReadLn или большого количества функций ReadKey, то некому выуживать информацию из буфера клавиатуры, он мгновенно переполняется и вы слышите раздраженный писк. На практике события, описанные всеми этими схемами, встречаются редко. Только неопытный пользователь будет жать на клавиши в тот момент, когда компьютер не готов воспринимать информацию. Обычно подавляющую часть времени буфер клавиатуры пуст, ни процессор, ни клавиатура с ним не работают. Раз в вечность человек в нужный момент нажимает на клавишу, в буфере появляется символ и тут же процессор при помощи ReadLn или ReadKey выуживает его оттуда и снова надолго буфер пуст.
Теперь я могу описать правила работы KeyPressed и ReadKey как надо:
Функция KeyPressedотвечает на вопрос, есть ли что-нибудь в буфере клавиатуры. В буфере клавиатуры она никаких изменений не производит.
Функция ReadKeyзабирает из буфера клавиатуры символ, который попал туда раньше других. Если буфер клавиатуры пуст, то ReadKey останавливает компьютер. Ожидание длится до тех пор, пока в буфере не появится символ (в результате нажатия на клавишу). ReadKey сразу же его оттуда забирает и компьютер продолжает работу.
Теперь вам должно быть понятно, зачем мы в одной из предыдущих циклических программ использовали KeyPressed. Без нее ReadKey просто остановила бы компьютер.
ReadLn при своей работе опустошает буфер клавиатуры. И еще. Мы знаем, что любая информация в компьютере закодирована (см. 3.5). Поэтому, хоть для простоты я везде говорил, что в буфер попадает символ, правильней было бы сказать, что в буфер попадает код символа.
Как очистить буфер клавиатуры, не останавливая компьютер: while KeyPressed do kl:=ReadKey то есть «пока в буфере не пусто, таскай оттуда по символу».
Как ждать нажатия на произвольную клавишу: repeat until KeyPressed то есть «повторяй ничегонеделанье, пока не нажмут на клавишу». Задание 98 “Управляемая точка”: Назначьте четыре клавиши. По нажатии одной из них точка по экрану перемещается на некоторый шаг вверх, другой - вниз, третьей - влево, четвертой - вправо. В 12.11 вы узнаете, как управлять компьютером при помощи клавиш управления курсором и других. Задание 99: Добавьте еще пару клавиш - одну для увеличения шага, другую - для уменьшения.
6.9. Гетерархия. Задание на игру “Торпедная атака” При создании мультфильма в 10.2 мы придерживались стиля программирования сверху-вниз, когда процедуры образовывали подчинение, иерархию: все “основные” процедуры вызывались из раздела операторов основной программы. Менее “основные” процедуры вызывались из “основных” и т.д. Однако, для многих задач, особенно связанных с моделированием сложных объектов и искусственного интеллекта, такой метод неестественен. Процедуры здесь часто получаются равноправными и вызываются не из раздела операторов основной программы, а согласно логике задачи вызывают друг друга по мере необходимости. Такая организация общения процедур называется гетерархией. Сейчас я напишу задание на создание программы для игры “Торпедная атака”. А затем предложу схему организации процедур этой программы. В учебных целях я выберу гетерархию, хотя в данном случае можно было бы обойтись и иерархией.
Задание 100:Наверху экрана слева направо плывет вражеский корабль. Внизу притаился ваш торпедный аппарат. В подходящий момент времени вы нажимаете клавишу - и торпеда плывет вверх. Если вы попали, то видна вспышка от взрыва, может быть, на мгновение виден и сам взрыв, раздается коротенькая радостная мелодия, на экране - коротенький поздравительный текст, счетчик подбитых кораблей на экране увеличивается на 1. Если не попали, то зрительные и звуковые эффекты - совсем другие. В любом случае увеличивается на 1 счетчик выпущенных торпед. Когда торпеды у вас кончатся (скажем, их было 10), игра заканчивается. Программа анализирует ваши успехи и в зависимости от них выдает на экран текст, скажем “Мазила!”, если вы не попали ни разу из 10, или “Профессионал!”, если вы попали 8 раз. Затем спрашивает, будете ли вы играть еще.
Схема программы (читайте ее не сверху вниз, а снизу вверх): Uses CRT,Graph;
VAR все переменные опишем именно здесь, а не внутри процедур
опережающие описания процедур
PROCEDURE ZAVERSHENIE_IGRI; Здесь анализируем, насколько успешно стрелял игрок, отмечаем мелодией, цветом и текстом его достижения, затем спрашиваем, будет ли игрок играть еще. Если да, то вызываем процедуру NACHALO, иначе закрываем графический режим и - Halt.
PROCEDURE NE_PORA_LI; Здесь увеличиваем счетчик торпед. Если он>10, то вызываем процедуру ZAVERSHENIE_IGRI, иначе процедуру RISUNOK.
PROCEDURE NEPOPAL; Здесь программируем все эффекты в случае промаха, после чего вызываем процедуру NE_PORA_LI.
PROCEDURE POPAL; Здесь программируем все эффекты в случае попадания, после чего вызываем процедуру NE_PORA_LI.
PROCEDURE ATAKA; Здесь плывут одновременно корабль и торпеда. Затем в зависимости от ситуации вызываются процедуры POPAL или NEPOPAL. Учтите также ситуацию, когда вы просто забыли выстрелить.
PROCEDURE KORABL; Здесь плывет корабль до выстрела, который вызывает процедуру ATAKA. PROCEDURE RISUNOK; Здесь рисуем береговую линию, указываем на экране имя игрока, счетчики торпед и подбитых кораблей. Затем вызываем процедуру KORABL.
PROCEDURE NACHALO; Здесь устанавливаем в нуль счетчики торпед и подбитых кораблей, спрашиваем имя игрока и делаем все прочее, что нужно делать один раз за всю игру в самом ее начале. Затем прямо из процедуры NACHALO вызываем процедуру RISUNOK. Begin инициализация графического режима; DirectVideo:=false; {Чтобы работал WriteLn } NACHALO {Вот такой короткий раздел операторов.} End. Помощь (читайте ее только в крайнем случае). Когда вы выстрелите, вы заметите, что корабль стал плыть медленнее. Это происходит потому, что теперь компьютер за каждый шаг корабля должен еще просчитать и изобразить на экране торпеду, а на это нужно время. Увеличьте шаг движения корабля после выстрела или уменьшите паузу Delay так, чтобы скорость осталась примерно той же. Как компьютер определит, попал или не попал? Нужно в тот момент, когда торпеда доплывет до линии движения корабля, сравнить горизонтальные координаты корабля и торпеды, и если они достаточно близки, считать, что попал.
Улучшение. Если у всех кораблей будет одинаковая скорость, то попадать будет слишком просто, а значит и играть неинтересно. Сделайте скорость кораблей случайной. Конечно, не совсем уж (скажем, в условных единицах скорости диапазон от 0 до 10 – это слишком), а в пределах разумного (скажем, от 4 до 8 – это нормально). Причем не нужно менять скорость одного и того же корабля в процессе движения. Пусть она остается постоянной, а то все будет зависеть не от мастерства, а от везения. Различаются скорости только разных кораблей. Пусть игрок сможет выбирать из нескольких уровней трудности. Трудность удобнее всего увеличивать, уменьшая размеры корабля, то есть требуемую величину близости координат корабля и торпеды при определении попадания.
Еще одно задание 101: «Графический редактор». Создайте программу, которая бы, повинуясь нажатию разных клавиш клавиатуры, рисовала бы, расширяла, сжимала, перемещала по экрану, заливала разными цветами прямоугольники (а если вам понравилось, то и эллипсы и линии и прочее). В качестве «печки, от которой танцевать», можете взять решение задания 98.
Мы с вами закончили первый из двух циклов знакомства с Паскалем. Если вам удались «Торпедная атака» или «Графический редактор» и они у вас работают не хуже, чем указано в задании, то у вас должна появиться уверенность, что теперь, умело разбивая программы на небольшие процедуры, вы можете создавать программы любой сложности, а значит цель этого цикла достигнута. Я вас поздравляю - вам присваивается звание “Программист-любитель III ранга”!
Часть III. Программирование на Паскале – второй уровень Если вам кажется, что вы уже все можете, то вы правы и неправы. Правы потому, что вы можете написать сколь угодно большую программу, разбив ее на разумное число процедур. Неправы потому, что ваша способность манипулировать данными в памяти компьютера еще очень ограничена. А без нее вам не поддадутся «умные» задачи. Например, не познакомившись с так называемыми массивами, вы не сможете запрограммировать игру в крестики-нолики или решить задачу о выходе из лабиринта; не освоив работу со строками, символами и файлами, вы не сможете решить задачу о мало-мальски серьезной секретной шифровке и расшифровке сообщений. Эта часть посвящена тому, чтобы · Расширить ваши знания о возможностях Паскаля · Сделать ваши знания о Паскале строгими, иначе вы не сможете исправлять в программах грамматические ошибки, а значит программы у вас работать не будут.
Начнем с наведения порядка в наших знаниях о Паскале.
|