TwelvestoneFlash

AS3: localToGlobal problem in loaded SWF


Sign in

  • Waiting for Godot ( 730 k posts )
    Just conversation.
  • Thunder Dome ( 23 k posts )
    Photoshop Tennis and Collabs.
  • Photography ( 5.1 k posts )
    For all you shutterbugs, sh...
  • Flash ( 18 k posts )
    ActionScripting to tweens, ...
  • Front End ( 5.9 k posts )
    general front end design an...
  • Back End ( 9.7 k posts )
    serverside scripting, progr...
  • Projects and Theory ( 12 k posts )
    This forum is for discussio...
  • FAQ ( 269 posts )
    All those nagging questions...
  • Design ( 17 k posts )
    graphics & all aspects of g...
  • Purgatory ( 3.6 k posts )
    12stone Jail, feel free to ...
DontBogartMe
 
2008-12-12

ok this has been driving me crasee all day - maybe there's something I'm missing or some fab work around someone can suggest...

I have this app that is loading in a game - the game works on its own, but when I load it into the app, and offset it to the middle, suddenly all the hitTestPoints I was using to detect collisions don't work. I need to be able to offset the point I check by the amount the whole game has been offset to adjust the Point to make the hitTest work. But localToGlobal doesn't seem to do anything in this case.

I've set up a simple test case to show the problem that has 2 SWFs, one that contains a red block to click, and another that loads the first in and offsets it.

The first one on its own to prove it works ok alone: http://www.danwashere.com/dev/flash_issues/hittest_and_loaded_swf/Loaded_SWF.html

Now loaded in and offset: http://www.danwashere.com/dev/flash_issues/hittest_and_loaded_swf/

You can see that in the 2nd one you can't click on the red block anymore - you have to click a little way away to get it to work.

Here's the class code for these two test files:

package {

import flash.display.*; 
import flash.events.*;  
import flash.geom.Point;

public class Loaded_SWF extends MovieClip {     

    public function Loaded_SWF() {          
        red_block.mouseEnabled = false;         
        bg.addEventListener( MouseEvent.MOUSE_DOWN , mouseDownHandler );
        indicator.visible = false;
    }

    private function mouseDownHandler( event:MouseEvent ):void {
        // Test to see if they clicked on the RED BLOCK
        var point:Point = new Point(mouseX, mouseY);
        trace("");
        trace("1 MOUSE_DOWN - " + point.x + "/" + point.y);
        localToGlobal(point);
        trace("2 MOUSE_DOWN - " + point.x + "/" + point.y + " - the localToGlobal - it does nothing!");

        if (red_block.hitTestPoint(mouseX, mouseY, true)) {
            indicator.visible = !indicator.visible;
        }           
    }
}

}

package {

import flash.display.*; 
import flash.events.*;

import flash.net.*;

public class Hittest_and_Loaded_SWF extends MovieClip {

    private var ldrLoaded_SWF:Loader = new Loader();
    private var urLoaded_SWF:URLRequest = new URLRequest("Loaded_SWF.swf");

    public function Hittest_and_Loaded_SWF() {
        ldrLoaded_SWF.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
        ldrLoaded_SWF.load(urLoaded_SWF);
    }

    private function initHandler(e:Event):void {
        addChild(ldrLoaded_SWF);

        // Move the loaded content a little to the right and down, to bugger up the hittest...          
        ldrLoaded_SWF.x = 100;
        ldrLoaded_SWF.y = 50;
    }
}

}

Is there a reliable way to get the offset from within the loaded SWF? Of course my application is a lot more complicated than this, I'm also hosting it in a 100% wide div which means I can't predict how much offset will be applied, so I need a solution that is nicely encapsulated in the loaded clip.

DontBogartMe
 
2008-12-15

now I just know one of you has the answer to this one... stop holding out on me!

DontBogartMe
 
2008-12-15

meh, solved it myself.

I'll post the solution here, not to help you slackers but to help myself in the future should I hit this again and forget how I fixed it - myself, without your help at all - the last time k

ok so localToGlobal doesn't work for some reason (is that a Flash bug perhaps?) so use a little recursion to go back up the display list, working out the total offset from the actual stage. This is the new code for the Loaded_SWF class:

package {

import flash.display.*; 
import flash.events.*;  
import flash.geom.Point;

public class Loaded_SWF extends MovieClip {     

    public function Loaded_SWF() {          
        red_block.mouseEnabled = false;         
        bg.addEventListener( MouseEvent.MOUSE_DOWN , mouseDownHandler );
        indicator.visible = false;
    }

    private function adjustPointToAncestors(obj![k](/images/smilies/grin.gif)isplayObject, curPoint:Point):Point {
        var retVal:Point = curPoint;

        if (obj.parent != null) {
            retVal = adjustPointToAncestors(obj.parent, retVal);
            retVal.x += obj.parent.x;
            retVal.y += obj.parent.y;
        }

        return retVal;
    }

    private function mouseDownHandler( event:MouseEvent ):void {
        // Test to see if they clicked on the RED BLOCK
        var point:Point = new Point(mouseX, mouseY);
        trace("");
        trace("1 MOUSE_DOWN - " + point.x + "/" + point.y);
        localToGlobal(point);
        trace("2 MOUSE_DOWN - " + point.x + "/" + point.y + " - the localToGlobal - it does nothing!");

        point = adjustPointToAncestors(this, point);
        trace("3 MOUSE_DOWN - " + point.x + "/" + point.y + " - Mmmm recursion. Aah, that's better now!");


        if (red_block.hitTestPoint(point.x, point.y, true)) {
            indicator.visible = !indicator.visible;
        }           
    }
}

}

Big Ern
 
2008-12-15

Sorry dude, I would've helped if I had even the slightest clue as to how to solve your problem.

If your question was something like "How do I pull a movie clip out of the library dynamically?" I would've been on that like Oprah on a honey ham.

That's what you get for being the shithottest flash guy in a flash forum. k

DontBogartMe
 
2008-12-15

lol - I ain't the best in here by a long way, but thanks anyway.

JLM
 
2008-12-15

sorry I saw the post but was fighting my own wars with flash I came back this evening with a wiskey to see if you were still stuck.

DontBogartMe
 
2008-12-15

well, I'm still open to opinions on why localToGlobal is useless in loaded clips. And any other opinions on my methods of working around it would be good too, although for my purposes it seems to be working fine with no noticeable affect on performance.

Storm
 
2008-12-15

well I don't really know for sure hence why I stayed away from this thread.

I look back at your original code and all I can think to ask is what happens with adding:

this.localToGlobal

? (or assigning it directly to the MC such as: mcTarget.localToGlobal)

Because of AS3's strictness, I'm just wondering if it doesn't properly know what point to report. localToGlobal(point) is useless without the MC to reference and coming from AS2 I KNOW it is where the function lies but sometimes with AS3 I don't know if it makes that connection automatically.

It's a weak theory I know but it's all I can think of when I read your code. It's a stretch.

JLM
 
2008-12-15

have you full source for us to play i have ideas but too lazy.. ;j

DontBogartMe
 
2008-12-16

Storm - my class extends MovieClip, so it inherits the 'localToGlobal' method, so the 'this' isn't needed. I tested it to make sure.

Here's the full source that includes the solution: http://www.danwashere.com/dev/flash_issues/hittest_and_loaded_swf/Hittest and Loaded SWF.zip

This example is also closer to my full project because it is shown in a 100% wide div with a min-width, and the loaded clip is always centered - this means that the offset changes when you resize the window, and the only method I can find that handles that is my recursive function.

http://www.danwashere.com/dev/flash_issues/hittest_and_loaded_swf/Hittest_and_Loaded_SWF.html

JLM
 
2008-12-17

DontBorgartMe

Seems like flash is a bit flaky here is my proposed approach that works.

    private var _topCorner: Sprite;

    private function localToRealGlobal( point: Point ):Point
    {

        var realRoot:   DisplayObject   = root.parent.stage as DisplayObject;

        if( _topCorner == null )
        {

            _topCorner          = new Sprite();
            _topCorner.visible  = false; 
            (root as MovieClip).addChild( _topCorner );
            _topCorner.graphics.lineTo( 1, 1 );

        }

        stage.localToGlobal( point );

        var localStage:  Rectangle       = _topCorner.getBounds( realRoot );// stage.getBounds( realRoot ) seems to have slight negative x offset??

        return new Point( localStage.x + point.x, localStage.y + point.y )

    }

It is used

point = localToRealGlobal( point );

Sorry, you must be a member to post to a conversation. Either log in or sign up to get involved.
TwelvestoneFlash

AS3: localToGlobal problem in loaded SWF