hitTest in loaded movies

Jan 10 2004 Published by under Flash

Send to Kindle

Boy do I feel foolish. Not only can I not believe that I never knew this, but I can’t believe I never had a problem with this. I only now just discovered that the x, y point fed to hitTest must be in terms of the main Stage, or global coordinates. How did this escape me for so many years and how did this only cause a problem now???

This revelation came about as I am redesigning my site. I’ve always kept the main content window in the upper left corner, due to the fact that I always loaded the experiments into a level, not a movie clip. I had to do this because many of my experiments refer to _root, and some of them would be messed up if loaded into a clip. So I kept loading into a level and kept the level at 0, 0.

Then, along came _lockroot. Now I can load my experiments into a clip, which can be anywhere on the stage. Assigning _lockroot=true to the clip keeps the clip’s _root contained to the clip. Great!

But once I did that, I found that a whole lot of my experiments still weren’t working right. I tracked it down to those which used hitTest. None of the tests were working right. So, after trying everything else, I turned to ASDG. Lo and behold, the hitTest point must be in terms of Stage (global) coords. Because my experiments sometimes just test _xmouse or _ymouse, or test the position of a clip against another clip, and the window containing the experiment’s local coords were now different than the global coords, it was always off. Because my experiment window had always been at 0, 0 before, I never ran into this problem. Wow.

Now, how to fix it? I didn’t really want to search through almost 600 files looking for hitTests. And even if I did, just using _root._xmouse wouldn’t help, because of _lockroot – _root._xmouse would still not be the global stage _xmouse. And in the case of testing a clip against the x, y coords of another clip. There’d be no easy way to change it. I’d have to go in and write a localToGlobal function in every single experiment that had a hitTest in it.

Finally, I went to bed, where I do my best thinking. As usual, lying there trying to go to sleep, the solution came to me. Overwrite hitTest to include a localToGlobal conversion. here’s what I came up with:

MovieClip.prototype.oldHitTest = MovieClip.prototype.hitTest;
MovieClip.prototype.hitTest = function(x, y, sf){
	var obj = {x:x, y:y};
	this._parent.localToGlobal(obj);
	return this.oldHitTest(obj.x, obj.y, sf);
}

This saves the original hitTest function as “oldHitTest” in MovieClip.prototype. Then creates a new version. This takes the testing point and assigns it to an object. Then it runs localToGlobal on the point. “this._parent” refers to the timeline that the calling object is on. If that timeline’s coordinates are different than global, the object will now contain the converted global coordinates. We then use these coordinates to call “oldHitTest”, which will return true or false, and pass that back to the caller.

Seems to work, and saved me many hours.

Send to Kindle

4 responses so far. Comments will be closed after post is one year old.

  • Vera says:

    That’s interesting. I also do my best thinking in bed, but it usually happens in the morning. I must be processing stuff all night long because when I wake up, the answer is staring at me. :)

  • Zoomfreddy says:

    Something relative to hitTest… as the hitTest function evaluates values, you can use any reference for the hittest, not just _x, & _y properties, of course the shape/bounding box option can’t be used on this scenario, example:

    if(this.hitTest(_root.someArray([0], _root.some_mc._alpha)){
    trace(“works!!!”)
    }

    is this useful?… yes, i used it once to make a game.
    is this the a correct way to code? I don’t think so :)

  • fredo says:

    if(this.hitTest(_root.someArray([0], _root.some_mc._alpha)){
    trace(“works!!!”)
    }

    WTF!! That’s insane!!

  • Antonio says:

    I have a little trouble when i try to public the .fla of 040129, flash say to my self that
    “**Error** S?mbolo=planet, capa=Layer 1, fotograma=1:L?nea 1: No se ha podido cargar la clase ‘com.bit101.BilliardBall’.

    Total de errores de ActionScript: 1 Errores comunicados: 1″

    i only pretend to talk it to you.
    Thank for do all this wonderfull thing…i stay hours in front of mi monitor watching your works.

    Sorry about my english.