Статьи

Создайте динамическое уведомление об авторских правах во Flash: часть 2

В первой части этого длинного руководства мы рассмотрели несколько полезных методов программирования, включая планирование, подготовку и загрузку XML, объявление переменных и функций, масштабирование, выравнивание и многие другие. Давайте закончим наше обманчиво простое (и очень гибкое) уведомление об авторских правах.


Если вы помните из части 1 , все наши переменные форматирования текста теперь содержат соответствующие значения. Мы можем присвоить эти переменные свойствам объекта TextFormat, который мы создали еще раньше. На этот раз давайте пропустим общую модель и просто сделаем это:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
     
//ASSIGN THE VARIABLES TO THE PROPERTIES OF THE TEXT FORMAT
 
//font
 
tfCopyright.font=theFont;
 
//size
 
tfCopyright.size=theFontSize;
 
//color
 
tfCopyright.color=theFontColor;
 
//url
 
tfCopyright.url=theLink;
 
//target
 
tfCopyright.target=theTarget;
 
//bold
 
tfCopyright.bold=theFontBold;
 
//italic
 
tfCopyright.italic=theFontItalic;
 
//underline
 
tfCopyright.underline=theFontUnderline;

Поскольку наш TextField отображает текст динамически, а текст теоретически может иметь любую длину, мы должны автоматически изменить размер текстового поля. Чтобы сделать это, мы также должны выровнять текст влево или вправо. Я говорю слева:

1
2
3
4
5
     
//AUTO-SIZE THE TEXT FIELD AND LEFT-ALIGN THE TEXT IN IT
 
    txtCopyright.autoSize=TextFieldAutoSize.LEFT;

Вся наша работа по форматированию текста была бы напрасной, если бы мы не применили ее к фактическому TextField. Сейчас самое время сделать это:

1
2
3
4
5
     
//APPLY TEXT FORMAT TO THE TEXT FIELD
 
    txtCopyright.setTextFormat(tfCopyright);

Как вы можете видеть , мы используем метод setTextFormat () класса TextField, передавая имя нашей переменной TextFormat в качестве одного аргумента.

Мы только что завершили часть нашего кода для форматирования текста. Вот как должна выглядеть наша основная функция:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
+015
016
+017
018
019
020
021
022
023
024
025
026
027
028
029
+030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
+055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//THE MAIN FUNCTION
     
function makeCopyright(copyright:XML):void {
         
    //Get the initial year from XML
    initialYear=copyright.initialYear.text();
 
    //Get the copyright holder text from XML
 
    theHolder=copyright.theHolder.text();
 
    //Get the statement text from XML
 
    theStatement=copyright.theStatement.text();
         
    //Get the current year from the local system
 
    currentDate = new Date();
    currentYear=currentDate.getFullYear();
    currentYearString=currentYear.toString();
         
    //Create the text field object
 
    txtCopyright = new TextField();
         
    //Add the TextField object to the Display List
         
    addChild(txtCopyright);
         
    //Display text in the TextField
 
    txtCopyright.text=»COPYRIGHT © «+initialYear+»–»+currentYearString+» «+theHolder+» «+theStatement;
 
    //FORMAT THE TEXT
         
    //Create TextFormat object
 
    tfCopyright = new TextFormat();
         
    //GET THE STRING AND NUMERIC VALUES FOR TEXT FORMAT FROM XML
         
    //theFont
         
    theFont=copyright.theFont.text();
         
    //theFontSize
         
    theFontSize=copyright.theFontSize.text();
         
    //theFontColor
         
    theFontColor=copyright.theFontColor.text();
         
    //theLink
         
    theLink=copyright.theLink.text();
         
    //theTarget
         
    theTarget=copyright.theTarget.text();
         
    //CONVERT STRINGS TO BOOLEANS AND HANDLE POSSIBLE ERRORS
         
    //theFontBold
 
    theFontBoldString=copyright.theFontBold.text();
 
    if (theFontBoldString==»true») {
        theFontBold=true;
    } else if (theFontBoldString == «false») {
        theFontBold=false;
    } else {
             
        //Handle the error
             
        txtCopyright.text = «Please set the correct Boolean value in theFontBold XML item.»;
    }
         
    //theFontItalic
 
    theFontItalicString=copyright.theFontItalic.text();
 
    if (theFontItalicString==»true») {
        theFontItalic=true;
    } else if (theFontItalicString == «false») {
        theFontItalic=false;
    } else {
             
        //Handle the error
             
        txtCopyright.text = «Please set the correct Boolean value in theFontItalic XML item.»;
    }
         
    //theFontUnderline
 
    theFontUnderlineString=copyright.theFontUnderline.text();
 
    if (theFontUnderlineString==»true») {
        theFontUnderline=true;
    } else if (theFontUnderlineString == «false») {
        theFontUnderline=false;
    } else {
             
        //Handle the error
             
        txtCopyright.text = «Please set the correct Boolean value in theFontUnderline XML item.»;
    }
 
    //ASSIGN THE VARIABLES TO THE PROPERTIES OF THE TEXT FORMAT
         
    //font
         
    tfCopyright.font = theFont;
         
    //size
         
    tfCopyright.size=theFontSize;
         
    //color
         
    tfCopyright.color=theFontColor;
         
    //url
         
    tfCopyright.url=theLink;
         
    //target
         
    tfCopyright.target=theTarget;
         
    //bold
         
    tfCopyright.bold=theFontBold;
 
    //italic
         
    tfCopyright.italic=theFontItalic;
 
    //underline
         
    tfCopyright.underline=theFontUnderline;
 
    //AUTO-SIZE THE TEXT FIELD AND LEFT-ALIGN THE TEXT IN IT
 
    txtCopyright.autoSize=TextFieldAutoSize.LEFT;
 
    //APPLY TEXT FORMAT TO THE TEXT FIELD
         
    txtCopyright.setTextFormat(tfCopyright);
 
    } // Closes the main function

И это то, что мы должны увидеть после того, как мы восстановим .as и повторно опубликуем .swf :

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


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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//GET THE VALUES FROM XML FOR THE VARIABLES THAT POSITION THE TEXT FIELD AND CONTROL ITS OPACITY
 
//theXOffset
     
theXOffset = copyright.theXOffset.text();
     
//theYOffset
     
theYOffset = copyright.theYOffset.text();
     
//relativeTo
 
relativeTo=copyright.relativeTo.text();
     
//leftOrRight
 
leftOrRight=copyright.leftOrRight.text();
 
//Convert String to Boolean for slideIn
 
slideInString=copyright.slideIn.text();
 
if (slideInString==»true») {
    slideIn=true;
} else if (slideInString == «false») {
    slideIn=false;
}
 
//slideInSpeed
     
slideInSpeed = copyright.slideInSpeed.text();
 
//slideInSpeedIndex
 
slideInSpeedIndex = copyright.slideInSpeedIndex.text();
                                                     
//Convert String to Boolean for fadeIn
 
fadeInString=copyright.fadeIn.text();
 
if (fadeInString==»true») {
    fadeIn=true;
} else if (fadeInString == «false») {
    fadeIn=false;
}
 
//fadeInSpeed
 
fadeInSpeed = copyright.fadeInSpeed.text();
 
//fadeInSpeedIndex
 
fadeInSpeed = copyright.fadeInSpeed.text();
 
//initialAlpha
 
initialAlpha=copyright.initialAlpha.text();
     
//finalAlpha
 
finalAlpha=copyright.finalAlpha.text();

У нас есть только еще одно значение для передачи из нашего XML-файла в ActionScript, и это значение содержится в элементе movieClipName нашего XML-файла. Давайте сначала получим строковое значение:

1
2
3
4
5
//movieClipName name
 
movieClipName=copyright.movieClipName.text();

Нам нужна эта переменная, чтобы получить ее значение из XML, потому что мы хотим иметь возможность разместить наше уведомление об авторских правах относительно сцены или любого мувиклипа, который мы можем выбрать. Предположительно, у нашего Flash-проекта будет несколько видеороликов в корневой временной шкале, и мы можем захотеть, чтобы уведомление об авторских правах появилось внизу одного из этих клипов. Зная имя экземпляра этого клипа, мы хотим иметь возможность установить его в файле XML, чтобы мы могли разместить уведомление об авторских правах без необходимости повторной публикации файла .swf.

Наша переменная movieClipName уже содержит значение, переданное из XML. В нашем XML-файле мы произвольно установили для movieClipName значение mcContentModule (и вы, возможно, помните, что таково имя экземпляра ссылочного MovieClip, который мы поместили в верхней части сцены в нашем файле .fla). После того как мы получим это значение в нашем коде ActionScript, оно станет «mcCopyrightModule» : строковое значение в двойных кавычках. Нам нужно преобразовать это значение из String в имя экземпляра MovieClip (так сказать, чтобы удалить кавычки) и выбрать это имя экземпляра из имен экземпляров всех MovieClip, которые мы можем иметь на сцене в нашем проекте Flash.

Чтобы выбрать один MovieClip из многих, которые могут находиться в корневой временной шкале проекта .fla, мы можем использовать синтаксис преобразования MovieClip и квадратные скобки, например:

1
MovieClip(root[movieClipName])

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

1
referenceClip = MovieClip(root[movieClipName]);

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

001
002
003
004
005
006
007
008
009
010
011
012
013
014
+015
016
+017
018
019
020
021
022
023
024
025
026
027
028
029
+030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
+055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
//THE MAIN FUNCTION
     
function makeCopyright(copyright:XML):void {
         
    //Get the initial year from XML
 
    initialYear=copyright.initialYear.text();
 
    //Get the copyright holder text from XML
 
    theHolder=copyright.theHolder.text();
 
    //Get the statement text from XML
 
    theStatement=copyright.theStatement.text();
         
    //Get the current year from the local system
 
    currentDate = new Date();
    currentYear=currentDate.getFullYear();
    currentYearString=currentYear.toString();
         
    //Create the text field object
 
    txtCopyright = new TextField();
         
    //Add the TextField object to the Display List
         
    addChild(txtCopyright);
         
    //Display text in the TextField
 
    txtCopyright.text=»COPYRIGHT © «+initialYear+»–»+currentYearString+» «+theHolder+» «+theStatement;
 
    //FORMAT THE TEXT
         
    //Create TextFormat object
 
    tfCopyright = new TextFormat();
         
    //GET THE STRING AND NUMERIC VALUES FOR TEXT FORMAT FROM XML
         
    //theFont
         
    theFont=copyright.theFont.text();
         
    //theFontSize
         
    theFontSize=copyright.theFontSize.text();
         
    //theFontColor
         
    theFontColor=copyright.theFontColor.text();
         
    //theLink
         
    theLink=copyright.theLink.text();
         
    //theTarget
         
    theTarget=copyright.theTarget.text();
         
    //CONVERT STRINGS TO BOOLEANS AND HANDLE POSSIBLE ERRORS
         
    //theFontBold
 
    theFontBoldString=copyright.theFontBold.text();
 
    if (theFontBoldString==»true») {
        theFontBold=true;
    } else if (theFontBoldString == «false») {
        theFontBold=false;
    } else {
             
        //Handle the error
             
        txtCopyright.text = «Please set the correct Boolean value in theFontBold XML item.»;
    }
     
    //theFontItalic
 
    theFontItalicString=copyright.theFontItalic.text();
 
    if (theFontItalicString==»true») {
        theFontItalic=true;
    } else if (theFontItalicString == «false») {
        theFontItalic=false;
    } else {
             
        //Handle the error
             
        txtCopyright.text = «Please set the correct Boolean value in theFontItalic XML item.»;
    }
         
    //theFontUnderline
 
    theFontUnderlineString=copyright.theFontUnderline.text();
 
    if (theFontUnderlineString==»true») {
        theFontUnderline=true;
    } else if (theFontUnderlineString == «false») {
        theFontUnderline=false;
    } else {
             
        //Handle the error
             
        txtCopyright.text = «Please set the correct Boolean value in theFontUnderline XML item.»;
    }
 
    //ASSIGN THE VARIABLES TO THE PROPERTIES OF THE TEXT FORMAT
         
    //font
         
    tfCopyright.font = theFont;
         
    //size
         
    tfCopyright.size=theFontSize;
         
    //color
         
    tfCopyright.color=theFontColor;
         
    //url
         
    tfCopyright.url=theLink;
         
    //target
         
    tfCopyright.target=theTarget;
         
    //bold
         
    tfCopyright.bold=theFontBold;
 
    //italic
         
    tfCopyright.italic=theFontItalic;
 
    //underline
         
    tfCopyright.underline=theFontUnderline;
 
    //AUTO-SIZE THE TEXT FIELD AND LEFT-ALIGN THE TEXT IN IT
 
    txtCopyright.autoSize=TextFieldAutoSize.LEFT;
 
    //APPLY TEXT FORMAT TO THE TEXT FIELD
         
    txtCopyright.setTextFormat(tfCopyright);
         
    //GET THE VALUES FROM XML FOR THE VARIABLES THAT POSITION THE TEXT FIELD
 
    //theXOffset
         
    theXOffset = copyright.theXOffset.text();
         
    //theYOffset
         
    theYOffset = copyright.theYOffset.text();
         
    //relativeTo
 
    relativeTo=copyright.relativeTo.text();
         
    //leftOrRight
 
    leftOrRight=copyright.leftOrRight.text();
 
    //Convert String to Boolean for slideIn
 
    slideInString=copyright.slideIn.text();
 
    if (slideInString==»true») {
        slideIn=true;
    } else if (slideInString == «false») {
        slideIn=false;
    }
 
    //slideInSpeed
         
    slideInSpeed = copyright.slideInSpeed.text();
 
    //slideISpeedIndex
 
    slideInSpeedIndex = copyright.slideInSpeedIndex.text();
                                                         
    //Convert String to Boolean for fadeIn
 
    fadeInString=copyright.fadeIn.text();
 
    if (fadeInString==»true») {
        fadeIn=true;
    } else if (fadeInString == «false») {
        fadeIn=false;
    }
 
    //fadeInSpeed
     
    fadeInSpeed = copyright.fadeInSpeed.text();
 
    //fadeInSpeedIndex
 
    fadeInSpeedIndex = copyright.fadeInSpeedIndex.text();
 
    //initialAlpha
 
    initialAlpha=copyright.initialAlpha.text();
         
    //finalAlpha
 
    finalAlpha=copyright.finalAlpha.text();
 
    //movieClipName name
 
    movieClipName=copyright.movieClipName.text();
 
    //Convert the string into a MovieClip name
         
    referenceClip=MovieClip(root[movieClipName]);
 
        } //Closes the main function

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

1
2
3
4
5
6
//SET RELATIVE COORDINATES
 
function setRelativeCoordinates():void {
 
}

Возможная позиция нашего уведомления об авторских правах будет определяться тремя основными переменными : lativeX , lativeZeroX иlativeY . Если уведомление об авторских правах размещено рядом с правым краем сцены или мувиклипа, его координата X будет основана на значении переменнойlativeX. Если уведомление об авторских правах размещено рядом с левым краем сцены или мувиклипа, его координата X будет основана на значении переменнойlativeZeroX. Координата Y уведомления об авторских правах будет в обоих случаях основываться на значении переменнойlativeY.

Фактические значения переменныхlativeX , lativeZeroX иlativeY должны, в свою очередь, зависеть от значения переменнойlativeTo, которая может содержать строки «stage» или «movieclip» .

Если переменнаяlativeTo содержит строку «stage», относительный X должен быть равен ширине сцены, относительный ZeroX должен быть равен 0, а относительный Y должен быть равен высоте сцены.

Если переменнаяlativeTo содержит строку «movieclip», относительный X должен быть равен сумме координаты X контрольного клипа и ширины контрольного клипа , относительный ZeroX должен быть равен координате Х контрольного клипа , а относительный Y должен быть равен сумма координаты Y контрольного клипа и его высоты.

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

01
02
03
04
05
06
07
08
09
10
11
12
//POSITION THE TEXT FIELD RELATIVE TO THE STAGE OR A MOVIECLIP
 
if (relativeTo==»stage») {
    relativeX=stage.stageWidth;
    relativeZeroX=0;
    relativeY=stage.stageHeight;
 
} else if (relativeTo==»movieclip») {
    relativeX=referenceClip.x+referenceClip.width;
    relativeZeroX=referenceClip.x;
    relativeY=referenceClip.y+referenceClip.height;
    }

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

На этом этапе мы нарисуем форму для маски, а на следующем этапе мы установим маску, чтобы при необходимости показывать наш объект TextField.

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
//POSITION THE TEXT FIELD RELATIVE TO THE STAGE OR A MOVIECLIP
 
if (relativeTo==»stage») {
    relativeX=stage.stageWidth;
    relativeZeroX=0;
    relativeY=stage.stageHeight;
 
} else if (relativeTo==»movieclip») {
    relativeX=referenceClip.x+referenceClip.width;
    relativeZeroX=referenceClip.x;
    relativeY=referenceClip.y+referenceClip.height;
 
    //DRAW THE MASK
 
    copyrightMask = new MovieClip();
}

Когда мы размещаем уведомление об авторском праве относительно MovieClip, мы хотим, чтобы наша маска была такой же ширины, как MovieClip, минус значение XOffset, умноженное на два (одно смещение слева и одно справа). Мы хотим, чтобы маска была такой же высоты, как наш TextField. Мы хотим разместить маску на расстоянии XOffset от левого края мувиклипа (который будет центрировать маску по горизонтали) — и на расстоянии YOffset от нижнего края мувиклипа.

Теперь давайте нарисуем маску.

01
02
03
04
05
06
07
08
09
10
//DRAW THE MASK
 
copyrightMask = new MovieClip();
 
copyrightMask.graphics.beginFill(0xFF0000,0);
copyrightMask.graphics.drawRect(0, 0, referenceClip.width-(theXOffset*2), txtCopyright.height);
copyrightMask.graphics.endFill();
copyrightMask.x=referenceClip.x+theXOffset;
copyrightMask.y = (referenceClip.y+referenceClip.height)-(txtCopyright.height+theYOffset);

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

1
2
3
4
5
6
7
//ASSIGN THE MASK TO THE TEXT FIELD
 
txtCopyright.mask=copyrightMask;
     
//ADD THE MASK TO THE DISPLAY LIST
     
addChild(copyrightMask);

Теперь давайте посмотрим, что мы имеем в этой части нашего кода:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//POSITION THE TEXT FIELD RELATIVE TO THE STAGE OR A MOVIECLIP
 
if (relativeTo==»stage») {
    relativeX=stage.stageWidth;
    relativeZeroX=0;
    relativeY=stage.stageHeight;
 
} else if (relativeTo==»movieclip») {
    relativeX=referenceClip.x+referenceClip.width;
    relativeZeroX=referenceClip.x;
    relativeY=referenceClip.y+referenceClip.height;
 
    //DRAW THE MASK
 
    copyrightMask = new MovieClip();
    copyrightMask.graphics.beginFill(0xFF0000,0);
    copyrightMask.graphics.drawRect(0, 0, referenceClip.width-(theXOffset*2), txtCopyright.height);
    copyrightMask.graphics.endFill();
    copyrightMask.x=referenceClip.x+theXOffset;
    copyrightMask.y = (referenceClip.y+referenceClip.height)-(txtCopyright.height+theYOffset);
 
    //ASSIGN THE MASK TO THE TEXT FIELD
 
    txtCopyright.mask=copyrightMask;
         
    //ADD THE MASK TO THE DISPLAY LIST
         
    addChild(copyrightMask);
}

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

Если мы сделаем координату Y TextField равной относительной Y, вершина нашего TextField будет размещена даже с нижней части сцены или MovieClip. Нам нужно вычесть высоту TextField из относительного Y. Мы также можем захотеть вычесть значение переменной YOffset , если хотим, чтобы наше уведомление об авторских правах появлялось немного выше нижнего края сцены или мувиклипа.

Все это переводится в следующую строку кода:

1
2
3
//SET THE RELATIVE Y COORDINATE FOR THE TEXT FIELD
 
txtCopyright.y=relativeY-(txtCopyright.height+theYOffset);

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

Если наше уведомление об авторских правах настроено так, чтобы оно отображалось по правому краю сцены или мувиклипа, мы должны вычесть ширину уведомления об авторских правах и значение XOffset из относительногоX . Если наше уведомление об авторском праве будет отображаться на левом краю сцены или мувиклипа, мы должны добавить XOffset к относительному ZeroX .

Следовательно, нам нужна левая конечная относительная координата и правая конечная относительная координата:

1
2
3
4
5
//ASSIGN VALUES TO THE FINAL LEFT AND RIGHT X COORDINATES FOR THE TEXT FIELD
 
xFinalRight = relativeX-(txtCopyright.width+theXOffset);
 
xFinalLeft=relativeZeroX+theXOffset;

Нам нужно обобщить окончательную X-координату для нашего TextField, но поместив ее в собственную переменную, значение которой будет меняться в зависимости от значения переменной leftOrRight . Мы делаем это с помощью условного оператора if … else if:

1
2
3
4
5
6
7
//ASSIGN THE VALUE TO THE FINAL RELATIVE X COORDINATE
 
if (leftOrRight==»right») {
    xFinal=xFinalRight;
} else if (leftOrRight == «left») {
    xFinal=xFinalLeft;
}

Предполагая, что все мувиклипы в нашем главном проекте Flash имеют фиксированный размер, сцена является единственным объектом, который потребует, чтобы наше уведомление об авторских правах обновило свою позицию, если пользователь изменит размер окна браузера. Мы уже установили относительную координату Y, которая будет обновляться при изменении размера сцены. Если уведомление об авторских правах расположено на левом краю сцены, изменение размера окна браузера не повлияет на относительную X-координату TextField. Однако, если уведомление об авторском праве расположено на правом краю сцены, окончательная относительная координата X текстового поля должна будет обновляться каждый раз при изменении размера окна браузера. Задача очень ясна, и все, что нам нужно сделать, это объяснить ее Flash на ее родном языке:

1
2
3
4
5
//REPOSITION THE TEXT FIELD ON RESIZE IF ITS PLACED RELATIVE TO STAGE AT THE RIGHT
 
if (leftOrRight==»right»&&relativeTo==»stage») {
    txtCopyright.x=xFinalRight;
    }

Это завершает функцию setRelativeCoordinates , и вся функция должна выглядеть следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//SET RELATIVE COORDINATES
 
function setRelativeCoordinates():void {
 
    //POSITION THE TEXT FIELD RELATIVE TO THE STAGE OR A MOVIECLIP
 
    if (relativeTo==»stage») {
        relativeX=stage.stageWidth;
        relativeZeroX=0;
        relativeY=stage.stageHeight;
 
    } else if (relativeTo==»movieclip») {
        relativeX=referenceClip.x+referenceClip.width;
        relativeZeroX=referenceClip.x;
        relativeY=referenceClip.y+referenceClip.height;
 
        //DRAW THE MASK
 
        copyrightMask = new MovieClip();
        copyrightMask.graphics.beginFill(0xFF0000,1);
        copyrightMask.graphics.drawRect(0, 0, referenceClip.width-(theXOffset*2), txtCopyright.height);
        copyrightMask.graphics.endFill();
        copyrightMask.x=referenceClip.x+theXOffset;
        copyrightMask.y = (referenceClip.y+referenceClip.height)-(txtCopyright.height+theYOffset);
 
        //ASSIGN THE MASK TO THE TEXT FIELD
 
        txtCopyright.mask=copyrightMask;
 
        //ADD THE MASK TO THE DISPLAY LIST
 
        addChild(copyrightMask);
    }
 
    }
 
    //SET THE RELATIVE Y COORDINATE FOR THE TEXT FIELD
 
    txtCopyright.y=relativeY-(txtCopyright.height+theYOffset);
 
    //ASSIGN VALUES TO THE FINAL LEFT AND RIGHT X COORDINATES FOR THE TEXT FIELD
 
    xFinalRight = relativeX-(txtCopyright.width+theXOffset);
 
    xFinalLeft=relativeZeroX+theXOffset;
 
    //ASSIGN THE VALUE TO THE FINAL RELATIVE X COORDINATE
 
    if (leftOrRight==»right») {
        xFinal=xFinalRight;
    } else if (leftOrRight == «left») {
        xFinal=xFinalLeft;
    }
 
    //REPOSITION THE TEXT FIELD ON RESIZE IF IT’S PLACED RELATIVE TO STAGE AT THE RIGHT
 
    if (leftOrRight==»right»&&relativeTo==»stage») {
        txtCopyright.x=xFinalRight;
 
    } //Closes the conditional statement
} //Closes setRelativeCoordinates

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

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

Для контроля скорости наших анимационных эффектов у нас есть числовые переменные, содержащие значения, полученные из XML: slideInSpeed , slideInSpeedIndex , fadeInSpeed и fadeInSpeedIndex . Изменение их значений в XML изменит скорость анимационных эффектов. У нас также есть две переменные таймера slideInTimer и fadeInTimer . Мы перейдем к использованию переменных slideInSpeedIndex и fadeInSpeedIndex, а также к созданию таймера для эффекта постепенного появления, но теперь пришло время создать таймер для вставной анимации. Чтобы поместить объект Timer в переменную slideInTimer, нам просто нужно вызвать конструктор класса Timer и передать ему переменную slideInSpeed в качестве аргумента:

1
2
3
//CREATE THE TIMER FOR SLIDE-IN ANIMATION
     
slideInTimer = new Timer(slideInSpeed);

Сначала давайте определим функцию, как обычно:

1
2
3
4
5
6
7
8
//SLIDING FUNCTION
 
//slideCopyright
 
function slideCopyright():void {
 
 
} //Closes slideCopyright

Мы хотим немного смягчить наш скользящий эффект, чтобы этот эффект выглядел немного более реалистичным, но все, что нам нужно, — это простое облегчение, и поэтому, как мы и договаривались ранее, нам не имеет смысла импортировать его. из огромных, богатых опциями популярных классов твинеров, таких как Caurina или TweenLite. Мы просто включим упрощение в код для нашего анимированного эффекта вставки. В идеале было бы замечательно написать код для эффекта слайдера таким образом, чтобы скольжение и замедление выполнялись одним и тем же оператором. И у нас есть только вещь для этого!

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

«Ослабление» означает изменение координат визуального объекта таким образом, чтобы с каждым следующим отправленным событием этот объект размещался ближе к конечным координатам с уменьшающимися интервалами. Проще говоря, например, если расстояние от текущей координаты X нашего TextField до его конечной координаты X составляет 80 пикселей, и это расстояние делится на два всякий раз, когда срабатывает таймер, то при первом тике таймера наша Объект TextField перемещается на 40 пикселей ближе к его окончательной координате X, на втором тике TextField перемещается только на 20 пикселей ближе к его окончательным координатам X, на третьем тике он перемещается на 10 пикселей, на четвертом тике на 5 в пятый тик — на 2,5, на шестой — на 1,25 и т. д. С точки зрения иллюзии движения может показаться, что TextField движется к своей конечной координате X, постепенно замедляясь. Разделив расстояние на два, вы получите действительно быструю анимацию. Но расстояние не нужно делить на два, оно может быть разделено на большее число. Чем выше число, тем медленнее анимация.

Чтобы перевести это в программные термины, нам понадобятся следующие данные:

  • Текущая координата X нашего объекта Text Field, обновляемая с каждым событием Timer
  • Конечная координата X объекта Text Field должна прибыть — это значение содержится в нашей переменной xFinal
  • Расстояние между текущей координатой X TextField и его окончательной координатой X также обновляется с каждым событием Timer — мы подготовили переменную xDistance для хранения этого значения
  • Индекс деления, который будет отбирать определенный процент xDistance каждый раз, когда отправляется событие Timer — этот индекс передается из XML в переменную slideInSpeedIndex

Имея данные, теперь мы можем написать код. Сначала давайте расскажем Flash, как рассчитать расстояние между текущей координатой X TextField и конечной координатой X:

1
2
     
xDistance = xFinal-txtCopyright.x;

Это логично, потому что определение расстояния — это разница между текущей позицией и исходной позицией: я сейчас нахожусь в Нью-Йорке, а разница между координатами Нью-Йорка и Парижа примерно равна расстоянию от кофейной чашки на моем стол к чьей-то дымящейся кофейной чашке на столе в Le Cafe Constant.

Теперь для фактического смягчения:

1
2
     
txtCopyright.x=txtCopyright.x+xDistance/slideInSpeedIndex;

Мы говорим Flash, чтобы он обновил текущую X-координату TextField, добавив к нему числовое значение, полученное путем деления текущего расстояния до конечного X на индекс, содержащийся в переменной slideInSpeedIndex

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

Я знаю, как безумно это звучало только сейчас, но то, что я описал, на самом деле хорошая практика кодирования. Мы должны обязательно остановить таймер и удалить прослушиватель событий, когда они больше не нужны (в нашем случае, когда TextField прибывает к месту назначения), чтобы таймер прекратил тикать, а прослушиватель событий прекратил проверять события, которые никогда не будут повторятся. Таким образом, мы освобождаем часть вычислительной мощности компьютера пользователя и, в конечном счете, экономим драгоценные природные ресурсы. Мы можем забыть или не успеть сделать это позже, когда нам придется прокрутить снизу вверх и найти нашу функцию вставки, так почему бы не сделать это сейчас, когда мы пишем функцию? В общем, вы можете часто останавливать таймеры и удалять прослушиватели событий, прежде чем запускать / добавлять их. В этом нет ничего необычного, это довольно часто.

Итак, вот что нам, видимо, нужно написать:

1
2
3
4
5
6
//Stop the timer and remove the event listener
     
if (txtCopyright.x==xFinal) {
    slideInTimer.stop();
    slideInTimer.removeEventListener(TimerEvent.TIMER, slideRight);
}

Мы только что сказали Flash остановить таймер и удалить его даже прослушиватель, когда объект TextField достигнет своей окончательной координаты. Код выглядит идеально, и все же он не будет работать. Проблема в том, что наше TextField никогда не достигнет своей окончательной координаты. Из-за неприятного парадокса дихотомии, который имеет полную силу над Flash, TextField просто будет продолжать перемещать себя все более и более небольшими приращениями на протяжении всей бесконечности, незаметно приближаясь к конечной координате x, даже не достигая ее.

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

1
2
3
4
5
6
//Stop the timer and remove the event listener
     
if (Math.round(txtCopyright.x)==xFinal) {
    slideInTimer.stop();
    slideInTimer.removeEventListener(TimerEvent.TIMER, slideRight);
}

Если мы хотим сделать его почти идеальным, мы также можем заставить объект TextField принять координату xFinal :

1
2
3
4
5
6
7
//Stop the timer and remove the event listener
     
if (Math.round(txtCopyright.x)==xFinal) {
    txtCopyright.x=xFinal;
    slideInTimer.stop();
    slideInTimer.removeEventListener(TimerEvent.TIMER, slideRight);
}

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
//SLIDING FUNCTION
 
//slideCopyright
 
function slideCopyright():void {
    xDistance=xFinal-txtCopyright.x;
    txtCopyright.x=txtCopyright.x+xDistance/slideInSpeedIndex;
 
    //Stop the timer and remove event listener
 
    if (Math.round(txtCopyright.x)==xFinal) {
        //txtCopyright.x=xFinal;
        slideInTimer.stop();
        slideInTimer.removeEventListener(TimerEvent.TIMER, slideCopyright);
    }
 
} //Closes slideCopyright

По сравнению с основным достижением программирования, которое мы только что достигли, функция, которая помещает наш TextField в его окончательную координату X, если для элемента slideIn в нашем XML-файле задано значение false, действительно скромна:

1
2
3
4
5
6
7
8
//NON-SLIDING FUNCTION
 
//placeCopyright
 
function placeCopyright():void {
 
    txtCopyright.x=xFinal;
} //Closes placeCopyright

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

1
2
3
function positionTheCopyright():void {
     
}

Если уведомление об авторском праве расположено относительно этапа, при каждом изменении размера этапа необходимо заново корректировать координаты уведомления об авторском праве. Нам нужен прослушиватель событий для проверки изменения размера этапа и обработчик событий для изменения положения TextField, содержащего текст об авторских правах. Хорошей новостью является то, что мы уже создали обработчик событий, и это не что иное, как функция setRelativeCoordinates, которую мы создали, что, кажется, давным-давно. Теперь давайте добавим прослушиватель событий:

1
2
3
//Add the resize event listener
     
stage.addEventListener(Event.RESIZE, setRelativeCoordinates);

Наш код теперь зависит от события resize, и ничего не произойдет до того, как произойдет событие resize. Но что, если на самом деле никому нет дела до изменения размеров сцены, чтобы привести вещи в движение? Чтобы убедиться, что TextField получает команду для позиционирования себя, мы собираемся запустить одно событие изменения размера внутри нашего кода. Размер рабочей области фактически не будет изменен (или вы можете подумать о том, что размер рабочей области изменяется с текущей ширины и высоты до точно такой же ширины и высоты), но Flash получит инструкцию для выполнения тех же операций, которые он выполняет если размер сцены изменился:

1
2
3
//Fire a resize event
     
stage.dispatchEvent(new Event(Event.RESIZE));

Наше TextField сначала материализуется в своей начальной координате. Если анимированный эффект вставки включен , TextField плавно переместится из этой начальной координаты в позицию xFinal . Если эффект вставки отключен, TextField мгновенно перейдет в положение xFinal . Такой переход не будет виден, потому что начальная координата TextField заставит его сначала появиться либо вне сцены (если переменнаяlativeTo содержит значение «stage» ), либо вне маски (если переменнаяlativeTo содержит «movieclip» « значение. В любом случае TextField не будет отображаться в исходном положении:

1
2
3
4
5
6
7
//Set the initial X coordinate for the TextField
 
    if (leftOrRight==»right») {
        txtCopyright.x=relativeZeroX-txtCopyright.width;
    } else if (leftOrRight==»left») {
        txtCopyright.x=relativeX;
    }

Теперь мы должны вызвать две наши функции размещения: slideCopyright и placeCopyright . Какой из них выполнит свою работу, будет зависеть от логического значения, содержащегося в переменной slideIn . Давайте сначала установим структуру:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
/*Slide in the text field, if slideIn in XML set to true
or place the text field if slideIn in XML set to false*/
 
if (slideIn==true) {
 
    //Slide the TextField
 
    slideCopyright();
 
} else if (slideIn == false) {
 
    //Place the TextField without sliding
 
    placeCopyright();
         
}

Помните, как мы остановили таймер, который мы никогда не запускали, и удалили прослушиватель событий, который мы никогда не добавляли? Пришло время запустить таймер и добавить прослушиватель событий. Таймер первый:

1
2
3
4
5
//Start the timer
 
slideInTimer.start();
         
}

Теперь слушатель события

1
2
3
//Add the event listener
         
slideInTimer.addEventListener(TimerEvent.TIMER, slideCopyright);

Прослушиватель событий, который мы только что добавили, может слышать только события Timer, и каждый раз, когда такое событие происходит, слушатель события вызывает обработчик событий, который мы (удивительно!) Уже создали. Изобретательно названный slideCopyright функция является то , что обработчик события.

Я уверен, что теперь вы понимаете, почему мы фактически остановили таймер перед его запуском и удалили прослушиватель событий перед его добавлением. Это работает так: когда таймер начинает тикать, слушатель событий реагирует на каждый тик и каждый раз вызывает функцию slideCopyright . Эта функция выполняется столько раз, сколько необходимо для того, чтобы TextField скользил достаточно близко к своей координате xFinal, чтобы вызвать код, который останавливает этот таймер и удаляет прослушиватель событий. Я знаю, что это немного похоже на решение кубика Рубика, но это действительно лучший способ сделать это.


Это не изменит внешний вид анимации, но немного отнимает нагрузку на компьютер, который будет ее воспроизводить. Когда TextField кэшируется как растровое изображение, Flash не придется перерисовывать его каждый раз, когда меняются его координаты.

1
2
3
//CACHE AS BITMAP
 
txtCopyright.cacheAsBitmap=true;

На этом мы завершаем часть, в которой мы пишем функцию positionTheCopyright , и вся функция должна выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    //POSITION AND REPOSITION THE TEXT FIELD
 
    function positionTheCopyright():void {
         
    //Add the resize event listener
         
    stage.addEventListener(Event.RESIZE, setRelativeCoordinates);
         
    //Fire a resize event
         
    stage.dispatchEvent(new Event(Event.RESIZE));
 
    //Set the initial X coordinate for the TextField
 
    if (leftOrRight=="right") {
        txtCopyright.x=relativeZeroX-txtCopyright.width;
    } else if (leftOrRight=="left") {
        txtCopyright.x=relativeX;
    }
 
    /*Slide in the text field, if slideIn in XML set to true
    or place the text field if slideIn in XML set to false*/
 
    if (slideIn==true) {
 
        //Start the timer
 
        slideInTimer.start();
             
        //Add the event listener
             
        slideInTimer.addEventListener(TimerEvent.TIMER, slideCopyright);
 
        //CACHE AS BITMAP
 
        txtCopyright.cacheAsBitmap=true;
 
        //Slide the TextField
 
        slideCopyright();
 
    } else if (slideIn == false) {
             
        //Place the TextField without sliding
             
        placeCopyright();
    } //Closes the else if clause
} //Closes positionTheCopyright

Мы написали функцию, но еще не вызвали ее. Ну, мы должны:

1
2
3
//CALL THE FUNCTION
 
positionTheCopyright();

Теперь, после того как мы повторно сохраним файл .as и повторно опубликуем файл .swf, мы сможем проверить фильм, изменив значения в XML. Давайте посмотрим на некоторые из возможных результатов. (Щелкните в любом месте изображения, чтобы воспроизвести анимацию.)

Относительно сцены, сдвиньте вправо.

Относительно мувиклипа, сдвиньте вправо.

Относительно мувиклипа, сдвиньте влево.

Теперь давайте проверим функция изменения размера: в следующем примере полного экрана, leftOrRight значение в XML устанавливается на правой , а relativeTo значение в XML устанавливается на этапе . Измените размер окна браузера несколько раз, чтобы увидеть, как уведомление об авторских правах корректирует свою позицию в соответствии с новым размером окна.

Посмотреть демо-версию .


Эффект постепенного появления основан, в основном, на тех же приемах, что и запрограммированный нами эффект скольжения: он использует объект Timer для отправки обычных событий, прослушиватель событий для прослушивания этих событий и вызова обработчика всякий раз, когда отправляется событие Timer. , Одно из отличий состоит в том, что, поскольку в этом случае мы не вкладываем прослушиватель событий в другой прослушиватель событий, который прослушивает событие другого типа (как мы делали раньше), мы можем написать обработчик событий после прослушивателя событий. Поэтому мы можем остановить таймер после его запуска и удалить прослушиватель событий после того, как мы добавили его … и это большое облегчение.

Вот весь список обработчика событий / обработчика событий:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//Fade in the text field, if fadeIn in XML set to true
 
if (fadeIn==true) {
    txtCopyright.alpha=initialAlpha;
 
    //Create and start the fade-in timer
 
    fadeInTimer=new Timer(fadeInSpeed);
    fadeInTimer.start();
    fadeInTimer.addEventListener(TimerEvent.TIMER, fadeInText);
 
    //Fade in the text field
 
    function fadeInText(event:Event):void {
         
        txtCopyright.alpha+=fadeInSpeedIndex;
         
        //remove event listener after fade
         
        if (txtCopyright.alpha>=finalAlpha) {
            //optional
            fadeInTimer.stop();
            fadeInTimer.removeEventListener(TimerEvent.TIMER, fadeInText);
        }//closes if clause
 
    }//closes the fadeInText function
 
} else if (fadeIn == false) {
    txtCopyright.alpha=finalAlpha;
}// closes the else if clause

Я уверен, что вы можете легко понять, что происходит в этом коде, но я хотел бы отметить еще одну вещь. Приблизительная природа уравнений Flash снова доставляет нам немало хлопот, когда нам нужно остановить таймер и удалить прослушиватель событий в этой функции. Непрозрачность TextField может никогда не быть равна finalAlpha , но в этом случае мы не можем округлить текущее значение до ближайшего целого числа просто потому, что альфа в ActionScript 3.0 установлена ​​в десятичных числах. Конечно, мы могли бы умножить значение на сто и манипулировать результатом умножения, но вместо этого мы будем использовать более элегантное решение.

Сказав Flash добавить значение fadeInSpeedIndex к текущему альфа- каналу на каждом такте таймера, мы фактически инструктируем Flash для превышения значения finalAlpha в какой-то момент, и как только это происходит, таймер получает команду на останов и прослушиватель событий. удален. Таким образом, мы можем заставить таймер останавливаться, а прослушиватель событий самостоятельно удалять, используя оператор> = вместо оператора ==. Этот фрагмент кода заботится об этом:

1
2
3
4
5
6
                     
if (txtCopyright.alpha>=finalAlpha) {
    //optional
    fadeInTimer.stop();
    fadeInTimer.removeEventListener(TimerEvent.TIMER, fadeInText);
}

Давайте теперь протестируем эффект постепенного изменения, внеся соответствующие изменения в файл XML, сохранив все файлы и повторно опубликовав файл .swf. (Щелкните в любом месте изображения, чтобы воспроизвести анимацию.)

Относительно сцены, статический слева, исчезать в

Теперь давайте на секунду задержим дыхание и восхитимся результатом нашей работы. Посмотрите на свой файл AS. Это огромная!


В созданном нами классе уведомления об авторском праве нет ничего особенного и ничего особенно продвинутого, но при его создании мы многое изучили и познакомились с набором разнообразных методов программирования. Я надеюсь, что вы найдете некоторые из них полезными в вашей повседневной работе. Я призываю вас немного поиграть со значениями в XML-файле и убедиться, как все работает. Вы также можете проверить останов таймеров и удаление обработчиков событий, вызвав глобальную функцию trace () прямо над операторами, которые сообщают Flash об удалении слушателей и останове таймеров, например, так:

01
02
03
04
05
06
07
08
09
10
//Stop the timer and remove event listener
 
            if (Math.round(txtCopyright.x)==xFinal) {
                //optional
 
                trace("The timer is stopped and the event listener is removed.");
 
                slideInTimer.stop();
                slideInTimer.removeEventListener(TimerEvent.TIMER, slideCopyright);
            }

Если вы протестируете код таким образом, вы увидите, что все наши обработчики событий удаляются, когда анимация заканчивается, и наши таймеры перестают тикать, когда им говорят.

Если по какой-либо причине вам нужно использовать материал, описанный в этом руководстве, в качестве основы для класса, реализованного как класс без документов, вам придется внести несколько изменений в код в файле ActionScript. Эти изменения выходят за рамки данного руководства, но вы найдете несколько дополнительных строк кода в загружаемой версии нашего класса Copyright. Дополнительные строки закомментированы, и вам нужно будет раскомментировать их, чтобы класс работал как класс без документов.

Спасибо, что прочитали этот урок и проработали его до конца.