Земля, пруд, три дерева и два фонаря
Пора переходить к процедуре Земля. Мы будем работать над ней и над другими процедурами точно так же, как и над процедурой Месяц. То есть, сначала запишем в окно кода ее заготовку, затем увеличим на один оператор главную процедуру рисования и затем постепенно будем создавать процедуру Земля, постоянно проверяя результат. Таким же манером мы будем действовать и в дальнейшем, пока проект не будет готов. Земля. Это большой зеленый прямоугольник ниже уровня горизонта: Sub Земля() Гр.FillRectangle(Brushes.LightGreen, 0, Уровень_горизонта, Me.Width, Me.Height) End Sub
Пруд. Это эллипс черного цвета с белой окантовкой: Sub Пруд() Dim x As Single = 400 Dim y As Single = 300 Dim Размер As Single = 200 Гр.FillEllipse(Brushes.Black, x, y, Размер, Размер / 3) 'Вода Гр.DrawEllipse(Pens.White, x, y, Размер, Размер / 3) 'Берег End Sub Обратите внимание, как легко превратить эту процедуру в процедуру с параметрами. Тогда легко будет разместить в парке несколько прудов. В будущем вы сможете делать отражение звезд в пруду. Три одиночных дерева и два одиночных фонаря. Вот когда понадобились наши Дерево и Фонарь: Sub Три_одиночных_дерева() Дерево(420, 240, 50) Дерево(600, 260, 70) Дерево(430, 260, 100) End Sub
Sub Два_одиночных_фонаря() Фонарь(480, 230, 60) Фонарь(540, 260, 140) End Sub Ряд деревьев Ряд деревьев – 1 версия. Нарисовать ряд деревьев с помощью процедуры Дерево – все равно, что нарисовать ряд окружностей с помощью процедуры DrawEllipse, что мы делали в 8.5. Вот как выглядит процедура, рисующая подходящий ряд из пары десятков деревьев на горизонте: Sub Ряд_деревьев() Dim x As Single = 400 Dim y As Single = Уровень_горизонта - 30 Dim i As Integer For i = 1 To 20 Дерево(x, y, 30) x = x + 15 Next End Sub Числа 400, 30, 30, 15 я подобрал так, чтобы картинка была более-менее похожа на заданную. Кстати, вы видите, что в нашей программе мы обращаемся из процедуры пользователя Ряд_деревьев к процедуре пользователя Дерево. Ряд деревьев – 2 версия. На нашем рисунке присутствуют еще два ряда деревьев. Они чем-то похожи, а чем-то непохожи на наш ряд. Нам нужно решить: будем ли мы, когда дело дойдет до их рисования, скромно создавать для них новые процедуры или же прямо сейчас смело сконструируем единую процедуру с такими хитрыми параметрами, чтобы она могла нарисовать любой из трех рядов деревьев на нашем рисунке. Нет ни малейшего сомнения, что мы выбираем второе. Эта процедура получится небольшим усложнением 1 версии. Попробуем ее переписать так, чтобы получился левый из двух рядов в аллее. Рисовать нужно начинать с самого дальнего дерева, иначе дальние загородят ближних. Если в первой версии у нас от дерева к дереву менялась только горизонтальная координата x, то здесь у нас должны меняться и вертикальная координата y (увеличиваться), и Размер (увеличиваться). Причем, если в 1 версии x рос, то здесь он должен уменьшаться:. Sub Ряд_деревьев_2_версия() Dim x As Single = 220 Dim y As Single = Уровень_горизонта - 30 Dim Размер As Single = 30 Dim i As Integer For i = 1 To 20 Дерево(x, y, Размер) x = x - 22 y = y + 20 Размер = Размер + 10 Next End Sub Временно допишите в процедуру рисования вызов этой процедуры и проверьте, как она работает. Есть ли у вас уверенность, что меняя только числа в процедуре, вы сможете рисовать любые нужные на рисунке ряды деревьев? У меня есть. Действительно, ряд деревьев на горизонте получается при помощи этой процедуры изменением четырех чисел в следующих строках: Dim x As Single = 400 x = x + 15 y = y + 0 Размер = Размер + 0 А раз так, то пора числа и переменные превращать в параметры. Ряд деревьев – окончательная версия. Посмотрим, от каких переменных и чисел зависит вид ряда деревьев. Начнем просматривать нашу процедуру сверху вниз: Dim x As Single = 220 Dim y As Single = Уровень_горизонта - 30 Dim Размер As Single = 30 Эти три строки определяют положение и размер самого первого дерева ряда. Конечно же, все три переменные должны стать параметрами. For i = 1 To 20 Эта строка задает число деревьев в ряду. Конечно, мы захотим иметь возможность рисовать ряды с разным числом деревьев. Число 20 превращаем в параметр. x = x - 22 y = y + 20 Размер = Размер + 10 Три числа: -22, 20, 10 определяют направление ряда деревьев, расстояние между деревьями и увеличение размеров от дерева к дереву. Без них не обойтись. Еще три параметра. Итого 7 параметров. Все они нужны, ничего не попишешь. Превращаем нашу процедуру в процедуру с параметрами: Sub Ряд_деревьев(ByVal x As Single, ByVal y As Single, ByVal Размер As Single, ByVal Число_деревьев _ As Integer, ByVal Шаг_по_гориз As Single, ByVal Шаг_по_вертик As Single, ByVal Увеличение As Single) Dim i As Integer For i = 1 To Число_деревьев Дерево(x, y, Размер) x = x + Шаг_по_гориз y = y + Шаг_по_вертик Размер = Размер + Увеличение Next End Sub Вы спросите: почему в строках x = x + Шаг_по_гориз y = y + Шаг_по_вертик стоят плюсы, ведь часто там должны быть и минусы? Отвечаю: Плюсы трогать не будем, а нужного результата будем добиваться отрицательным значением шага. Например, вот как будет выглядеть вызов процедуры для рисования левого из двух рядов в аллее: Ряд_деревьев (220, Уровень_горизонта - 30, 30, 20, -22, 20, 10) А вот как – для ряда деревьев на горизонте: Ряд_деревьев (400, Уровень_горизонта - 30, 30, 20, 15, 0, 0) У процедуры есть недостаток: расстояния между соседними деревьями вдали и вблизи одинаковы, что не соответствует законам перспективы. Вы можете исправить это положение, сделав шаги зависящими от размера. Ряд фонарей и аллея Ряд фонарей. Эта процедура строится совершенно аналогично процедуре Ряд_деревьев. Создайте ее самостоятельно. Вот что получилось у меня: Sub Ряд_фонарей(ByVal x As Single, ByVal y As Single, ByVal Размер As Single, ByVal Число_фонарей _ As Integer, ByVal Шаг_по_гориз As Single, ByVal Шаг_по_вертик As Single, ByVal Увеличение As Single) Dim i As Integer For i = 1 To Число_фонарей Фонарь(x, y, Размер) x = x + Шаг_по_гориз y = y + Шаг_по_вертик Размер = Размер + Увеличение Next End Sub Процедуры Ряд_деревьев и Ряд_фонарей до смешного одинаковы. Это значит, что если как следует подумать, процедуру Ряд_фонарей не надо было выдумывать, а надо было просто скопировать Ряд_деревьев и немного изменить. Одинаковость наводит еще на одну мысль: а что, если сделать единую процедуру для рисования ряда деревьев или фонарей? Что именно рисовать, решают еще один строковый параметр и оператор If внутри процедуры. Но это упражнение я оставляю для энтузиастов. Теперь добавьте в главную процедуру рисования вызов процедуры рисования ряда фонарей на горизонте: Ряд_фонарей (20, Уровень_горизонта - 30, 70, 6, 25, 0, 0) 'на горизонте Кстати, ваше окно кода сильно выросло и доставляет вам неудобство тем, что для поиска нужной процедуры вам приходится его долго прокручивать вверх-вниз. Хотите избавиться от лишней прокрутки – перечтите 6.1.3 и щелкните по крохотным минусикам у заголовков ненужных пока процедур. Их тела скроются из вида, освободив дефицитное место. Чтобы их вернуть, щелкайте по плюсикам. Аллея. Мы прекрасно понимаем, что вместо создания и вызова процедуры Аллея можно бы просто написать два вызова процедуры Ряд_деревьев и один вызов процедуры Ряд_фонарей. И мороки было бы меньше. Все это верно. Но в этом случае мы ослушались бы прохожего, а этого нельзя делать, потому что мы нарушили бы великий принцип простоты и наглядности. К тому же, кто знает, может быть в будущем наш парк украсится несколькими аллеями? А? Пояснять процедуру Аллея излишне. Вот она: Sub Аллея() Ряд_деревьев(220, Уровень_горизонта - 30, 30, 20, -22, 20, 10) 'левый Ряд_деревьев(240, Уровень_горизонта - 30, 30, 20, 12, 20, 10) 'правый Ряд_фонарей(220, Уровень_горизонта, 70, 20, -36, 64, 30) End Sub Обратите внимание, что значение первого параметра во всех трех обращениях почти одинаково. Это наводит на мысль превратить его в параметр процедуры Аллея. Вот так: Sub Аллея(ByVal x As Single) Ряд_деревьев(x, Уровень_горизонта - 30, 30, 20, -22, 20, 10) 'левый Ряд_деревьев(x + 20, Уровень_горизонта - 30, 30, 20, 12, 20, 10) 'правый Ряд_фонарей(x, Уровень_горизонта, 70, 20, -36, 64, 30) End Sub А вот окончательный вид главной процедуры рисования парка: Private Sub Рисуем_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Рисуем.Click Гр = Me.CreateGraphics Звездное_небо() Месяц() Земля() Пруд() Три_одиночных_дерева() Два_одиночных_фонаря() Ряд_деревьев(400, Уровень_горизонта - 30, 30, 20, 15, 0, 0) 'на горизонте Ряд_фонарей(20, Уровень_горизонта - 30, 70, 6, 25, 0, 0) 'на горизонте Аллея(220) End Sub Проект завершен. Меняя параметр процедуры Аллея, мы сдвигаем всю аллею целиком влево-вправо. Ощущение могущества! Чем хорошо программирование: минимальные усилия, а результат меняется колоссально. Если бы мы рисовали вручную, сколько времени нам понадобилось бы, чтобы перерисовать всю аллею? Попробуйте как следует понизить уровень горизонта. Вся земля сдвинулась, а пруд и окружающие его деревья и фонари остались на месте. В результате чего очутились на небе. Н-да-а … Это потому, что при их рисовании мы уровень горизонта не учитывали.
Популярное: Почему человек чувствует себя несчастным?: Для начала определим, что такое несчастье. Несчастьем мы будем считать психологическое состояние... Организация как механизм и форма жизни коллектива: Организация не сможет достичь поставленных целей без соответствующей внутренней... Как вы ведете себя при стрессе?: Вы можете самостоятельно управлять стрессом! Каждый из нас имеет право и возможность уменьшить его воздействие на нас... Как выбрать специалиста по управлению гостиницей: Понятно, что управление гостиницей невозможно без специальных знаний. Соответственно, важна квалификация... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (561)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |