Загрузите внешний SWF-файл, назначьте событие MOUSE_DOWN и не нажимайте на пустое место / подэтап. - PullRequest
0 голосов
/ 24 марта 2011

Я занимаюсь Flash уже более 15 лет, и недавно начал разрабатывать игры на Flash Actionscript 3. У меня возникли некоторые трудности, и мне нужна помощь. Я потратил несколько дней, пытаясь найти решение, но безуспешно.

У меня есть основной SWF, который загружает анимации sub SWF. Один объект может иметь 5 различных анимаций / SWF-файлов, связанных с ним. Допустим, у меня есть курица, chicken01.swf, chicken02.swf, ...

Я назначаю событие MOUSE_DOWN первому загруженному SWF-файлу, затем, основываясь на инструменте, используемом при нажатии на объект, оно загружает другие анимации. Моя проблема в том, что у каждого SWF есть свободное место вокруг, которое становится кликабельным. Мне нужен только кликабельный объект, а не пустое пространство, потому что некоторые объекты могут перекрывать друг друга, что затрудняет щелчок по объекту позади другого объекта.

Sub SWFs / анимации находятся на одной временной шкале, и я поиграл с Bitmap Tracing, чтобы удалить пустое пространство вокруг импортированных объектов PNG. Это сработает, если я уменьшу размер рабочей области до объекта, но затем испорчу размер загруженного SWF-файла из-за того, что размер рабочей области меньше объекта. Поэтому, когда я назначаю объекту ширину и высоту с меньшей сценой, объект становится огромным. Если я ограничу размер рабочей области размером объекта, даже если это растровое растровое изображение, сцена будет активна. Я попытался назначить событие MOUSE_DOWN для объекта на вспомогательном SWF-файле из основного SWF-файла, но это приводит к ошибкам.

Моя цель - загрузить вспомогательный SWF-файл, назначить событие MOUSE_DOWN, и только объект должен быть активным, а не сцена или пустое пространство вокруг объекта.

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

Ниже приведен код, который я использую.

var loadimage = foreground_list[i].imagelocation + foreground_list[i].image;

var loader:SWFLoader = new SWFLoader(loadimage,{container:tn_mc,x:current_tn_x,y:current_tn_y,name:current_name,alpha:1,width:current_tn_w,height:current_tn_h,rotation:0});

loader.load();
tn_mc.buttonMode = true;

tn_mc.addEventListener( MouseEvent.MOUSE_DOWN, tn_down );
tn_mc.addEventListener( MouseEvent.MOUSE_UP, tn_up );

addChild( tn_mc );


function tn_down(e:MouseEvent):void
{
    switch (MovieClip(this.root).PointerTool)
    {
        case "move" :

            stage.addEventListener(MouseEvent.MOUSE_UP, stage_up );

            e.target.startDrag();
            break;
        case "play" :

            var loader4:SWFLoader = new SWFLoader(foreground_list.imagelocation + foreground_list.playimage,{container:tn_mc,name:e.target.name,x:foreground_list.setx,y:foreground_list.sety,width:foreground_list.setw,height:foreground_list.seth,rotation:0});
            tn_mc.removeChildAt(0);
            tn_mc.addEventListener( MouseEvent.MOUSE_DOWN, tn_down );
            tn_mc.addEventListener( MouseEvent.MOUSE_UP, tn_up );

            loader4.load();
            loader4.addEventListener(Event.COMPLETE, completeactionHandler);
            break;

        default :
            //Some other animation
            break;
    }
}

1 Ответ

1 голос
/ 24 марта 2011

Создайте мувиклип - векторную фигуру внутри каждого SWF, которая совпадает с вашей кликабельной областью. Установите альфа в 0% на цвет заливки вектора. Дайте ему и имени экземпляра что-то вроде activeArea , и назначьте этому слушателю событий вместо moveiclip внешней оболочки.

Другой подход, который может сработать, - это использование hitTestObject () для события MOUSE_DOWN , которое позволит вам игнорировать прозрачность.

EDIT

Трудно точно сказать, что вы пытаетесь сделать, не видя этого. Я на самом деле не компилировал это, поэтому я не уверен, будет ли это работать так, как есть, но в теории это должно быть близко. Это немного другой подход, чем вы используете. Я использовал Loader () вместо SWFLoader и немного прояснил идею. В качестве примечания следует избегать использования root в as3.

var _swfLoader:Loader;

var loadimage = foreground_list[i].imagelocation + foreground_list[i].image;

var loader:SWFLoader = new SWFLoader(loadimage,{container:tn_mc,x:current_tn_x,y:current_tn_y,name:current_name,alpha:1,width:current_tn_w,height:current_tn_h,rotation:0});

loader.load();
tn_mc.buttonMode = true;

tn_mc.addEventListener( MouseEvent.MOUSE_DOWN, tn_down );

addChild( tn_mc );

function tn_down(e:MouseEvent):void
{
    tn_mc.addEventListener( MouseEvent.MOUSE_UP, tn_up );

    switch (MovieClip(this.root).PointerTool)
    {
        case "move" :

            stage.addEventListener(MouseEvent.MOUSE_UP, stage_up );
            e.target.startDrag();

        break;

        case "play" :

            _swfLoader = new Loader();
            var req:URLRequest = new URLRequest(foreground_list.imagelocation + foreground_list.playimage);
            _swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, animationLoaded);

            _swfLoader.load(req);

        break;

        default :

            //Some other animation

        break;
    }
}

function tn_up(e:MouseEvent):void
{
    tn_mc.removeEventListener( MouseEvent.MOUSE_UP, tn_up );
}

function animationLoaded(evt:Event):void
{
    _swfLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, animationLoaded);

    tn_mc.removeChildAt(0);

    var loadedSwf = evt.target.content;
    loadedSwf.x = foreground_list.setx;
    loadedSwf.y = foreground_list.sety;
    loadedSwf.width = foreground_list.setw;
    loadedSwf.height = foreground_list.seth;
    loadedSwf.rotation = 0;

    loadedSwf.addEventListener(MouseEvent.MOUSE_DOWN, onAnimationStart);

    // might wanna add theses to an array to keep track of them and run clean up later on

    // now add to some display list
}

function onAnimationStart(evt:MouseEvent):void
{
    loadedSwf.addEventListener(MouseEvent.MOUSE_UP, onAnimationStop);

    // play your animation or whatever else
    evt.target.play();
}

function onAnimationStop(evt:MouseEvent):void
{
    loadedSwf.removeEventListener(MouseEvent.MOUSE_UP, onAnimationStop);

    // stop your animation or whatever else
    evt.target.stop();
}
...