I am trying to determine in AS3 Flash if a draggable movieclip on the stage completely fills another movieclip also on the stage. I looked into another StackOverflow article with this code:
var inter = mcOverlay.getRect(this).intersection(mcLoadedImage.getRect(this));
if ((inter.width * inter.height) == 0) {
return false;
} else {
return true;
}
This code uses the intersect method, it works, but I also want to check that the movieclip is completely covered by the draggable movieclip on the stage.
Any suggestions? Thanks!
I think you could use compare each movieclips rect, ie compare the left, right, top and bottom values.
Instead of using intersection, use Rectangle.contains.
var contains : Boolean = mcContainer.getRect(this).contains(mcContained.getRect(this));
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Rectangle.html#containsRect()
Related
I have a Sprite type of variable:
var can: Sprite;
can= new Sprite();
addChild(can);
can.x = 5;
can.y = 5;
This Sprite is making a grid in my scene as shows below:
How it makes the grid?
I will pass it to a class named "Grid" to make the whole grid.
When I am going to go to another scene, I need to remove all child in current scene. So, I use the function:
function clearAllTut(): void {
//trace(numChildren);
while (numChildren > 0) {
removeChildAt(0);
}
}
when I will come back to this scene again, all the other child are demonstrated except "can".
The problem is with the removing function? (then why all the other child will be demonstrated again except "can")
or I need to change the method of programming for a Sprite type of variable?
i am using AS3 to create a function that will automatically play a movieclip all the way through and then remove it. my project is going to have a lot of animated cutscenes, so id like to be able to call this function, use the cutscene id like as a parameter, and then move on to the next. the problem is, im trying to use the function multiple times in a row to play clips sequentially, but they're all playing at the same time. is there a fix, or a better way to do this altogether?
playClip(new a_walk); //find a way to make these stop playing at the same time
playClip(new a_door);
//a_walk and a_door are the AS linkage class names for the movieclips im referring to
function playClip (clip:MovieClip):void {
addChildAt(clip, 0);
clip.mask = myMask;
clip.x=412.4;
clip.y=244.5;
clip.addEventListener(Event.ENTER_FRAME, checkframes);
function checkframes(event:Event) {
if (clip.currentFrame == clip.totalFrames) {
//trace("wow! youre an idiot!");
if (clip.parent) {
clip.parent.removeChild(clip);
trace (100);
return;
}
}
}
}
Sounds like you want a mechanism to play a queue of MovieClips? If so, here is a way you can accomplish this:
//create an array with the clips you want to play (in order), in my example here, the items can be a MovieClip derived Class, or a MovieClip instance
var playQueue:Array = [a_walk, a_door];
//create a var to store the currently playing clip
var currentClip:MovieClip;
playNext(); //call this when you want the queue of clips to start playing
function playNext():void {
//if there was an item previously playing (currentClip has a value), stop it and remove it/dispose of it
if(currentClip){
currentClip.stop(); //stop it from playing
currentClip.addFrameScript(currentClip.totalFrames-1, null); //remove the frame script that was added
currentClip.parent.removeChild(currentClip); //remove it from the display
currentClip = null;
}
//check if there's anything left to play
if(playQueue.length < 1) return;
var nextItem:* = playQueue.shift(); //shift retrieves and removes the first item in the array;
if(nextItem is Class){
//if it's a class, instantiate it
currentClip = new nextItem();
}else{
currentClip = MovieClip(nextItem);
}
//initialize the movie clip
addChildAt(currentClip, 0);
currentClip.gotoAndPlay(1);
//this is just what you were doing before:
currentClip.mask = myMask;
currentClip.x=412.4;
currentClip.y=244.5;
//add a command on the last frame of the movie clip to play the next item in the queue
currentClip.addFrameScript(currentClip.totalFrames-1, playNext);
//addFrameScript is 0 based, so 0 would refer to the first frame. This is why we subtract 1 to get the last frame
}
I should note, that addFrameScript is an undocumented function. It serves as a nice shortcut so you don't have to have an ENTER_FRAME listener checking currentFrame vs. totalFrames. Being undocumented however, one can not count on it's continued existence in future versions of the Flash/AIR runtimes (though it's been around for a long long time)
note
This answer is a work in progress. I'm waiting on a response from the OP.
// playClip(new a_door); don't call this yet, or they will just both play.
var clipData:CustomClass = new CustomClass(); // add an instance of a custom class to hold the value of the movie
//clip being played (so that you can use this value later in the event handler.)
// it will also hold a value of the next clip
clipData._currentClip = a_walk;
clipData._nextClip = a_door;
playClip(new a_walk);
function playClip (clip:MovieClip):void {
addChildAt(clip, 0);
clip.mask = myMask;
clip.x=412.4;
clip.y=244.5;
clip.addEventListener(Event.ENTER_FRAME, checkframes);
}
function checkframes(event:Event) {
if (clipData._currentClip.currentFrame == clipData._currentClip.totalFrames) {
//trace("wow! youre an idiot!");
if (clipData._currentClip.parent) {
playClip(clipData._nextClip);
clipData._currentClip.parent.removeChild(clipData._currentClip);
clipData._currentClip = clipData._nextClip; // moves the clips down
//clipData._nextClip = here we have
//a problem. Do these clips play in a set
//order, first to last? Or do the play out of
//order jumping back and forth? If so, how
//are you planning on controlling which clip
//plays next?
trace (100);
return;
}
}
}
I haven't checked this in Flash yet to see if it works, but I noticed that you are defining a function inside another function, which I don't think is good practice, so this might clean things up for you. Give it a try and let us know.
I'll try to fix my code above when I get a chance. In the meantime, you answered my question about playing the clips in order, so a simple solution would be to put all the clips in an array and then play them by playClip(clipArray[i]) and then when the clip ends and gets removed, do i++ and call the same function playClip(clipArray[i]) which will play the next clip in the array.
I have made a simple drag and match game for kids.
I used setchildindex for movie clips to be dragged but when I click next button and go to another frame but movie clips are remaining in the same stage. What should i do?
Here is my code I used: (drag_1, this.numChildren0);.
When I reload it's not working.
drag_1.buttonMode = true;
drag_1.addEventListener(MouseEvent.MOUSE_UP, dropMe_1);
drag_1.addEventListener(MouseEvent.MOUSE_DOWN, dragMe_1);
var back_1X:Number = back_1.x;
var back_1Y:Number = back_1.y;
var hit_2X:Number = hit_2.x;
var hit_2Y:Number = hit_2.y;
function dragMe_1(event:MouseEvent)
{
drag_1.startDrag()
setChildIndex(drag_1, this.numChildren-1);
}
function dropMe_1(event:MouseEvent)
{
drag_1.stopDrag();
if(drag_1.hitTestObject(drop_2))
{
TweenMax.to(drag_1, 0.5, {
x:hit_2X,
y:hit_2Y,
ease:Cubic.easeOut
});
drag_1.mouseEnabled = false;
SoundMixer.stopAll();
}
else
{
TweenMax.to(drag_1, 0.5,
{
x:back_1X,
y:back_1Y,
ease:Bounce.easeOut
});
}
}
You need to remove the MovieClips using removeChild().
Now, why do you need to do that here? Well, this is one of those odd problems you get when you mix the timeline with code. When you place a symbol on the timeline keyframe, the Flash Player will instantiate that symbol when it reaches that frame. After that, any frame on the timeline that updates the symbol (tweens, effects, etc) will do just that, and any frame that lacks the symbol will remove it. However, the Flash Player is very picky about identifying that symbol on each frame of the timeline. When you move it using setChildIndex you are basically breaking the timeline link, and the Flash Player no longer identifies it and removes it based on the keyframes. You'll also find that if you revisit a keyframe that had that symbol, the Flash Player will instantiate a second one regardless if the one you moved is still there. As you can see, it can get pretty messy.
On my stage I have several DisplayObjects. To some of them I have applied a MouseOver functions.
These functions are primarily like this:
this.addEventListener(MouseEvent.MOUSE_OVER, hoverHandler);
private function hoverHandler(evt:MouseEvent):void
{
this.alpha = 2 * this.alpha;
this.addEventListener(MouseEvent.MOUSE_OUT, awayHandler);
}
private function awayHandler(evt:MouseEvent):void
{
this.alpha = this.alpha / 2;
}
This works fine until some of my moving sprites suddenly also is above one of the sprites I have applied Mouseover functions to. Then my MouseOver-function can no longer detect if the mouse is on the sprite.
This is rather disturbing for the usability of my code. Does anyone know how to avoid this?
Thank you!
You can set mouseEnabled and mouseChildren of the Sprites getting in the way to false:
aboveSprite.mouseEnabled = false;
aboveSprite.mouseChildren = false;
Use somethng like:
mc_1.hitTestObject(mc_2);
to determine an overlap. Then discover which MovieClip is 'above' the other with something like
parent.getChildIndex(this)
Then use mouseEnabled = false to de-sensitize the MovieClip that you don't want to respond.
Your exact code may vary somewhat depending on the setup.
I just want to clarify, can a movieclip that triggers by interaction trigger another movieclip?
I am doing a function which using blowing function which is working by the way.
function doEveryFrame(e:Event)
{
trace(mic.activityLevel);
if(mic.activityLevel == 100)
{
ballMC.gotoAndPlay(1);
}
}
After above interaction ballMC reaches my rectangle graphic. From the rectangle, I want my blueballMC to just play.
I hope this is clear enough, though.
Yes, this is more than possible by:
1: First check if the movieclip is on the frame you want it to be on (if you want it to be on the last frame, you can check the movieclip's totalFrames keyword): if(yourMovieClip.currentFrame == frameYouWantItToBeOnToTrigger)
2: Trigger the next movieclip: if(yourMovieClip.currentFrame == frameYouWantItToBeOnToTrigger)
{
nextMovieClip.gotoAndPlay(frameNumberForNextMovieClipToStartOn);
}
And that's all there is to it.