2011-03-24 2 views
0

저는 15 년 넘게 Flash에서 현재 개발 중이며 최근에 Flash Actionscript 3에서 게임을 개발하기 시작했습니다. 도움이 필요해. 나는 행운이없는 해결책을 찾으려고 며칠을 보냈습니다.외부 SWF로드, MOUSE_DOWN 이벤트 할당 및 빈 공간/하위 스테이지 클릭 안 함

하위 SWF 애니메이션을로드하는 기본 SWF가 있습니다. 하나의 객체에는 5 개의 다른 애니메이션/SWF가 연관 될 수 있습니다. 그럼 닭고기 chicken01.swf, chicken02.swf가 있다고 가정 해 보겠습니다.

로드 된 SWF에 MOUSE_DOWN 이벤트를 할당 한 다음 개체를 클릭하는 동안 사용 된 도구를 기반으로 다른 애니메이션. 내 문제는 각 SWF에 클릭 할 수있는 빈 공간이 있다는 것입니다. 개체 중 일부는 서로 겹칠 수 있기 때문에 빈 개체가 아니라 클릭 할 수있는 개체 만 클릭하면됩니다. 그러면 다른 개체 뒤의 개체를 클릭하기가 어려워집니다.

하위 SWF/애니메이션은 단일 타임 라인에 있고 비트 맵 추적으로 재생하여 가져온 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; 
    } 
} 
+0

전체 SWF가 아닌로드 된 SWF 내부의 인스턴스를 대상으로 지정해야합니다. – goliatone

답변

1

movieclip - 클릭 할 수있는 영역과 동일한 모양 인 각 SWF 내부에 벡터 모양을 만듭니다. 벡터의 칠 색상에 알파를 0 %로 설정하십시오. activeArea과 같은 인스턴스 이름을 지정하고 외부 쉘 moveiclip 대신 이벤트 리스너를 할당하십시오. 작동 할 수

또 다른 접근 방식은 투명성을 무시하도록 선택할 수 있도록 해주는 MOUSE_DOWN 이벤트에 hitTestObject()를 사용하는 것입니다.

당신이 그것을 보지 않고 일을하려고 정확히 말해 하드 EDIT. 나는 이것이 실제로 컴파일되지 않았으므로 이것이 제대로 작동하는지 확신 할 수 없지만 이론적으로는 가까워 야합니다. 당신이 사용하는 것보다 약간 다른 접근법. SWFLoader 대신 Loader()를 사용하고 약간의 아이디어를 정리했습니다. 보조 노트로 루트을 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(); 
} 
+0

나는 양쪽 모두를 시험해보고 어느 것이 가장 효과가 있는지 봅니다. hitTestObject() 함수를 사용하는 방법에 대한 예제를 줄 수 있습니까? 이 MOUSE_DOWN 함수에 갈 것이라고? 신속한 답변에 감사드립니다. 따라서 오래된 AS2 일을 사용하고 작년 AS3 작업을 시작했습니다.나는 그것을 좋아하지만 AS2에서 매우 쉬운 것들은 AS3에서 빌드하는 데 더 많은 시간이 걸리는 것으로 보인다. –

+0

방금 ​​hittest에 대한 빠른 테스트를 했으므로 작동하지 않을 것이고 첫 번째 아이디어를 고수 할 것입니다. 하지만 질문에 대답하기 위해 hitTestPoint라는 두 가지 방법이 있습니다.이 방법은 객체와 포인트를 비교합니다. myMovieClip.hitTestPoint (stage.mouseX, stage.mouseY). 다른 하나는 hitTestObject입니다. 두 객체가 겹치고 있는지 비교합니다 : myMovieClip.hitTestObject (MyOtherMovieClip). 이 둘은 모두 투명도를 포함하여 무비 클립의 경계 영역을 포함할지 또는 보이는 픽셀에만주의 할지를 나타내는 선택적 제 3 부울 매개 변수를 갖습니다. – Ribs

+0

두 가지 방법을 모두 시도했지만 성공하지 못했습니다. 인스턴스 이름을 추가하는 다른 방법이없는 한 0 알파를 사용하여 벡터 외곽선을 작성했지만 인스턴스 이름을 적용하려면 기호로 변환해야했습니다. 난 그냥 주 SWF에서 클릭 이벤트를 적용하는 방법을 알아낼 수 없습니다. hitTest는 항상 클릭 할 때 거짓이 아닙니다. mouseX와 mouseY를 사용했지만 도움이되지 않습니다. 이러한 기능을위한 코드에 대한 아이디어. hitTest에 대한 연구를 해보고 행운이없는 몇 가지 예를 시도했습니다. –