Читайте также:
|
|
Программу мы будем составлять для следующей задачи.
Задача: Создать мультфильм следующего содержания:
1) На экране возникает ночной пейзаж и секунды три ничего не происходит:
2)
3) Затем сверху слева появляется летающая тарелка (пусть это будет небольшой эллипс) и не спеша опускается на землю (до линии горизонта).
4) Затем снова раздается та же музыка.
5) Затем в окне ближайшего дома вспыхивает свет. Все.
10.2. Программирование по методу “сверху-вниз”
Повторю, что любая реальная (то есть достаточно большая и делающая «реальные» вещи) программа на Паскале содержит процедуры. Обычно более “основные” процедуры (P, I, N ¼) обращаются к менее “основным” (tochka, tire), те - к еще менее “основным” и т.д. Такая организация называется иерархией. Она подобна организации подчинения в армии - генералы приказывают полковникам, те - майорам и т.д.
Первая задача, стоящая перед программистом, - разбить программу на несколько частей, исходя из смысла задачи. В 8.2 это были части P, I, P, I, N, G. Обычно для правильного разбиения нужен опыт. В нашем случае разбиение напрашивается само собой исходя из последовательности действий мультфильма:
1) рисование пейзажа
2) пауза три секунды
3) музыка
4) движение тарелки
5) музыка
6) свет в окне
Теперь, когда мы разбили программу на части, нужно решить, какую из частей сделать процедурой, а какую можно описать просто группой операторов. Процедура выгодна тогда, когда часть или достаточно сложная (пейзаж), или встречается больше одного раза (музыка).
Итак, у нас будет три процедуры. Придумаем им имена:
* пейзаж - Landscape
* музыка - Music
* тарелка - Flying_Saucer
Теперь относительно каждой из процедур нужно решить, следует ли ее разбивать на части, причем рассуждать нужно так же, как при разбиении на части всей программы:
Music. Для музыки можно было бы использовать процедуры-ноты, но я для простоты ограничусь набором операторов Sound и Delay. Не разбиваем.
Flying_Saucer. Движение тарелки по экрану ничем не отличается от движения окружности, которое программируется небольшим циклом. Здесь тоже не нужно разбиения на части.
Landscape. Вот здесь без разбиения не обойтись. Для этого посмотрим, из чего состоит пейзаж. Он состоит из земли и неба. Земля состоит из горизонта, зеленой краски травы, домов и деревьев. Небо состоит из синей краски неба, звезд и луны. Вы можете разделить пейзаж на две большие части - землю и небо, каждую из которых делить дальше. Это будет логично и четко. Я же для простоты забуду о земле и небе и буду считать пейзаж прямо состоящим из горизонта, травы, домов, деревьев, синевы, звезд и луны. Порядок рисования я выберу такой:
1) горизонт
2) синева
3) луна
4) звезды
5) дерево
6) дерево
7) дерево
8) дом
9) дом
10) трава
Ни одна из этих десяти частей не является достаточно большой, чтобы претендовать на ранг процедуры. Однако, дом и дерево встречаются не один раз, значит они и будут процедурами. Придумаем им имена:
· дом - House
· дерево - Tree
Я на примере показал, как нужно дробить любую задачу на все более мелкие части до тех пор, пока не станет ясно, как любую из этих мелких частей запрограммировать на Паскале. Это и называется программированием по методу “сверху вниз”. Можно программировать и по методу “снизу вверх”, когда программист сначала составляет список самых мелких частей, из которых состоит задача, а потом собирает из них более крупные части.
Поговорим о том, как запрограммировать на Паскале наши самые мелкие части:
· горизонт - просто линия во весь экран
· синева - заливаем верхнюю часть экрана до горизонта синей краской
· луна - желтая окружность, залитая желтой краской
· звезды - звездное небо мы уже делали. Здесь надо будет только позаботиться, чтобы звезды не появлялись ниже горизонта
· дерево - залитые эллипс и прямоугольник
· дом - аналогично дереву
· трава - аналогично синеве
У вас может возникнуть следующий вопрос: Процедура Tree рисует некое дерево в определенном месте экрана. Как, использовав эту процедуру три раза, мы получим три дерева в разных местах экрана? Ответ: здесь нам на помощь придут переменные величины, о чем позже.
10.3. Сначала – работа над структурой программы
Прежде чем заселять жителей в город, нужно на каждом доме написать, кто в нем живет, и вообще, проследить, чтобы трамваи ходили правильно. А то возникнет неразбериха и люди не смогут ездить друг к другу в гости.
Прежде чем наполнять паскалевским содержимым наши части и процедуры, нужно сделать “скелет” программы, то есть “пустую” программу, в которой все части и процедуры ничего не делают, а только рапортуют о своем существовании, примерно так: “Работает процедура Дом”. Когда мы запустим такую программу-скелет и увидим, что все части и процедуры рапортуют в нужном порядке, мы можем надеяться, что ничего не перепутали и структура программы правильная. Вот после этого и можно постепенно заселять жителей, то есть наполнять пустые процедуры реальным содержанием. Если мы не проделаем этого заранее, то при отладке не будем знать, отчего у нас на экране получается ерунда - то ли оттого, что мы неправильно запрограммировали процедуру, то ли от того, что перепутали порядок вызова процедур.
Сначала для простоты отладим “пустую” программу без разбивки пейзажа, и если она работает правильно, тогда составим “пустую” программу полностью. Вот программа без разбивки пейзажа:
USES Graph,CRT;
VAR Device, Mode:Integer;
PROCEDURE Landscape;
BEGIN WriteLn(‘Работает процедура Пейзаж’) END;
PROCEDURE Music;
BEGIN WriteLn(‘Работает процедура Музыка’) END;
PROCEDURE Flying_Saucer;
BEGIN WriteLn(‘Работает процедура Летающая тарелка’) END;
BEGIN
Device:=0;
InitGraph(Device, Mode, ’< путь к гр.др.> ’);
DirectVideo:=false;
Landscape; { рисование пейзажа }
WriteLn(‘Работает пауза 3 секунды’); { пауза три секунды }
Music; { музыка }
Flying_Saucer; { движение тарелки }
Music; { музыка }
WriteLn(‘Работает свет в окне’); { свет в окне }
ReadLn;
CloseGraph
END.
Пояснение. В нашей программе мы используем и модуль Graph и модуль CRT, так как нам понадобятся и графика и музыка. В этом случае оператор WriteLn просто так не работает. Чтобы он все-таки заработал, необходимо предварительно выполнить оператор DirectVideo:=false. Смысл его рассматривать не будем.
В разделе операторов операторы приведены в той последовательности, в которой они должны согласно мультфильму выполняться программой. В разделе описаний процедуры описаны пока в произвольной последовательности. Каждая процедура внутри себя содержит рапорт о своей работе, чтобы мы знали “правильно ли ходят наши трамваи”. Те части программы, которые не удостоились стать процедурами (пауза, свет), рапортуют с того места, где в дальнейшем будут записаны на Паскале.
Если все у нас правильно, то результатом работы программы будет такая последовательность сообщений:
Работает процедура Пейзаж
Работает пауза 3 секунды
Работает процедура Музыка
Работает процедура Летающая тарелка
Работает процедура Музыка
Работает свет в окне
Теперь составим “пустую” программу полностью, с разбивкой пейзажа.
USES Graph,CRT;
VAR Device, Mode:Integer;
Дата добавления: 2015-11-14; просмотров: 43 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Использование случайных величинпри рисовании | | | Записываем программу целиком |