Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Web-дизайн 1 часть / Литература / ActionScript 2.0. Программирование во Flash MX 2004.pdf
Скачиваний:
354
Добавлен:
26.03.2015
Размер:
8.81 Mб
Скачать

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

var a: String = "Привет"; var b: String = а;

а += "!!!"; // Изменяем а: если переменная b является ссылкой на тот же

trace(а);

// объект, изменится и ее значение

// Выводит: Привет!!!

trace(b);

// Выводит: Привет (Следствие: b ссылается на иной объект

 

// данных, чем а)

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

var a:Object = {property:1}; // Переменная хранит объект со свойством

// property=1

var b:Object = а;

//Меняем свойство property: если а и b ссылаются на один объект данных, то

//b возвратит новое значение

a.property=2;

trace(b.property); // Выводит: 2 (объект данных был изменен)

Можно долго спорить, чего больше — хорошего или плохого — в особенностях присвоения переменной с составным значением. В передаче ссылки, а не копировании самого объекта данных имеются свои положительные и отрицательные стороны. Так, описанная тонкость зачастую ставит в тупик начинающих кодеров, которые часами не могут найти причины внезапного сбоя алгоритма. Однако нужно признать, что копирование по ссылке неизбежно — иначе нехватка оперативной памяти станет основной проблемой Flash-плейера.

«А что делать, — спросите вы, — если переменной необходимо передать именно индивидуальный объект данных?» Решений этой задачи можно найти много, в зависимости от типа объекта данных. В наиболее общем случае можно создать собственный класс и использовать затем его функциюконструктор. Если объектом данных является массив, то на помощь может прийти функция split(). Размножить клип можно, применив методы attachMovie() или duplicateMovieClip(). В общем, трудности, вызываемые особенностями операции присваивания для переменной с составным значением, легко решаемы.

3.6. Есть ли переменные в ActionScript?

Между понятиями «свойство» и «переменная» нет заметной разницы. И первое, и второе обозначают именованный контейнер для хранения данных — и на уровне реализации языка трудно найти различие между ними. Свойство является структурным элементом объекта, а переменная существует сама по себе — вот и вся разница. Однако в ActionScript стирается даже это отличие между свойствами и переменными. Так, размещая код на кадре основной временной шкалы, мы можем создать переменную с использованием ключевого слова var. Но если нам необходимо прочитать значение этой переменной из вложенного на _root клипа, то обратиться к ней мы должны как к свойству, применив оператор «.» или «[]». Переменные остаются переменными только в рамках «родной» временной шкалы. Вне ее они уже свойства определенного объекта класса MovieClip. To же самое можно сказать про локальные переменные функций: их вполне можно считать свойствами ее объекта активации (и, как будет показано в главе 4, они таковыми и являются).

Учитывая сказанное выше, правильнее было бы назвать эту главу не «Переменные», а «Свойства». Впрочем, практически все, что было изложено ранее, в равной степени справедливо как для переменных, так и для свойств. Например, присваивание свойству другого свойства с составным зна-

чением будет означать передачу ссылки на объект данных, а не его копирование.

Расположение кода на кадрах клипов делает сценарии фильмов Flash чрезвычайно гибкими. Однако это вносит и значительную путаницу во многие вопросы языка. Например, нужно ли использовать var, если переменная клипа создается удаленно? Ответ; нет, так как при этом она рассматривается как свойство. Нужно ли ключевое слово var, если объявляется глобальная переменная? Ответ: нет, так как она есть просто свойство объекта Global. Вообще оператор точки и var не совместимы: такое сочетание вызывает ошибку.

var _root.myVar=0; // Ошибка: переменная не может быть свойством

ВЕСМА-262 с каждым исполнимым кодом связана особая служебная структура, называемая объектом переменных (variable object). Свойства этого объекта имеют такие же имена, как и определенные в коде переменные и функции. Значениями же этих свойств являются объекты данных, с которыми при помощи операции присваивания связываются соответствующие переменные. При необходимости получить доступ к некоторой переменной считывается значение созданного на основании ее определения свойства объекта переменных. Понятие «объект переменных» вводится для того, чтобы стала возможной инкапсуляция исполнимого кода и реализация концепции цепочек областей видимости.

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

trace(_х);

//

Выводит:

0

trace(_root._x) //

Выводит:

0

С другой стороны, создание на основании определения переменной свойства клипа означает, что различия между понятиями «переменная» и «свойство» нивелируются. Интересные особенности возникают при обращении к свойству клипа из расположенного на нем кода. Так, если мы попытаемся получить к нему доступ, не используя имя клипа и оператор точки, а набрав только имя, то на его наличие будет просмотрена связанная с исполнимым кодом цепочка областей видимости. Это означает, что в данном случае идентификатор рассматривается как имя переменной. Если же к свойству мы пытаемся обратиться, используя имя клипа и оператор точки, то просматривается связанная с клипом цепочка прототипов (идентификатор интерпретируется как свойство). Так как три звена (сам клип, прототип конструктора MovieClip, прототип конструктора Object) у цепочки наследования клипа и цепочки областей видимости расположенного на нем кода совпадают, то в подавляющем большинстве случаев не возникает никаких различий от того, как происходит обращение к свойству клипа или переменной кода. Однако если переменная является глобальной, то обратиться к ней как к свойству клипа невозможно. Это связано с тем, что объект Global имеется в любой цепочке областей видимости, однако в цепочку наследования клипов он не входит:

_global.per="Привет"; //

Создаем глобальную переменную

trace(per);

//

Выводит: Привет (per воспринимается как переменная)

trace(_root.per);

//

Выводит: undefined (per воспринимается как свойство)

Из-за того, что переменные и функции одновременно являются свойствами и методами клипаносителя кода, путаются понятия цепочки областей видимости и цепочки прототипов. Формально в цепочку областей видимости кода, расположенного на кадре клипа, входят сам клип и объект Global. Но из-за того, что при обращении к свойству клипа на его наличие просматриваются еще и прототипы конструкторов MovieClip и Object, количество объектов, фактически входящих в цепочку областей видимости, увеличивается до четырех. Конечно, между свойствами, получаемыми из цепочки наследования клипа, и «настоящими» переменными, принадлежащими к полноценным объектам цепочки областей видимости исполнимого кода, имеются определенные отличия. Так, наследуемое свойство клипа переопределено не может быть, а собственное свойство клипа — с легкостью. Однако в подавляющем большинстве случаев свойства, принадлежащие к прототипам

конструкторов MovieClip и Object, и свойства самого клипа и объекта Global ведут себя при обращении из кода к идентификатору абсолютно идентично. Поэтому для простоты мы будем считать, что цепочка областей видимости кода клипа выглядит следующим образом: сам клип, прототип конструктора MovieClip, прототип конструктора Object, объект Global. На самом же деле, как вы уже знаете, структура цепочки областей видимости кода клипа куда проще. Ее видимое удлинение возникает из-за того, что при обращении к свойству клипа на его наличие проверяется также характерная для него цепочка прототипов.

Если бы для кода, расположенного на кадре клипа, создавался специальный объект переменных, а не использовался с этой целью сам клип, то понятия «переменная» и «свойство» было бы легко различить, и не возникало бы такой путаницы с цепочками областей видимости и цепочками прототипов. Будем надеяться, что в следующих версиях Flash ситуация в этом отношении изменится. Имеется только одно серьезное отличие между переменными и свойствами. Переменную можно строго типизировать, а свойство — нет. Впрочем, эта особенность существует лишь до компиляции. В транслированном коде обнаружить различие между свойством клипа и переменной расположенного на нем кода невозможно.

Проанализировав приведенные факты, мы можем сделать следующее заключение: в ActionScript в принципе нет переменных, а есть переменные-свойства. Такой странный симбиоз возник из-за применения не слишком удачной концепции языка программирования. Согласитесь, что не так много общего между браузером и программой векторной анимации, чтобы использовать для них один стандарт скриптового языка (а ЕСМА-262 — это стандарт именно Web-скриптов). Пожалуй, определенной стройности ActionScript можно было бы добиться, отказавшись от жесткой привязки сценариев к временной шкале — но это радикально усложнит кодирование, поэтому разработчики вряд ли на это пойдут (но первый шаг разработчиками к этому уже сделан — в область видимости кода методов внешних классов входят только объект, вызвавший метод, и объект Global).

Автор этой книги считает запутанность понятий переменная-свойство одним из главных недостатков ActionScript. При всем желании невозможно описать эту головоломку какой-то стройной схемой. Да и лучше этого не делать — вывод, к которому вы придете, приведен в предыдущем абзаце. Действуйте интуитивно — это самый верный подход во многих вопросах программирования во Flash.

3.7. Удаление переменных

Удалить переменную можно, используя оператор delete:

var new_var:Number=3; delete new_var;

trace(new_var); // Выводит: undefined (переменная удалена)

В том случае, если операция удаления произошла успешно, оператор delete возвращает true. Если же переданный идентификатор изначально не указывал на определенный объект данных, то результат — false:

var new_var=3;

trace(delete new_var); // Выводит: true

trace(delete new_var); // Выводит: false (переменной new_var больше не

// существует)

Свои особенности имеет удаление объектов данных составного типа. Так, если вы используете в качестве операнда delete переменную, значением которой является объект или клип, то произойдет удаление указателя, связывающего переменную и объект данных, а не самого объекта данных. Любой объект типа object будет существовать в памяти до тех пор, пока на него имеется хотя бы одна ссылка. Чтобы удалить его, нужно использовать оператор delete по отношению ко всем указывающим на него переменным. Только в этом случае при ближайшей чистке памяти данный объект будет выгружен как мусор. Чтобы удалить клип, нужно использовать метод removeMovieClip()

— применение же по отношению к его идентификатору оператора delete не даст никакого результата.

Любая переменная и любое свойство могут быть защищены от удаления. Как это сделать, мы обсуждали в предыдущей главе в разделе, посвященном атрибутам свойств.

Проект 3: Пружинный маятник

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

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

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

Y = Ay cos((k / m)12 t +ϕ0 ) eαt .

Сложная формула? Совсем нет! Вы без труда в ней разберетесь, прочитав описание входящих в нее величин:

Y – величина абсолютного удлинения пружины в момент времени t. Периодически изменяется в интервале от 0 до Ау.

Ау — амплитуда колебаний, т. е. максимальное удлинение пружины, Если скорость груза при начале движения равна 0, то амплитуда соответствует удлинению пружины в этот момент.

m — масса груза. Чем она больше, тем более плавными будут колебания (т. е. частота колебательного движения будет ниже),

к — жесткость пружины. Чем она больше, тем более резкими будут колебания (т. е. их частота будет выше).

t — время от начала колебательного движения.

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

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

Вы можете сказать: «Мы хотим научиться программировать на ActionScript, а нам читают лекции по физике! Нельзя ли без формул?» Увы — нет. Математика — единственный язык, на котором можно описывать явления вокруг нас. Любая игра, эффект или даже анимация — это прежде всего математическая модель. Уверенное владение основами математики хотя бы за курс средней школы просто необходимо тому, кто хочет проявить себя на поприще Flash-программирования. В этой книге мы будем создавать много моделей, в которых будет активно использоваться королева наук

— и вы увидите, какой это мощный инструмент (в умелых руках, разумеется).

Не будем утомлять вас длинными теоретическими выкладками и приступим-таки к реализации задуманного проекта.

С чего бы начать? Разумно будет вначале создать пружинный маятник в «железе» и лишь затем приступать к написанию кода (иначе мы просто не сможем его тестировать).

В том, чтобы нарисовать груз или опору, нет никакой сложности. А вот как изобразить пружину? Рисовать несколько часов одно кольцо за другим? Слишком сложно. Тем более, что звенья пружины вряд ли при всем старании получатся одинаковыми, отчего она будет казаться грубой, а сам

маятник — не особо похожим на оригинал. Мы поступим по-другому. Нарисовав фрагмент, соответствующий одному шагу спирали, мы создадим нужное число его копий (10-20). Совмещая затем участки пружины, получим необходимое изображение с минимальными усилиями. Несколько советов:

Чтобы нарисовать элемент пружины, создайте эллипс, а затем, разрезав его кольцо при помощи ластика, просто сместите один конец кривой вверх, а другой — вниз (рис. 3.1, а).

Работайте в увеличенном масштабе (300-500 %) при этом проще совмещать концы фрагментов пружины.

Соединив 4—5 фрагментов, в дальнейшем используйте полученный элемент для сборки пружины — это значительно ускорит выполнение поставленной задачи.

Чтобы создать копию фрагмента, выделите его и выполните протаскивание мышью при нажатой клавише <Ctrl>.

Когда нужное число витков будет соединено, немного удлините свободные концы пружины — за один из них она будет прикреплена к основе, к другому будет присоединен груз. Затем трансформируйте пружину (инструмент Free Transform) так, чтобы она выглядела сжатой (рис. 3.1, b). Переведите изображение пружины в клип (<F8>).

Рис. 3.1. Заготовка для пружины (а) и пружина (b)

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

 

Теперь необходимо нарисовать груз. Как он будет выглядеть —

 

это решать только вашей фантазии. Наиболее очевидный вариант

 

— небольшой металлический цилиндр (рис. 3.2). Нарисовав гру-

 

зик, переведите его в клип.

 

Третьим необходимым элементом пружинного маятника является

 

подвес. Чтобы не тратить много времени, изобразите его просто

 

как узкий и длинный прямоугольник. Сохранить его необходимо

 

как символ типа graph.

Рис. 3.2. Пружинный маятник

Собираем маятник из созданных компонентов. У вас должно по-

лучиться приблизительно то же, что и на рис. 3.2.

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

Для начала даем клипам с изображением пружины и груза идентификаторы. Первый называем pruzina, второй — gruz.

Создаем новый слой и, назвав его «Код», размешаем выше существующего. Выделяем его первый кадр и нажимаем <F9>. При этом открывается наш основной холст — панель Actions, заставляя задуматься: с чего бы лучше начать?

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

var k:Number = 1000;

//

Жесткость пружины

var n:Number = 200;

//

Масса груза

var alpha:Number = 0.1; //

Коэффициент трения

var A:Number = null;

//

Амплитуда (она будет задана при смещении груза)

Присвоенные значения взяты навскидку: при тестировании модели мы их заменим более подходящими. Пока трудно предполагать, чему должна равняться каждая переменная — хотя бы потому, что смещение мы будем измерять не в метрах, а в пикселях.

Выводить колебательную систему из равновесия пользователь будет самостоятельно, оттягивая указателем мыши грузик на нужное расстояние вниз. Чтобы обеспечить соответствующие трансформации, нам необходимо как-то регистрировать событие нажатия кнопки мыши в тот момент, когда курсор располагается над клипом gruz. Сделать это можно несколькими способами, самый простой из которых связан с использованием «кнопочного» события onPress (во Flash MX клипы стали листенерами таких событий):

gruz.onPress=function():Void { trace (this);

}

Войдите в режим тестирования. Если после «щелчка» по грузу откроется панель Output со строкой «_level0.gruz», то, удалив функцию trace(), продолжайте выполнение проекта. Иначе — ищите ошибку.

О том, что пользователь начал протаскивание грузика, должны узнать остальные Функцииобработчики сценария. Для этого при наступлении события onPress клипа gruz будем устанавливать булев флаг в специальной переменной:

gruz_press=true; // Эта переменная должна быть создана там же, где и // остальные, со значением false

После того как произойдет щелчок курсором по грузу, он должен начать перемешаться вслед за курсором мыши. Причем смещение должно происходить только По вертикали и в определенных пределах (пружина не может растягиваться и сжиматься до бесконечности). Справиться с этой задачей очень просто, воспользовавшись мощным методом класса MovieClip startDrag (center, xmin, ymin, xmax, ymax), где:

center — параметр, определяющий, перемешается ли клип относительно той точки, в которой находился указатель мыши в момент активации метода (false), или же точка его центра и указатель жестко связываются (true). Очевидно, что нам скорее подходит первый режим;

xmin, ymin, xmax, ymax — точки, задающие границу области перемещения клипа.

Определяем граничные точки следующим образом:

xmin. Смещения по горизонтали происходить не должно, поэтому задаем левую границу области, равную текущей координате X клипа: this._x.

ymin. Груз не должен подниматься выше того положения, когда маятник находится в равновесии. Конечно, это отклонение от физической модели пружинного маятника, в которой насколько пружина растягивается, настолько она потом и сжимается. Однако будем считать, что пружина у нас достаточно жесткая и полностью сжата. А это означает, что при колебаниях ее длина никогда не будет заметно меньшей, чем в состоянии покоя.

Положение груза при равновесии фиксируем в специальной переменной (она должна быть задана вместе с остальными):

var gruz_pos :Number=gruZ._y;

xmax. Задаем аналогично xmin.

ymax. Даже самая пластичная пружина не может растянуться более, чем в 3—4 раза от ее начальной длины. Поэтому нижний предел смещения груза стоит ограничить 3 значениями ширины клипа pruzina, отсчитанными от его положения в состоянии равновесия. Так как ширина пружины будет непрерывно меняться, то необходимо зафиксировать ее начальную величину, создав для этого отдельную переменную:

var pruz_height:Nυ =pruzina._height;

Строку с методом startDrag() заносим в тело единственной пока функции-обработчика:

gruz.startDrag(false,this._x, gruz_pos, this,_x, 3*pruz_height+gruz_pos);

При отпускании кнопки мыши протаскивание груза должно быть закончено. «Отловить» соответствующее событие можно несколькими способами. Во-первых, можно воспользоваться встроенным «кнопочным» событием onRelease. Однако при этом не будет фиксироваться отпускание кнопки мыши в том случае, если указатель находится не над клипом. Чтобы предусмотреть такую ситуацию, придется использовать специальный обработчик onReleaseOutside. Два обработчика для одного события — это слишком много. Мы поступим по-другому: «отлавливая» событие отпускания кнопки мыши при помощи обработчика onMouseUp, будем проверять, чему равняется переменная graz_press. Если она равна true, значит, груз протаскивался. При этом необходимо остановить работу метода startDragO (для чего используем метод stopDragO), а также указать в переменной gruz_press, что перемещения клипа gruz больше не происходит. В виде ActionScript описанные действия материализуются как:

_root.onMouseUp = function():Void { if(gruz_press) {

gru2_press = false; gruz.StopDrag();

}

};

Тестируем фильм и проверяем, все ли работает так, как задумано. Если да, то продолжаем выполнение проекта.

Раз груз жестко закреплен на пружине, то при его смещении она должна растягиваться. Этот процесс должен быть непрерывным, поэтому реализующий деформацию код следует вызывать достаточно часто. Для этого можно или создать функцию-обработчик события onEnterFrame, или воспользоваться таймером setInterval(). Мы, ввиду простоты, применим первый вариант:

_root,onEnterFrame = function():Void { };

При вызове созданного обработчика будем проверять, чему равна переменная gruz_press. Если ей соответствует true, значит, груз протаскивается. При этом пружина должна быть удлинена на-

столько, насколько он сместился относительно своего начального положения:

pruzina._height = pruz_height+gruz._y-gruz_pos;

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

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

var pruz_width:Number = pruzina._width;

Ниже выражения, определяющего длину пружины, в теле обработчика onEnterFrame наберите следующую строку:

pruzina._width = pruz_width;

Тестируем фильм. Вот теперь действительно все работает так, как надо!

В том случае, если переменная pruz_press равна false (груз был отпущен), по событию onEnterFrame будем запускать механизм, реализующий колебания маятника. Для его создания переведем на язык ActionScript рассмотренную в начале описания проекта формулу:

else { // Math.abs — метод, вычисляющий абсолютную величину числа pruzina._height = pruz_height + Math.abs(A*Math.cos (Math.sqrt (k/m)*time) *Math.exp (-alpha*time));

pruzina._width = pruz_width;

gruz._y = gruz_pos+Math.abs (A*Math.cos (Math.sqrt(k/m)*time) *Math.exp(-alpha*time));

}

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

В заданных формулах используются величины, которые мы еще не описали:

Амплитуда А. Должна быть вычислена в момент отпускания груза как разность между его положением и координатой точки равновесия:

А = gruz._y-gruz_pos; // Строку добавляем в тело обработчика события onMouseUp

Время time. Должно быть определено равным 0, там же, где и амплитуда. Явно переменную time надо задать вместе с остальными, присвоив значение null. Менять значение времени мы будем сразу же после вычисления текущего значения смешения:

time+=l/12; // Заносим выражение в блок предложения else обработчика

// onEnterFrame

Более точно время колебаний можно измерять, воспользовавшись возможностями класса Date или глобальной функцией getTimer(). Однако не будем забегать вперед.

Чтобы вычисления колебаний маятника не происходили до того, как он будет выведен из равновесия, соответствующие выражения будем выполнять лишь в том случае, если time отлична от null:

if(time!=null) {

}

Модель готова. Остался последний штрих. Мы должны предоставить пользователю удобный интерфейс, при помощи которого можно будет менять значения параметров. Для этого создадим три поля ввода и, подписав их «Масса», «Жесткость», «Трение», свяжем (поле Var) с переменными m, k, alpha. Теперь любое изменение текста в полях будет сопровождаться переопределением переменных, что позволит быстро проверить работу модели при самом различном сочетании значений параметров.

Если при тестировании созданный вами фильм не будет работать, то найти ошибку вы сможете, сравнив его с авторским проектом, который сохранен в папке ПроектЗ архива проектов.

Соседние файлы в папке Литература