Статьи

Создайте изменяемую подсказку AS3 с ООП

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


Давайте сначала кратко рассмотрим нашу подсказку в действии:


Давайте начнем с создания новой папки под названием «Подсказка». В папке ToolTip создайте FLA-код ActionScript 3.0.


Теперь создайте округленный квадрат размером 150×77 пикселей со следующими свойствами:

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

Нарисуйте картинку (17x17px), похожую на рисунок ниже:

Выберите второй рисунок, нажмите клавишу F8 и примените конфигурацию ниже:

Сохраните файл FLA.


FlashDevelop — это редактор ActionScript со многими ресурсами. Вы можете загрузить FlashDevelop по адресу http://www.flashdevelop.org/community/viewforum.php?f=11 .

Документацию по FlashDevelop можно найти по адресу: http://www.flashdevelop.org/wikidocs/index.php?title=Main_Page

Откройте FlashDevelop, затем выберите: « Проект»> «Новый проект» , чтобы создать новый проект.

В диалоговом окне установите параметры, как на следующем изображении.


Сначала выберите вкладку «Проект» (если вкладка «Проект» не отображается, выберите «Вид»> «Менеджер проекта»).

На этой вкладке вы можете увидеть все файлы и папки проекта. Щелкните правой кнопкой мыши папку ToolTip, затем выберите: Add> New Folder и создайте папку с именем tooltip (в нижнем регистре).

Теперь щелкните правой кнопкой мыши папку подсказки и выберите: «Добавить»> «Новая папка» и создайте папку с именем display . Щелкните правой кнопкой мыши папку отображения и выберите: «Добавить»> «Новый класс».

В диалоговом окне вставьте ToolTip качестве имени класса и найдите flash.display.Sprite в поле Базовый класс .

Теперь наш проект имеет следующую структуру:

И это наш класс ToolTip (генерируется автоматически):

01
02
03
04
05
06
07
08
09
10
11
12
package tooltip.display
{
    import flash.display.Sprite;
     
    public class ToolTip extends Sprite
    {
        public function ToolTip()
        {
             
        }
    }
}

Пакет утилит поможет нам в функциях, связанных с Bitmap, Sprite и TextField. Идея состоит в том, чтобы следовать методикам ООП , делая этот пакет многоразовым.

Итак, давайте создадим пакет утилит. Щелкните правой кнопкой мыши папку всплывающей подсказки, затем выберите: «Добавить»> «Новая папка» и создайте папку с именем utils .

Создайте класс BitmapUtils внутри этой папки:

01
02
03
04
05
06
07
08
09
10
package tooltip.utils
{
    public final class BitmapUtils
    {
        public function BitmapUtils()
        {
            throw new Error(«BitmapUtils must not be instantiated»);
        }
    }
}

Создайте тоже класс SpriteUtils :

01
02
03
04
05
06
07
08
09
10
package tooltip.utils
{
    public final class SpriteUtils
    {
        public function SpriteUtils()
        {
            throw new Error(«SpriteUtils must not be instantiated»);
        }
    }
}

Наконец, создайте класс TextFieldUtils :

01
02
03
04
05
06
07
08
09
10
package tooltip.utils
{
    public final class TextFieldUtils
    {
        public function TextFieldUtils()
        {
            throw new Error(«TextFieldUtils must not be instantiated»);
        }
    }
}

У BitmapUtils есть один статический метод, который делает снимок экземпляра IBitmapDrawable .

Вот код:

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
package tooltip.utils
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.IBitmapDrawable;
    import flash.display.PixelSnapping;
    import flash.geom.Matrix;
     
    public final class BitmapUtils
    {
         
        public function BitmapUtils()
        {
            throw new Error(«BitmapUtils must not be instantiated»);
        }
        /**
         * Create a snapshot of an IBitmapDrawable instance
         * @param source IBitmapDrawable instance to be used as source
         * @param width Final width
         * @param height Final height
         * @param matrix Matrix instance to manipulate the part of source that will be drawed
         * @param smoothing Smooth the result
         * @param cacheAsBitmap Stores the bitmap in memory
         * @return The snapshot
         */
        public static function snapShot(source:IBitmapDrawable, width:int, height:int, matrix:Matrix = null, smoothing:Boolean = false, cacheAsBitmap:Boolean = false):Bitmap
        {
            var b:Bitmap;
            var bd:BitmapData = new BitmapData(width, height, true, 0x000000);
             
            bd.draw(source, matrix, null, null, null, smoothing);
     
            b = new Bitmap(bd, PixelSnapping.ALWAYS, smoothing);
            b.cacheAsBitmap = cacheAsBitmap;
            return b;
        }
    }
}

Этот класс добавляет Sprite в список отображения:

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
package tooltip.utils
{
    import flash.display.DisplayObjectContainer;
    import flash.display.Sprite;
     
    public final class SpriteUtils
    {
         
        public function SpriteUtils()
        {
            throw new Error(«SpriteUtils must not be instantiated»);
        }
        /**
         * Attach a Sprite instance into a DisplayObjectContainer instance
         * @param linkage The linkage of Sprite that will be attached
         * @param parent The parent of Sprite that will be attached
         * @return
         */
        public static function attachSprite(linkage:String, parent:DisplayObjectContainer):Sprite
        {
            var s:Object = parent.loaderInfo.applicationDomain.getDefinition(linkage);
            return parent.addChild(new s()) as Sprite;
        }
    }
}

Этот класс легко создает экземпляр TextField .

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

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
package tooltip.utils
{
    import flash.display.DisplayObjectContainer;
    import flash.text.AntiAliasType;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFieldType;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
     
    public final class TextFieldUtils
    {
         
        public function TextFieldUtils()
        {
            throw new Error(«TextFieldUtils must not be instantiated»);
        }
        /**
         * Create a textField instance
         * @param parent Parent of textField
         * @param text Text of textField (htmlText)
         * @param font Font name to be used in textField
         * @param embed
         * @param size
         * @param color
         * @param width
         * @param height
         * @param autoSize
         * @param multiline
         * @param wordWrap
         * @param cacheAsBitmap
         * @param align
         * @param leading
         * @param letterSpacing
         * @param type
         * @param selectable
         * @param sharpness
         * @param border
         * @return
         */
        public static function textField(parent:DisplayObjectContainer, text:String, font:*, embed:Boolean = true, size:Number = NaN, color:Number = 0xFFFFFF, width:Number = NaN, height:Number = NaN, autoSize:String = «none», multiline:Boolean = false, wordWrap:Boolean = false, cacheAsBitmap:Boolean = false, align:String = «left», leading:Number = NaN, letterSpacing:Number = NaN, type:String = «dynamic», selectable:Boolean = false, sharpness:Number = NaN, border:Boolean = false):TextField
        {
            var t:TextField = new TextField();
            var tf:TextFormat = new TextFormat();
             
            parent.addChild(t);
             
            tf.align = TextFormatAlign.LEFT;
            tf.font = font;
            if(size) tf.size = size;
            tf.color = color;
            tf.leading = leading;
            if (letterSpacing) tf.letterSpacing = letterSpacing;
                     
            switch(align.toLowerCase())
            {
                case «left»:
                    tf.align = TextFormatAlign.LEFT;
                break;
                case «center»:
                    tf.align = TextFormatAlign.CENTER;
                break;
                case «right»:
                    tf.align = TextFormatAlign.RIGHT;
                break;
                case «justify»:
                    tf.align = TextFormatAlign.JUSTIFY;
                break;
                default:
                    tf.align = TextFormatAlign.LEFT;
                break;
            }
             
            t.antiAliasType = AntiAliasType.ADVANCED;
            t.type = (type == «dynamic») ?
            t.defaultTextFormat = tf;
            t.embedFonts = embed;
            t.cacheAsBitmap = cacheAsBitmap;
            t.mouseEnabled = selectable;
            t.selectable = selectable;
            t.multiline = multiline;
            t.border = border;
            t.wordWrap = wordWrap;
            if (sharpness) t.sharpness = sharpness;
            t.htmlText = text;
            t.width = (width) ?
            t.height = (height) ?
             
            switch(autoSize.toLowerCase())
            {
                case «left»:
                    t.autoSize = TextFieldAutoSize.LEFT;
                break;
                case «center»:
                    t.autoSize = TextFieldAutoSize.CENTER;
                break;
                case «right»:
                    t.autoSize = TextFieldAutoSize.RIGHT;
                break;
            }
             
            return t;
        }
    }
}

Чтобы создать фон с изменяемым размером, мы будем использовать концепцию 9-фрагментного масштабирования , аналогичную 9-фрагментному масштабированию, встроенному во Flash. К сожалению, нативный 9-фрагмент в Flash не отвечает нашим потребностям.

Идея состоит в том, чтобы разделить источник (Sprite) на 9 частей (см. Изображение 🙂

Когда ширина фона изменяется, части 2, 5 и 8 растягиваются горизонтально, в то время как другие части остаются неизменными.

Аналогично, когда высота фона изменяется, части 4, 5 и 6 растягиваются вертикально, а остальные не меняются.


Класс Matrix создает карту точек для использования во многих формах. Для получения дополнительной информации, пожалуйста, прочитайте документацию класса Matrix с сайта Adobe.

Мы будем использовать класс Matrix для перевода источника фона и рисования частей. Фактически, класс Matrix не влияет на перемещение перевода в объекте автоматически, он только сохраняет значения, которые объект имел бы, если бы движение было перенесено. Это позволяет вам использовать экземпляр Matrix различными способами без привязки к DisplayObject.

Например, чтобы нарисовать второе изображение, мы должны принять во внимание положение (x = 0 y = 0) и размер (10 x 10px) изображения 1. Он будет применять перевод (без влияния на источник) и только после что рисовать вторую часть. Пример:

1
2
3
4
5
6
7
var source:Sprite = new Sprite();
 
var m:Matrix = new Matrix();
m.translate(-10, 0);
 
var bd:BitmapData = new BitmapData(source.width, source.height, true, 0x000000);
bd.draw(source, m);

Метод identity() можно использовать для сброса матрицы. Если мы не сбросим настройки, он выполнит новые вычисления на основе ранее сохраненных значений.


Чтобы создать класс CustomBg , создайте новый пакет с именем bg внутри пакета дисплея. Создайте новый класс внутри этой папки с именем CustomBg . Этот класс должен расширять Sprite .

Вот класс:

01
02
03
04
05
06
07
08
09
10
11
12
package tooltip.display.bg
{
    import flash.display.Sprite;
     
    public final class CustomBg extends Sprite
    {
        public function CustomBg()
        {
     
        }
    }
}

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

1
2
3
4
5
6
import flash.display.Bitmap;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.utils.getDefinitionByName;
import tooltip.utils.BitmapUtils;

Теперь создайте два свойства:

1
2
private var _parts:Vector.<Bitmap>;
private var _boundaries:int;

Конструктор должен содержать следующие параметры:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
/**
 * Create a resizable Background
 * @param linkage Linkage of a Sprite to be drawed
 * @param parent Parent of Background
 * @param width Initial width
 * @param height Initial height
 * @param boundaries Boundaries to slice the image
 * @param smoothing Smooth the Background
 * @param cacheAsBitmap Stores the Background in memory
 */
public function CustomBg(linkage:String, parent:DisplayObjectContainer, width:Number = NaN, height:Number = NaN, boundaries:int = 10, smoothing:Boolean = true, cacheAsBitmap:Boolean = false)
{
 
}

В конструкторе мы нарежем изображение.

Сначала мы объявляем переменные. С помощью переменных «Instance» и «source» мы присоединяем наш фон (Sprite) к классу CustomBg . В переменной «parts» мы храним нарисованные части фона. Наконец, с помощью переменной «m» мы получаем значения перевода и используем их для рисования частей нашего CustomBg .

Вот код:

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
var Instance:Class = getDefinitionByName(linkage) as Class;
var source:Sprite = new Instance() as Sprite;
var parts:Vector.<Bitmap> = new Vector.<Bitmap> ();
var m:Matrix = source.transform.matrix;
 
parts[0] = BitmapUtils.snapShot(source, boundaries, boundaries, null, smoothing);
 
m.translate( -boundaries, 0);
parts[1] = BitmapUtils.snapShot(source, source.width — boundaries * 2, boundaries, m, smoothing);
 
m.identity();
m.translate( -source.width + boundaries, 0);
parts[2] = BitmapUtils.snapShot(source, boundaries, boundaries, m, smoothing);
 
m.identity();
m.translate( 0, -boundaries);
parts[3] = BitmapUtils.snapShot(source, boundaries, source.height — boundaries * 2, m, smoothing);
 
m.identity();
m.translate( -boundaries, -boundaries);
parts[4] = BitmapUtils.snapShot(source, source.width — boundaries * 2, source.height — boundaries * 2, m, smoothing);
 
m.identity();
m.translate( -source.width + boundaries, -boundaries);
parts[5] = BitmapUtils.snapShot(source, boundaries, source.height — boundaries * 2, m, smoothing);
 
m.identity();
m.translate(0, -source.height + boundaries);
parts[6] = BitmapUtils.snapShot(source, boundaries, boundaries, m, smoothing);
 
m.identity();
m.translate(-boundaries, -source.height + boundaries);
parts[7] = BitmapUtils.snapShot(source, source.width — boundaries * 2, boundaries, m, smoothing);
 
m.identity();
m.translate(-source.width + boundaries, -source.height + boundaries);
parts[8] = BitmapUtils.snapShot(source, boundaries, boundaries, m, smoothing);
 
this.addChild(parts[0]);
this.addChild(parts[1]);
this.addChild(parts[2]);
this.addChild(parts[3]);
this.addChild(parts[4]);
this.addChild(parts[5]);
this.addChild(parts[6]);
this.addChild(parts[7]);
this.addChild(parts[8]);
 
this._parts = parts;
this._boundaries = boundaries;
 
this.width = (isNaN(width)) ?
this.height = (isNaN(height)) ?
 
parent.addChild(this);

Каждый раз, когда фон изменяется, положение частей должно быть обновлено. Давайте создадим arrange() , чтобы обновить положение всех частей фона:

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
private function arrange():void
{
    var parts:Vector.<Bitmap> = this._parts;
    var boundaries:int = this._boundaries;
     
    parts[0].x = 0;
    parts[0].y = 0;
     
    parts[1].x = boundaries;
    parts[1].y = 0;
     
    parts[2].x = parts[0].width + parts[1].width;
    parts[2].y = 0;
     
    parts[3].x = 0;
    parts[3].y = boundaries;
     
    parts[4].x = boundaries;
    parts[4].y = boundaries;
     
    parts[5].x = parts[3].width + parts[4].width;
    parts[5].y = boundaries;
     
    parts[6].x = 0;
    parts[6].y = parts[0].height + parts[3].height;
     
    parts[7].x = boundaries;
    parts[7].y = parts[6].y;
     
    parts[8].x = parts[6].width + parts[7].width;
    parts[8].y = parts[6].y;
}

Наконец, мы переопределяем методы width и height класса Sprite, чтобы изменить размеры и обновить позиции деталей:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
public override function set width(v:Number):void
{
    var parts:Vector.<Bitmap> = this._parts;
    var boundaries:int = this._boundaries;
     
    parts[1].width = v — boundaries * 2;
    parts[4].width = v — boundaries * 2;
    parts[7].width = v — boundaries * 2;
     
    this.arrange();
}
public override function set height(v:Number):void
{
    var parts:Vector.<Bitmap> = this._parts;
    var boundaries:int = this._boundaries;
     
    parts[3].height = v — boundaries * 2;
    parts[4].height = v — boundaries * 2;
    parts[5].height = v — boundaries * 2;
     
    this.arrange();
}

Теперь у нас есть фон изменяемого размера, который не претерпевает искажений при изменении размера. Смотрите превью:


Шаблоны проектирования — это методологии программирования, которые предлагают решения общих проблем в разработке программного обеспечения.

Мы создадим класс ToolTip под аспектами шаблона проектирования Singleton , который дает нам класс, имеющий всего один глобальный экземпляр во всем проекте. Подумайте: вы хотите использовать всплывающую подсказку в меню с несколькими кнопками. Было бы ненужным и непрактичным создавать экземпляр класса ToolTip для каждой кнопки меню, поскольку мы можем отображать только одну подсказку за раз. Наилучший подход в этом случае — создать глобальный экземпляр для всего проекта и использовать методы show() и hide() для управления отображением.

Шаблон проектирования Singleton предотвратит вызов конструктора класса; он создает экземпляр класса внутри себя и всегда возвращается через определенный метод. Обратите внимание на нашу реализацию Singleton:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
package tooltip.display
{
    import flash.display.Sprite;
     
    public class ToolTip extends Sprite
    {
     
        private static var _instance:ToolTip;
         
        public static function getInstance():ToolTip
        {
            if (!ToolTip._instance) ToolTip._instance = new ToolTip(new Singleton());
            return ToolTip._instance;
        }
         
        public function ToolTip(s:Singleton)
        {
         
        }
    }
}
internal class Singleton{}

В приведенном выше примере мы видим объявление статического экземпляра. Он всегда будет возвращен методом getInstance() .

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

Метод getInstance() проверяет, была ли объявлена ​​переменная; если он не был объявлен, метод getInstance() объявляет экземпляр и затем возвращает его. Если экземпляр уже объявлен, getInstance() просто возвращает экземпляр.

1
2
var toolTip:ToolTip = new ToolTip();//Error
var toolTip:ToolTip = ToolTip.getInstance();//Ok

TweenMax Джека Дойла — это анимационный движок, который часто упоминается в Activetuts +. Это позволяет легко создавать анимацию движения.

Библиотека TweenMax и ее документация могут быть найдены на GreenSock.com .

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

1
TweenMax.to(displayObjectInstance, duration, { property:value );

Теперь посмотрим на простое использование класса TweenMax:

Посмотрите пример кода, используемого для достижения этой цели:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
import com.greensock.TweenMax;
bt.label = «ROLL OVER TO ADD SHADOW»;
bt.addEventListener(MouseEvent.MOUSE_OVER, onOver);
bt.addEventListener(MouseEvent.MOUSE_OUT, onOut);
 
function onOver(e:MouseEvent):void
{
    bt.label = «ROLL OUT TO REMOVE SHADOW»;
    TweenMax.to(bt, 0.5, { dropShadowFilter: { color:0x000000, alpha:0.7, blurX:4, blurY:4, angle:45, distance:7 }} );
}
function onOut(e:MouseEvent):void
{
    bt.label = «ROLL OVER TO ADD SHADOW»;
    TweenMax.to(bt, 0.5, { dropShadowFilter: { color:0x000000, alpha:0, blurX:0, blurY:0, angle:0, distance:0 }} );
}

Мы добавим объекты на сцене с помощью наших ранее созданных классов и двух методов. Мы должны добавить прослушиватель для события Event.ADDED_TO_STAGE чтобы избежать нулевых ссылок на сцену.

Обновите конструктор и добавьте два метода ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public function ToolTip(s:Singleton)
{
    this.addEventListener(Event.ADDED_TO_STAGE, this.onAddedToStage);
}
 
private function onAddedToStage(e:Event):void
{
    this.removeEventListener(Event.ADDED_TO_STAGE, this.onAddedToStage);
     
    this.draw();
}
private function draw():void
{
    this.alpha = 0;
    this._bg = new CustomBg(«ToolTipBg», this);
    this._tail = SpriteUtils.attachSprite(«ToolTipTail», this);
    this._tipField = TextFieldUtils.textField(this, «», «Arial», false, 13, 0x000000);
     
    TweenMax.to(this, 0, { dropShadowFilter: { color:0x000000, alpha:0.7, blurX:4, blurY:4, angle:45, distance:7 }} );
     
    this.removeChild(this._bg);
    this.removeChild(this._tail);
    this.removeChild(this._tipField);
}

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

Чтобы узнать, в каком аспекте должна появляться подсказка, я разделил сцену на сетку из девяти квадратов (используя вычисления; я не использовал DisplayObjects). Всего шести квадратов было бы достаточно, но я создал девять квадратов, чтобы вы могли изменить поведение квадратов 3, 4 и 5. В этом случае счет начинается с нуля.

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

В onFrame() я проверяю, в каком квадрате находится курсор мыши, а затем onFrame() метод onFrame() arrange(style:int) , передавая в качестве параметра номер воображаемого квадрата, чтобы он onFrame() так, как я хочу , Я использовал однострочные операторы, потому что они быстрее.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
private function onFrame(e:Event):void
{
    var sW:Number = this.stage.stageWidth;
    var sH:Number = this.stage.stageHeight;
     
    var rW:Number = sW / 3;
    var rH:Number = sH / 3;
     
    var mX:Number = this.stage.mouseX;
    var mY:Number = this.stage.mouseY;
     
    if (mX < rW && mY < rH) this.arrange(0);
    else if (mX > rW && mX < rW * 2 && mY < rH) this.arrange(1);
    else if (mX > rW * 2 && mY < rH) this.arrange(2);
    else if (mX < rW && mY > rH && mY < rH * 2) this.arrange(3);
    else if (mX > rW && mX < rW * 2 && mY > rH && mY < rH * 2) this.arrange(4);
    else if (mX > rW * 2 && mY > rH && mY < rH * 2) this.arrange(5);
    else if (mX < rW && mY > rH * 2) this.arrange(6);
    else if (mX > rW && mX < rW * 2 && mY > rH * 2) this.arrange(7);
    else this.arrange(8);
}

arrange() обновляет все элементы ToolTip на основе значения, полученного в параметре.

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
private function arrange(style:int):void
{
    var b:CustomBg = this._bg;
    var t:Sprite = this._tail;
    var tF:TextField = this._tipField;
     
    t.scaleY = 1;
    tx = 0;
    ty = 0;
     
    tF.width = tF.textWidth + 5;
    tF.height = tF.textHeight + 5;
    tF.x = 0;
    tF.y = 0;
     
    b.width = tF.width + 10;
    b.height = tF.height + 10;
     
    bx = 0;
    by = 0;
     
    var mX:Number = this.stage.mouseX;
    var mY:Number = this.stage.mouseY;
     
    if (style == 0)
    {
        t.scaleY = -1;
        tx = mX;
        ty = mY + 40;
     
        bx = mX — 10;
        by = mY + t.height + b.height — 5;
    }
    else if (style == 1)
    {
        t.scaleY = -1;
        tx = mX;
        ty = mY + 40;
     
        bx = mX — b.width * 0.5 + t.width * 0.5;
        by = mY + t.height + b.height — 5;
    }
    else if(style == 2)
    {
        t.scaleY = -1;
        tx = mX;
        ty = mY + 40;
     
        bx = mX — b.width + t.width + 10;
        by = mY + t.height + b.height — 5;
    }
    else if(style == 3 || style == 6)
    {
        tx = mX;
        ty = mY — t.height;
         
        bx = tx — 10;
        by = ty — b.height + 2;
    }
    else if(style == 4 || style == 7)
    {
        tx = mX;
        ty = mY — t.height;
         
        bx = tx — b.width * 0.5 + t.width * 0.5;
        by = ty — b.height + 2;
    }
    else if(style == 5 || style == 8)
    {
        tx = mX;
        ty = mY — t.height;
         
        bx = tx — b.width + t.width + 10;
        by = ty — b.height + 2;
    }
                     
    tF.x = bx + 5;
    tF.y = by + 5;
}

Метод ниже не нуждается в большом объяснении; это говорит само за себя.

01
02
03
04
05
06
07
08
09
10
11
12
13
public function show(message:String):void
{
    this._tipField.htmlText = message;
    this.parent.setChildIndex(this, this.parent.numChildren — 1);
     
    this.addChild(this._bg);
    this.addChild(this._tail);
    this.addChild(this._tipField);
     
    TweenMax.to(this, 0.25, { alpha:1 } );
     
    this.addEventListener(Event.ENTER_FRAME, this.onFrame);
}

Я создал метод onCompleteHide() который будет выполняться после окончания инструкции TweenMax (это делается с помощью следующего оператора: onComplete: this.onCompleteHide ). Это удалит все элементы со сцены.

01
02
03
04
05
06
07
08
09
10
11
12
public function hide():void
{
    this.removeEventListener(Event.ENTER_FRAME, this.onFrame);
    TweenMax.to(this, 0.25, { alpha:0, onComplete:this.onCompleteHide } );
}
 
private function onCompleteHide():void
{
    this.removeChild(this._bg);
    this.removeChild(this._tail);
    this.removeChild(this._tipField);
}

Чтобы использовать нашу подсказку, я предлагаю вам добавить ее в объект DisplayObject, который находится на самом высоком уровне (например, DocumentClass). Сделав это, просто вызовите методы show() и hide() при необходимости. Вот два простых примера использования всплывающей подсказки:

1
2
3
var t:ToolTip = ToolTip.getInstance();
this.addChild(t);
t.show(«Some tip»);

В качестве альтернативы:

1
2
this.addChild(ToolTip.getInstance());
ToolTip.getInstance().show(«Some tip»);

Надеюсь, вам понравилось это; Я создал этот инструмент, используя лучшие методы объектно-ориентированного программирования с целью повышения скорости обработки, повторного использования классов и низкого потребления системы. Увидимся в следующем уроке! Благодарность!