0

私は Flash で 15 年以上開発を続けており、最近 Flash Actionscript 3 でゲームの開発を始めました。いくつかの問題があり、助けが必要です。解決策を見つけるために何日も費やしましたが、運がありませんでした。

サブ SWF アニメーションをロードするメイン SWF があります。1 つのオブジェクトに 5 つの異なるアニメーション / SWF を関連付けることができます。たとえば、ニワトリがいて、chicken01.swf、chicken02.swf、...

最初に読み込まれた SWF に MOUSE_DOWN イベントを割り当てます。次に、オブジェクトをクリックしたときに使用されたツールに基づいて、他のアニメーションが読み込まれます。私の問題は、各 SWF の周りに空白があり、クリック可能になることです。クリック可能なオブジェクトのみが必要で、空のスペースは必要ありません。これは、一部のオブジェクトが互いに重なり合う可能性があり、別のオブジェクトの背後にあるオブジェクトをクリックするのが難しくなるためです。

サブ SWF / アニメーションは 1 つのタイムライン上にあり、インポートされた PNG オブジェクトの周りの空きスペースを削除するためにビットマップ トレースを使用しました。これは、ステージのサイズをオブジェクトの後ろに縮小した場合に機能しますが、ステージのサイズがオブジェクトよりも小さいため、ロードされた SWF のサイズが大きくなります。そのため、オブジェクトに幅と高さを割り当てると、小さいステージでオブジェクトが巨大になります。ステージ サイズをオブジェクトのサイズに制限すると、トレースされたビットマップ イメージであっても、ステージはクリック可能になります。メイン SWF からサブ SWF 上のオブジェクトに MOUSE_DOWN イベントを割り当てようとしましたが、エラーが発生します。

私の目標は、サブ 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;
    }
}
4

1 に答える 1

1

ムービークリップを作成します。これは、クリック可能な領域と同じ形状である、各 swf 内のベクトル形状です。ベクトルの塗りつぶし色のアルファを 0% に設定します。それに activeAreaのようなインスタンス名を付けて、外側のシェルの moveiclip の代わりにイベント リスナーをそれに割り当てます。

もう 1 つの方法として、MOUSE_DOWNイベントでhitTestObject()を使用する方法があります。これにより、透過性を無視することを選択できます。

編集

自分が何をしようとしているのか、それを見ずに正確に伝えるのは難しい。私は実際にこれをコンパイルしていないので、これがそのまま機能するかどうかはわかりませんが、理論的には近いはずです。使用しているアプローチとは少し異なります。SWFLoader の代わりに Loader() を使用し、アイデアを少し整理しました。補足として、 as3 ではrootの使用を避ける必要があります。

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();
}
于 2011-03-24T18:07:29.817 に答える