PDA

Просмотр полной версии : Переопределение свойства visible в MovieClip


dark256
07.06.2012, 12:30
В одном большом, большом, старом страшном монстроообразном проекте сложилась следующая ситуация:
элементы главного пользовательского интерфейса ( будем называть его HUD) стали мешать низлежащему объекту под названием ПОЛЯНА. Условно говоря, если ставишь на Поляну "домик", а он в момент отпускания клавиши мышки находится над эл-том HUD с visible=false , то МВЦ игры считает, что домик ставится НЕ на поляну, а на этот невидимый элемент.

Соответственно, могучим коллективом программистов на посвященном этой проблеме брифинге, плавно перешедшим в фуршет, было принято волевое решение изменять видимость элементов HUD посредством
HUD.removeChild(Clip) и HUD.addChild(Clip).

В результате родился следующий код:
private var itemActionsPanel : MovieClip;
private var _itemActionsVisible : Boolean;

override protected function init():void {
itemActionsPanel = graphics.topPanel.itemActions;
}

private function set itemActionsVisible(value : Boolean) : void {
_itemActionsVisible=value;
if(!itemActionsPanel){
return;
}
if(!_itemActionsVisible){
if(itemActionsPanel.parent){
itemActionsPanel.parent.removeChild(itemActionsPanel);
}
}else{
graphics.topPanel.addChild(itemActionsPanel);
}
}
private function get itemActionsVisible() : Boolean {
return _itemActionsVisible;
}
Как легко можно заметить, далее по коду мы пишем уже
не graphics.topPanel.itemActions.visible = false,
а itemActionsVisible=false

Легко, удобно, просто, красиво, элегантно.

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

Я и решил обратиться к великому могучему ООП, с целью переопределить акцессоры MovieClip.
В результате долгого плодотворного общения с коллегами, наряду с выслушиванием кучи матюгов рекомендаций по ООП и АС3 был сотворен следующий класс:
package Utils
{
import flash.display.DisplayObjectContainer;
import flash.display.MovieClip;

public class Revisible extends MovieClip
{
protected var _parent : DisplayObjectContainer;
protected var _clip:MovieClip;

public function Revisible(){
trace("Revisible Class Start", this, this.parent);
super();
_clip = this;
_parent = this.parent;
}

override public function get visible () : Boolean{
return super.visible;
}

override public function set visible (value:Boolean) : void{
if ( value ){
_parent.addChild( _clip ); // SHOW
} else {
_parent.removeChild( _clip ); // HIDE
}
super.visible = value;
}
}
}

Полная нативная оригинальная версия тут: http://pastebin.com/BwZvY1aA

Красиво, удобно, вообще все гут. За исключением мелких неточностей ( он так и не запустился, отладить не удалось пока ).
В чем возникла проблема.

В HUD лежит мувиклип прогресс-бара, для которого я хочу сделать САБЖ.
После загрузки и инициализации в классе HUD dызов конструктора:
bonusProgressBar = new BonusProgressBar( HUD.bonus_proigress);

Класс прогресс-бара, частично:

package GUI
{
import Utils.Revisible;

import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.MovieClip;

public class BonusProgressBar
{
private var _bar : MovieClip;
private var scene:DisplayObjectContainer;

public function BonusProgressBar(barDisplayObject : Revisible)
{
_bar = barDisplayObject;
}
}
}

По идее, barDisplayObject должен стать уже клипом с переопределнными акцессорами, и далее bonusProgressBar .visible = false должен работать как removeChild.

И тут, при вызове конструктора BonusProgressBar компилятор выдает ошибку о невозможности преобразования обьекта со стэйджа ( мувиклипа прогресс-бара ) к типу Revisible.

И тут моя мысль потерялась. Соотв вопрос к знатокам - что не так и какого ему еще надо?

Исходник прогресс-бара, вторнутого в HUD прилагается. Сорри, коллеги, это CS5.0

silin
07.06.2012, 13:18
не уверен, что однозначно понял трабл, но ты ожидаешь что наследник MovieClip (HUD.bonus_proigress) только за счет кастинга станет вдруг Revisible, с чего бы ?
поставь этому bonus_progress_bar в библиотеке базовым классом Revisible вместо MovieClip

Molecula
07.06.2012, 13:43
Да, кастинг такого волшебства не сделает.
Скорее всего будет как-то так:
new BonusProgressBar(this.getChildByName("HUD") as MovieClip);
...
private var _bar : Revisible;
private var scene:DisplayObjectContainer;

public function BonusProgressBar(barDisplayObject : MovieClip)
{
_bar = new Revisible(barDisplayObject);
}
...
public function Revisible(clip:MovieClip){
super();
trace("Revisible Class Start", this, this.parent);
//_clip = this;
_clip = clip;
_parent = this.parent;
}

Или так:
var pr:BonusProgressBar = new BonusProgressBar(new Revisible(this.getChildByName("HUD") as MovieClip));
private var _bar : Revisible;
private var scene:DisplayObjectContainer;

public function BonusProgressBar(barDisplayObject : Revisible)
{
_bar = barDisplayObject;
}

dark256
07.06.2012, 19:05
Спасибо за советы, меня тут дико работой завалили, проверю и отпишусь позжее :(