0
votes

building an Adobe AIR app- seem to be having an issue with localToGlobal. I've been following this to set up my app for multiple screen sizes:

http://www.adobe.com/devnet/air/articles/multiple-screen-sizes.html

But I seem to always be running into an issue with my localToGlobal. I have used most of the code in the "Scaling and centering an interface" section and my App is adjusting the app size properly.

I have converted all my localToGlobal calls and multiplied the new scale value to the x and y but am not getting the result needed. It works fine still on the original iPhone 4/4s resolution, but testing on the 3gs resolution my Line Intersections are not working, that specifically use the localToGlobal code to figure out.

Here's the code for a call to a local point:

var p:Point = localToGlobal(_lineStart);
p = parent.globalToLocal(p);
p.x *= GameHolderSun.scaleValue;
p.y *= GameHolderSun.scaleValue;

return p;

Determine Intersection:

var p:Point = determineLineIntersection(_laser.get2ndLastPoint(), _laser.getLastPoint(), _reflectors[i].lineStart, _reflectors[i].lineEnd);
if(p != null){
    _laser.addNewLinePoint(p, _reflectors[i].rotation);
}

Line Intersection function I grabbed online:

private function determineLineIntersection(A:Point, B:Point, E:Point, F:Point,as_seg:Boolean=true):Point 
    {   
        var ip:Point;
        var a1:Number;
        var a2:Number;
        var b1:Number;
        var b2:Number;
        var c1:Number;
        var c2:Number;

        a1= B.y-A.y;
        b1= A.x-B.x;
        c1= B.x*A.y - A.x*B.y;
        a2= F.y-E.y;
        b2= E.x-F.x;
        c2= F.x*E.y - E.x*F.y;

        var denom:Number=a1*b2 - a2*b1;
        if (denom == 0) {
            return null;
        }

        ip=new Point();
        ip.x=(b1*c2 - b2*c1)/denom;
        ip.y=(a2*c1 - a1*c2)/denom;
        ip.x *= GameHolderSun.scaleValue;
        ip.y *= GameHolderSun.scaleValue;

        if(as_seg)
        {
            if(Math.pow(ip.x - B.x, 2) + Math.pow(ip.y - B.y, 2) > Math.pow(A.x - B.x, 2) + Math.pow(A.y - B.y, 2)) return null;
            if(Math.pow(ip.x - A.x, 2) + Math.pow(ip.y - A.y, 2) > Math.pow(A.x - B.x, 2) + Math.pow(A.y - B.y, 2)) return null;
            if(Math.pow(ip.x - F.x, 2) + Math.pow(ip.y - F.y, 2) > Math.pow(E.x - F.x, 2) + Math.pow(E.y - F.y, 2)) return null;
            if(Math.pow(ip.x - E.x, 2) + Math.pow(ip.y - E.y, 2) > Math.pow(E.x - F.x, 2) + Math.pow(E.y - F.y, 2)) return null;
        }

        return ip;
    }

Hope someone can help!! I can give more information if needed!!

1

1 Answers

2
votes

I believe your issue is DPI, at least if you are setting applicationDPI. Stage values do not compensate for the forced DPI change.

To fix this, you have two options:

1) For stage.mouseX/mouseY and stage.stageHeight/Width, you can just use FlexGlobals.topLevelApplication.systemManager properties. I believe SystemManager has a mouseX/mouseY property and you can find the new width/height in the screen property

2) You account for the DPI change yourself. It's relatively simple to do so. For using localToGlobal, I think this is what you will have to do.

var x:Number = 200; //this number is in default DPI size
var appDPI:Number = FlexGlobals.topLevelApplication.applicationDPI;
var deviceDPI:Number = Capabilities.screenDPI; //actual DPI of device

//Adobe doesn't use the actual DPI, they use either 160, 240, or 320 
//and use ranges to determine which maps where
if ( deviceDPI < 200 ) {
    deviceDPI = 160;
}
else if ( deviceDPI >= 200 && deviceDPI < 280 ) {
    deviceDPI = 240;
}
else if ( deviceDPI >= 280 ) {
    deviceDPI = 320;
}

var newX:Number = x / ( deviceDPI / appDPI );

I highly suggest you create a Util class and throw this into a (maybe static) function as you will likely end up using it often. The X var can be any number, so long as it is not adjusted for DPI changes.

Hope that helps. I beat my head on a rock trying to figure out why my stage.stageWidth and stage.stageHeight values were incorrect back in July.