Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Создание инфо-панели для MOUSE_OVER (http://www.flasher.ru/forum/showthread.php?t=203654)

Fogflasher 03.10.2013 11:16

Создание инфо-панели для MOUSE_OVER
 
Пробую создать инфо-панель, на которой бы выводилась информация об объекте, который в данный момент находится под курсором.

Документ-класс, Main.as:

Код AS3:

package
{
 
        import flash.display.*;
        import flash.events.*;
        import flash.text.*;
 
 
        public class Main extends Sprite
        {
 
                //--- Экземпляр класса инфо-панели ---//
                private var panel_placer:Panel_placer;
 
                //--- Произвольные объекты на экране ---//
                private var some_textfield:TextField;
                private var some_shape:Shape;
                private var shape_sprite:Sprite;
 
                public function Main()
                {
 
 
                        //--- Размещаем текстфилд ---//
                        some_textfield = new TextField();
                        some_textfield.text = "Move Cursor Here";
                        some_textfield.autoSize = TextFieldAutoSize.LEFT;
                        some_textfield.background = true, some_textfield.backgroundColor = 0xFF8800;
                        some_textfield.border = true, some_textfield.borderColor = 0xFF00BB;
                        some_textfield.x = 100, some_textfield.y = 100;
                        addChild(some_textfield);
 
                        //--- Размещаем квадрат ---//
                        some_shape = new Shape();
                        shape_sprite = new Sprite();
                        shape_sprite.x = 300, shape_sprite.y = 100;
                        some_shape.graphics.lineStyle(1);
                        some_shape.graphics.beginFill(0x00CCFF, 1);
                        some_shape.graphics.drawRect(0, 0, 75, 50);
                        shape_sprite.addChild(some_shape);
                        addChild(shape_sprite);
 
                        //--- Размещаем экземпляр дополнительного класса ---//
                        panel_placer = new Panel_placer();
                        addChild(panel_placer);
 
                        //--- Вешаем слушатель на стэйдж ---//
                        stage.addEventListener(MouseEvent.MOUSE_OVER, showInfo);
 
 
                }
 
                private function showInfo(e:MouseEvent)
                {
 
 
//                        panel_placer.info_panel.info_texter.text = String(e.Target);  //  ОШИБКА !
 
 
 
                        trace("e.Target = ", e.target);
 
                }
 
 
        }
 
 
 
}

И дополнительный класс, Panel_placer.as.
Который использует, созданный посредством галочки Export to ActionScript, библиотечный символ класса Info_panel.
В этом символе есть динамический текст-филд, с именем инстанции: info_texter, не содержащий никакого текста.

Код AS3:

package
{
        import flash.display.Sprite;
        import flash.events.*;
        import flash.text.*;
 
        public class Panel_placer extends Sprite
        {
 
                private var info_panel:Info_panel;
 
                public function Panel_placer()
                {
 
                        info_panel = new Info_panel();
                        info_panel.x = 57;
                        info_panel.y = 379;
 
                        addChild(info_panel);
 
 
                }
 
 
        }
 
}


И вот я хочу, чтобы информация с события e.target была передана этому текстфилду info_texter.
И тогда он будет отображать имя объекта, на который указывает мышь.

Пробую в основном классе сделать это посредством строки:

Код AS3:

panel_placer.info_panel.info_texter.text = String(e.Target);

Однако, она выдает ошибку:
Цитата:

1178: Attempted access of inaccessible property info_panel through a reference with static type Panel_placer. panel_placer.info_panel.info_texter.text = String(e.currentTarget);
Хотя трэйс работает нормально.

Как же тогда передать инфу в эту панель?

KumoKairo 03.10.2013 11:28

У вас тут две ошибки сразу на самом деле.
Первая - вы пытаетесь получить доступ к приватном полю info_panel (кстати помните, что названия приватных полей лучше начинать писать с подчеркивания, а само имя CamelCase - _infoPanel?). Надо либо модификатор доступа на public, либо сделать геттер:
Код AS3:

package
{
        import flash.display.Sprite;
        import flash.events.*;
        import flash.text.*;
 
        public class Panel_placer extends Sprite
        {
        ...
                public var info_panel:Info_panel;
        ...
        }
}

Либо
Код AS3:

package
{
        import flash.display.Sprite;
        import flash.events.*;
        import flash.text.*;
 
        public class Panel_placer extends Sprite
        {
        ...
                private var _infoPanel:Info_panel;
 
                public function get infoPanel():Info_panel
                {
 
                }
        ...
        }
}

А потом, где вы приводите e.target к String, вы пытаетесь объект привести к строке. Тоже будет вылетать с ошибкой.

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

Fogflasher 03.10.2013 11:44

Вложений: 1
KumoKairo, спасибо за наводку, исправил private на public, и ошибка исчезла.
С геттерами пока не хочу связываться, ибо сие езмь нечто чужеродное унд богомерзкое : )
С камелкейз и подчеркиваниями ок, щас исправлю.

По поводу превращения объекта в String, кстати, проблем нет.
Вроде всё нормально работает, вот смотрите:

Main.swf   (3.5 Кб)


Хотя, подозреваю, что если просто Shape разместить, без засовывания его в Sprite, то он наверное не будет в инфопанели виден.

KumoKairo 03.10.2013 11:47

Цитата:

По поводу превращения объекта в String, кстати, проблем нет.
Вроде всё нормально работает, вот смотрите:
А, да, ошибся немного

Но в любом случае не то что надо) Вам же конкретный текст нужен а не тип объекта?

Fogflasher 03.10.2013 11:56

KumoKairo, кстати да.
Но дело в том, что ведь у некоторых объектов не будет текста. У спрайта же нет текста.

В идеале бы вообще иметь сообщения, навроде: "Текстовое поле", "Рамка экрана" (еще не реализована), "Инфо-панель", "Форма"(еще не реализована), "Пустота" (это если навести курсор в любое незанятное место).

Но как это сделать? Наверное нужно некий внутренний switch-case написать, где перепрописывать.

Вот только я не понимаю, почему когда я навожу мышку в пустоту - в инфопанели ничего не появляется?
Ведь там должно быть например Stage, или имя экземпляра класса Main

KumoKairo 03.10.2013 12:12

Вложений: 1
Цитата:

Но дело в том, что ведь у некоторых объектов не будет текста. У спрайта же нет текста.
Поэтому и говорю:
Цитата:

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

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

Вам нужно сделать свой Sprite, в котором будет свойство .containedText, затем проверять, кто именно поймал событие, и если это наш Sprite с текстом - выводить в текстовое поле этот текст, а если любой другой объект - выводить сообщение "Это неправильный объект. И он делает неправильный текст":
Код AS3:

//Наш класс объекта с текстом
package
{
        import flash.display.Sprite;
 
        public class MyLittleSpriteWithText extends Sprite
        {
                public var containedText:String;
 
                public function MyLittleSpriteWithText(textToContain:String)
                {
                        containedText = textToContain;
                }
        }
}

Код в Main (канву с вашего оригинала скопировал):
Код AS3:

        public class Main extends Sprite
        {
                ...
                public function Main()
                {
                        var myTextedSprite1:MyLittleSpriteWithText = new MyLittleSpriteWithText("ПИСЯ");
                        addChild(myTextedSprite1);
 
                        //--- Вешаем слушатель на стэйдж ---//
                        stage.addEventListener(MouseEvent.MOUSE_OVER, showInfo);
                }
 
                private function showInfo(e:MouseEvent)
                {
                        var currentTarget:MyLittleSpriteWithText = e.target as MyLittleSpriteWithText;
                        if(currentTarget)
                        {
                                trace(currentTarget.containedText);
                        }
                        else
                        {
                                trace("Это неправильный объект. И он делает неправильный текст");
                        }
                }
        }

Приведение (Вложение 30052) с помощью оператора as позволит избавиться от рантайм ошибок приведения, но придется проверять конечную переменную на null. При неуспешном приведении переменной currentTarget присвоится null и условие if(currentTarget) не выполнится

Fogflasher 03.10.2013 12:44

Цитата:

Если на месте курсора нет ребенка - некому ловить событие.
А разве экземпляр класса Main не может ловить события?
Правда не совсем понятно, как на него слушатель повесить, может быть
Код AS3:

this.AddEventListener(MouseEvent.MOUSE_OVER, showInfo)

Цитата:

Вам нужно сделать свой Sprite, в котором будет свойство .containedText
Цитата:

Приведение с помощью оператора as позволит избавиться от рантайм ошибок приведения, но придется проверять конечную переменную на null. При неуспешном приведении переменной currentTarget присвоится null и условие if(currentTarget) не выполнится
Ок, вроде понял идею, щас попробую воплотить.

Но мне, кстати, не нужно кого-то одного определять.
Идея панели в том, чтобы она выдавала инфу по любому объекту, на который наводится мышь, не важно что это вообще. Поэтому свойство containedText по идее должно содержать не одно значение, а наверное некий набор, равный количеству объектов на экране.

AlexCooper 03.10.2013 12:51

Я бы реализовал для объектов, которым нужно выводить справку, интерфейс IHint. Соответственно был бы геттер description, а в MOUSE_OVER проверял
Код AS3:

if (e.target is IHint) trace( (e.target as IHint).description );

Добавлено через 5 минут
Код AS3:

package  {
 
        public interface IHint {
 
                // Interface methods:
                function get description ():String;
        }
 
}

Код AS3:

package  {
 
        import flash.display.MovieClip;
 
 
        public class Bober extends MovieClip  implements IHint {
 
                public function get description():String {
                        return 'Это бобёр';
                }
 
                public function Bober() {
                        // constructor code
                }
        }
 
}


KumoKairo 03.10.2013 13:05

Цитата:

А разве экземпляр класса Main не может ловить события?
Экземпляр класса Main является контейнером. Контейнер сам по себе мышиные события ловить не будет.
Это так же как купить холодильник и удивляться, почему в нем нет еды.

Akopalipsis 03.10.2013 14:12

KumoKairo эта тема точь в точь мои вчерашние слова. Вот если бы ТС хотел не по наведению, а по клику получать текст, как тогда, вешать на все обьекты слушателей down?

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

Добавлено через 12 минут
А то у мня у самого чувство, что я придираюсь...


Часовой пояс GMT +4, время: 19:51.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.