I've been developing in Flash now for over 15 years, and recently started developing games in Flash Actionscript 3. I am having some difficulties, and need some help. I've spent days trying to find a solution, with no luck.
I have a main SWF, which loads sub SWF animations. One object can have 5 different animations / SWFs associated with it. So lets say I have a chicken, chicken01.swf, chicken02.swf, ...
I assign a MOUSE_DOWN event to the first loaded SWF, then based on the tool used while clicking on the object, it will load the other animations. My problem is that each SWF has empty space around it which becomes clickable. I only need the object clickable, and not the empty space, because some of the objects can overlap each other, which makes it hard to click on the object behind another object.
The Sub SWFs / animations are on a single timeline, and I played with Bitmap Tracing to remove the empty space around the imported PNG objects. This works if I reduce the Stage size to behind the Object, but then screws up the size of the loaded SWF due to the Stage size being smaller than the object. So when I assign a width and height to the object, with a smaller stage, the object is huge. If I constraint the stage size to the size of th开发者_如何学Goe object, even as a Traced bitmap image, the stage is still clickable. I tried to assign the MOUSE_DOWN event to the object on the sub SWF, from the Main SWF, but this gives errors.
My goal is to load a sub SWF, assign the MOUSE_DOWN event, and only have the object clickable, and not the Stage, or empty space around the object.
Is this possible? I also played around with creating an invisible button, but this makes it difficult to assign to 300 + objects of different shapes and sizes.
Below is some of the code I'm using.
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;
}
}
Create a movieclip - a vector shape inside each swf, that is the same shape as your clickable area. Set the alpha to 0% on the vector's fill color. Give it and instance name of something like activeArea, and assign your event listener to that instead of the outer shell moveiclip.
Another approach that might work is to use hitTestObject() on a MOUSE_DOWN event, which would allow you to choose to ignore the transparency.
EDIT
Hard to tell exactly what you are trying to do without seeing it. I didn't actually compile this so I'm not sure if this will work just the way it is, but in theory it should be close. Its a slightly different approach than you are using. I used Loader() instead of SWFLoader, and cleaned up the idea a little bit. As a side note, you should avoid the use of root in 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();
}
精彩评论