From e698d6bd355b997a0e48b027f465a3d76c3af56c Mon Sep 17 00:00:00 2001 From: Timothy Hely Date: Wed, 26 Dec 2012 09:51:54 -0600 Subject: [PATCH] Fixing issue 53: FlxU.RotatePoint Should use subtract and not add for dy. --- org/flixel/FlxU.as | 1242 ++++++++++++++++++++++---------------------- 1 file changed, 621 insertions(+), 621 deletions(-) diff --git a/org/flixel/FlxU.as b/org/flixel/FlxU.as index 5e0c3eff..e137cf0e 100755 --- a/org/flixel/FlxU.as +++ b/org/flixel/FlxU.as @@ -1,621 +1,621 @@ -package org.flixel -{ - import flash.net.URLRequest; - import flash.net.navigateToURL; - import flash.utils.getDefinitionByName; - import flash.utils.getQualifiedClassName; - import flash.utils.getTimer; - - public class FlxU - { - /** - * Opens a web page in a new tab or window. - * MUST be called from the UI thread or else badness. - * - * @param URL The address of the web page. - */ - static public function openURL(URL:String):void - { - navigateToURL(new URLRequest(URL), "_blank"); - } - - /** - * Calculate the absolute value of a number. - * - * @param Value Any number. - * - * @return The absolute value of that number. - */ - static public function abs(Value:Number):Number - { - return (Value>0)?Value:-Value; - } - - /** - * Round down to the next whole number. E.g. floor(1.7) == 1, and floor(-2.7) == -2. - * - * @param Value Any number. - * - * @return The rounded value of that number. - */ - static public function floor(Value:Number):Number - { - var number:Number = int(Value); - return (Value>0)?(number):((number!=Value)?(number-1):(number)); - } - - /** - * Round up to the next whole number. E.g. ceil(1.3) == 2, and ceil(-2.3) == -3. - * - * @param Value Any number. - * - * @return The rounded value of that number. - */ - static public function ceil(Value:Number):Number - { - var number:Number = int(Value); - return (Value>0)?((number!=Value)?(number+1):(number)):(number); - } - - /** - * Round to the closest whole number. E.g. round(1.7) == 2, and round(-2.3) == -2. - * - * @param Value Any number. - * - * @return The rounded value of that number. - */ - static public function round(Value:Number):Number - { - return int(Value+((Value>0)?0.5:-0.5)); - } - - /** - * Figure out which number is smaller. - * - * @param Number1 Any number. - * @param Number2 Any number. - * - * @return The smaller of the two numbers. - */ - static public function min(Number1:Number,Number2:Number):Number - { - return (Number1 <= Number2)?Number1:Number2; - } - - /** - * Figure out which number is larger. - * - * @param Number1 Any number. - * @param Number2 Any number. - * - * @return The larger of the two numbers. - */ - static public function max(Number1:Number,Number2:Number):Number - { - return (Number1 >= Number2)?Number1:Number2; - } - - /** - * Bound a number by a minimum and maximum. - * Ensures that this number is no smaller than the minimum, - * and no larger than the maximum. - * - * @param Value Any number. - * @param Min Any number. - * @param Max Any number. - * - * @return The bounded value of the number. - */ - static public function bound(Value:Number,Min:Number,Max:Number):Number - { - var lowerBound:Number = (ValueMax)?Max:lowerBound; - } - - /** - * Generates a random number based on the seed provided. - * - * @param Seed A number between 0 and 1, used to generate a predictable random number (very optional). - * - * @return A Number between 0 and 1. - */ - static public function srand(Seed:Number):Number - { - return ((69621 * int(Seed * 0x7FFFFFFF)) % 0x7FFFFFFF) / 0x7FFFFFFF; - } - - /** - * Shuffles the entries in an array into a new random order. - * FlxG.shuffle() is deterministic and safe for use with replays/recordings. - * HOWEVER, FlxU.shuffle() is NOT deterministic and unsafe for use with replays/recordings. - * - * @param A A Flash Array object containing...stuff. - * @param HowManyTimes How many swaps to perform during the shuffle operation. Good rule of thumb is 2-4 times as many objects are in the list. - * - * @return The same Flash Array object that you passed in in the first place. - */ - static public function shuffle(Objects:Array,HowManyTimes:uint):Array - { - var i:uint = 0; - var index1:uint; - var index2:uint; - var object:Object; - while(i < HowManyTimes) - { - index1 = Math.random()*Objects.length; - index2 = Math.random()*Objects.length; - object = Objects[index2]; - Objects[index2] = Objects[index1]; - Objects[index1] = object; - i++; - } - return Objects; - } - - /** - * Fetch a random entry from the given array. - * Will return null if random selection is missing, or array has no entries. - * FlxG.getRandom() is deterministic and safe for use with replays/recordings. - * HOWEVER, FlxU.getRandom() is NOT deterministic and unsafe for use with replays/recordings. - * - * @param Objects A Flash array of objects. - * @param StartIndex Optional offset off the front of the array. Default value is 0, or the beginning of the array. - * @param Length Optional restriction on the number of values you want to randomly select from. - * - * @return The random object that was selected. - */ - static public function getRandom(Objects:Array,StartIndex:uint=0,Length:uint=0):Object - { - if(Objects != null) - { - var l:uint = Length; - if((l == 0) || (l > Objects.length - StartIndex)) - l = Objects.length - StartIndex; - if(l > 0) - return Objects[StartIndex + uint(Math.random()*l)]; - } - return null; - } - - /** - * Just grabs the current "ticks" or time in milliseconds that has passed since Flash Player started up. - * Useful for finding out how long it takes to execute specific blocks of code. - * - * @return A uint to be passed to FlxU.endProfile(). - */ - static public function getTicks():uint - { - return getTimer(); - } - - /** - * Takes two "ticks" timestamps and formats them into the number of seconds that passed as a String. - * Useful for logging, debugging, the watch window, or whatever else. - * - * @param StartTicks The first timestamp from the system. - * @param EndTicks The second timestamp from the system. - * - * @return A String containing the formatted time elapsed information. - */ - static public function formatTicks(StartTicks:uint,EndTicks:uint):String - { - return ((EndTicks-StartTicks)/1000)+"s" - } - - /** - * Generate a Flash uint color from RGBA components. - * - * @param Red The red component, between 0 and 255. - * @param Green The green component, between 0 and 255. - * @param Blue The blue component, between 0 and 255. - * @param Alpha How opaque the color should be, either between 0 and 1 or 0 and 255. - * - * @return The color as a uint. - */ - static public function makeColor(Red:uint, Green:uint, Blue:uint, Alpha:Number=1.0):uint - { - return (((Alpha>1)?Alpha:(Alpha * 255)) & 0xFF) << 24 | (Red & 0xFF) << 16 | (Green & 0xFF) << 8 | (Blue & 0xFF); - } - - /** - * Generate a Flash uint color from HSB components. - * - * @param Hue A number between 0 and 360, indicating position on a color strip or wheel. - * @param Saturation A number between 0 and 1, indicating how colorful or gray the color should be. 0 is gray, 1 is vibrant. - * @param Brightness A number between 0 and 1, indicating how bright the color should be. 0 is black, 1 is full bright. - * @param Alpha How opaque the color should be, either between 0 and 1 or 0 and 255. - * - * @return The color as a uint. - */ - static public function makeColorFromHSB(Hue:Number,Saturation:Number,Brightness:Number,Alpha:Number=1.0):uint - { - var red:Number; - var green:Number; - var blue:Number; - if(Saturation == 0.0) - { - red = Brightness; - green = Brightness; - blue = Brightness; - } - else - { - if(Hue == 360) - Hue = 0; - var slice:int = Hue/60; - var hf:Number = Hue/60 - slice; - var aa:Number = Brightness*(1 - Saturation); - var bb:Number = Brightness*(1 - Saturation*hf); - var cc:Number = Brightness*(1 - Saturation*(1.0 - hf)); - switch (slice) - { - case 0: red = Brightness; green = cc; blue = aa; break; - case 1: red = bb; green = Brightness; blue = aa; break; - case 2: red = aa; green = Brightness; blue = cc; break; - case 3: red = aa; green = bb; blue = Brightness; break; - case 4: red = cc; green = aa; blue = Brightness; break; - case 5: red = Brightness; green = aa; blue = bb; break; - default: red = 0; green = 0; blue = 0; break; - } - } - - return (((Alpha>1)?Alpha:(Alpha * 255)) & 0xFF) << 24 | uint(red*255) << 16 | uint(green*255) << 8 | uint(blue*255); - } - - /** - * Loads an array with the RGBA values of a Flash uint color. - * RGB values are stored 0-255. Alpha is stored as a floating point number between 0 and 1. - * - * @param Color The color you want to break into components. - * @param Results An optional parameter, allows you to use an array that already exists in memory to store the result. - * - * @return An Array object containing the Red, Green, Blue and Alpha values of the given color. - */ - static public function getRGBA(Color:uint,Results:Array=null):Array - { - if(Results == null) - Results = new Array(); - Results[0] = (Color >> 16) & 0xFF; - Results[1] = (Color >> 8) & 0xFF; - Results[2] = Color & 0xFF; - Results[3] = Number((Color >> 24) & 0xFF) / 255; - return Results; - } - - /** - * Loads an array with the HSB values of a Flash uint color. - * Hue is a value between 0 and 360. Saturation, Brightness and Alpha - * are as floating point numbers between 0 and 1. - * - * @param Color The color you want to break into components. - * @param Results An optional parameter, allows you to use an array that already exists in memory to store the result. - * - * @return An Array object containing the Red, Green, Blue and Alpha values of the given color. - */ - static public function getHSB(Color:uint,Results:Array=null):Array - { - if(Results == null) - Results = new Array(); - - var red:Number = Number((Color >> 16) & 0xFF) / 255; - var green:Number = Number((Color >> 8) & 0xFF) / 255; - var blue:Number = Number((Color) & 0xFF) / 255; - - var m:Number = (red>green)?red:green; - var dmax:Number = (m>blue)?m:blue; - m = (red>green)?green:red; - var dmin:Number = (m>blue)?blue:m; - var range:Number = dmax - dmin; - - Results[2] = dmax; - Results[1] = 0; - Results[0] = 0; - - if(dmax != 0) - Results[1] = range / dmax; - if(Results[1] != 0) - { - if (red == dmax) - Results[0] = (green - blue) / range; - else if (green == dmax) - Results[0] = 2 + (blue - red) / range; - else if (blue == dmax) - Results[0] = 4 + (red - green) / range; - Results[0] *= 60; - if(Results[0] < 0) - Results[0] += 360; - } - - Results[3] = Number((Color >> 24) & 0xFF) / 255; - return Results; - } - - /** - * Format seconds as minutes with a colon, an optionally with milliseconds too. - * - * @param Seconds The number of seconds (for example, time remaining, time spent, etc). - * @param ShowMS Whether to show milliseconds after a "." as well. Default value is false. - * - * @return A nicely formatted String, like "1:03". - */ - static public function formatTime(Seconds:Number,ShowMS:Boolean=false):String - { - var timeString:String = int(Seconds/60) + ":"; - var timeStringHelper:int = int(Seconds)%60; - if(timeStringHelper < 10) - timeString += "0"; - timeString += timeStringHelper; - if(ShowMS) - { - timeString += "."; - timeStringHelper = (Seconds-int(Seconds))*100; - if(timeStringHelper < 10) - timeString += "0"; - timeString += timeStringHelper; - } - return timeString; - } - - /** - * Generate a comma-separated string from an array. - * Especially useful for tracing or other debug output. - * - * @param AnyArray Any Array object. - * - * @return A comma-separated String containing the .toString() output of each element in the array. - */ - static public function formatArray(AnyArray:Array):String - { - if((AnyArray == null) || (AnyArray.length <= 0)) - return ""; - var string:String = AnyArray[0].toString(); - var i:uint = 1; - var l:uint = AnyArray.length; - while(i < l) - string += ", " + AnyArray[i++].toString(); - return string; - } - - /** - * Automatically commas and decimals in the right places for displaying money amounts. - * Does not include a dollar sign or anything, so doesn't really do much - * if you call say var results:String = FlxU.formatMoney(10,false); - * However, very handy for displaying large sums or decimal money values. - * - * @param Amount How much moneys (in dollars, or the equivalent "main" currency - i.e. not cents). - * @param ShowDecimal Whether to show the decimals/cents component. Default value is true. - * @param EnglishStyle Major quantities (thousands, millions, etc) separated by commas, and decimal by a period. Default value is true. - * - * @return A nicely formatted String. Does not include a dollar sign or anything! - */ - static public function formatMoney(Amount:Number,ShowDecimal:Boolean=true,EnglishStyle:Boolean=true):String - { - var helper:int; - var amount:int = Amount; - var string:String = ""; - var comma:String = ""; - var zeroes:String = ""; - while(amount > 0) - { - if((string.length > 0) && comma.length <= 0) - { - if(EnglishStyle) - comma = ","; - else - comma = "."; - } - zeroes = ""; - helper = amount - int(amount/1000)*1000; - amount /= 1000; - if(amount > 0) - { - if(helper < 100) - zeroes += "0"; - if(helper < 10) - zeroes += "0"; - } - string = zeroes + helper + comma + string; - } - if(ShowDecimal) - { - amount = int(Amount*100)-(int(Amount)*100); - string += (EnglishStyle?".":",") + amount; - if(amount < 10) - string += "0"; - } - return string; - } - - /** - * Get the String name of any Object. - * - * @param Obj The Object object in question. - * @param Simple Returns only the class name, not the package or packages. - * - * @return The name of the Class as a String object. - */ - static public function getClassName(Obj:Object,Simple:Boolean=false):String - { - var string:String = getQualifiedClassName(Obj); - string = string.replace("::","."); - if(Simple) - string = string.substr(string.lastIndexOf(".")+1); - return string; - } - - /** - * Check to see if two objects have the same class name. - * - * @param Object1 The first object you want to check. - * @param Object2 The second object you want to check. - * - * @return Whether they have the same class name or not. - */ - static public function compareClassNames(Object1:Object,Object2:Object):Boolean - { - return getQualifiedClassName(Object1) == getQualifiedClassName(Object2); - } - - /** - * Look up a Class object by its string name. - * - * @param Name The String name of the Class you are interested in. - * - * @return A Class object. - */ - static public function getClass(Name:String):Class - { - return getDefinitionByName(Name) as Class; - } - - /** - * A tween-like function that takes a starting velocity - * and some other factors and returns an altered velocity. - * - * @param Velocity Any component of velocity (e.g. 20). - * @param Acceleration Rate at which the velocity is changing. - * @param Drag Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set. - * @param Max An absolute value cap for the velocity. - * - * @return The altered Velocity value. - */ - static public function computeVelocity(Velocity:Number, Acceleration:Number=0, Drag:Number=0, Max:Number=10000):Number - { - if(Acceleration != 0) - Velocity += Acceleration*FlxG.elapsed; - else if(Drag != 0) - { - var drag:Number = Drag*FlxG.elapsed; - if(Velocity - drag > 0) - Velocity = Velocity - drag; - else if(Velocity + drag < 0) - Velocity += drag; - else - Velocity = 0; - } - if((Velocity != 0) && (Max != 10000)) - { - if(Velocity > Max) - Velocity = Max; - else if(Velocity < -Max) - Velocity = -Max; - } - return Velocity; - } - - //*** NOTE: THESE LAST THREE FUNCTIONS REQUIRE FLXPOINT ***// - - /** - * Rotates a point in 2D space around another point by the given angle. - * - * @param X The X coordinate of the point you want to rotate. - * @param Y The Y coordinate of the point you want to rotate. - * @param PivotX The X coordinate of the point you want to rotate around. - * @param PivotY The Y coordinate of the point you want to rotate around. - * @param Angle Rotate the point by this many degrees. - * @param Point Optional FlxPoint to store the results in. - * - * @return A FlxPoint containing the coordinates of the rotated point. - */ - static public function rotatePoint(X:Number, Y:Number, PivotX:Number, PivotY:Number, Angle:Number,Point:FlxPoint=null):FlxPoint - { - var sin:Number = 0; - var cos:Number = 0; - var radians:Number = Angle * -0.017453293; - while (radians < -3.14159265) - radians += 6.28318531; - while (radians > 3.14159265) - radians = radians - 6.28318531; - - if (radians < 0) - { - sin = 1.27323954 * radians + .405284735 * radians * radians; - if (sin < 0) - sin = .225 * (sin *-sin - sin) + sin; - else - sin = .225 * (sin * sin - sin) + sin; - } - else - { - sin = 1.27323954 * radians - 0.405284735 * radians * radians; - if (sin < 0) - sin = .225 * (sin *-sin - sin) + sin; - else - sin = .225 * (sin * sin - sin) + sin; - } - - radians += 1.57079632; - if (radians > 3.14159265) - radians = radians - 6.28318531; - if (radians < 0) - { - cos = 1.27323954 * radians + 0.405284735 * radians * radians; - if (cos < 0) - cos = .225 * (cos *-cos - cos) + cos; - else - cos = .225 * (cos * cos - cos) + cos; - } - else - { - cos = 1.27323954 * radians - 0.405284735 * radians * radians; - if (cos < 0) - cos = .225 * (cos *-cos - cos) + cos; - else - cos = .225 * (cos * cos - cos) + cos; - } - - var dx:Number = X-PivotX; - var dy:Number = PivotY+Y; //Y axis is inverted in flash, normally this would be a subtract operation - if(Point == null) - Point = new FlxPoint(); - Point.x = PivotX + cos*dx - sin*dy; - Point.y = PivotY - sin*dx - cos*dy; - return Point; - }; - - /** - * Calculates the angle between two points. 0 degrees points straight up. - * - * @param Point1 The X coordinate of the point. - * @param Point2 The Y coordinate of the point. - * - * @return The angle in degrees, between -180 and 180. - */ - static public function getAngle(Point1:FlxPoint, Point2:FlxPoint):Number - { - var x:Number = Point2.x - Point1.x; - var y:Number = Point2.y - Point1.y; - if((x == 0) && (y == 0)) - return 0; - var c1:Number = 3.14159265 * 0.25; - var c2:Number = 3 * c1; - var ay:Number = (y < 0)?-y:y; - var angle:Number = 0; - if (x >= 0) - angle = c1 - c1 * ((x - ay) / (x + ay)); - else - angle = c2 - c1 * ((x + ay) / (ay - x)); - angle = ((y < 0)?-angle:angle)*57.2957796; - if(angle > 90) - angle = angle - 270; - else - angle += 90; - return angle; - }; - - /** - * Calculate the distance between two points. - * - * @param Point1 A FlxPoint object referring to the first location. - * @param Point2 A FlxPoint object referring to the second location. - * - * @return The distance between the two points as a floating point Number object. - */ - static public function getDistance(Point1:FlxPoint,Point2:FlxPoint):Number - { - var dx:Number = Point1.x - Point2.x; - var dy:Number = Point1.y - Point2.y; - return Math.sqrt(dx * dx + dy * dy); - } - } -} +package org.flixel +{ + import flash.net.URLRequest; + import flash.net.navigateToURL; + import flash.utils.getDefinitionByName; + import flash.utils.getQualifiedClassName; + import flash.utils.getTimer; + + public class FlxU + { + /** + * Opens a web page in a new tab or window. + * MUST be called from the UI thread or else badness. + * + * @param URL The address of the web page. + */ + static public function openURL(URL:String):void + { + navigateToURL(new URLRequest(URL), "_blank"); + } + + /** + * Calculate the absolute value of a number. + * + * @param Value Any number. + * + * @return The absolute value of that number. + */ + static public function abs(Value:Number):Number + { + return (Value>0)?Value:-Value; + } + + /** + * Round down to the next whole number. E.g. floor(1.7) == 1, and floor(-2.7) == -2. + * + * @param Value Any number. + * + * @return The rounded value of that number. + */ + static public function floor(Value:Number):Number + { + var number:Number = int(Value); + return (Value>0)?(number):((number!=Value)?(number-1):(number)); + } + + /** + * Round up to the next whole number. E.g. ceil(1.3) == 2, and ceil(-2.3) == -3. + * + * @param Value Any number. + * + * @return The rounded value of that number. + */ + static public function ceil(Value:Number):Number + { + var number:Number = int(Value); + return (Value>0)?((number!=Value)?(number+1):(number)):(number); + } + + /** + * Round to the closest whole number. E.g. round(1.7) == 2, and round(-2.3) == -2. + * + * @param Value Any number. + * + * @return The rounded value of that number. + */ + static public function round(Value:Number):Number + { + return int(Value+((Value>0)?0.5:-0.5)); + } + + /** + * Figure out which number is smaller. + * + * @param Number1 Any number. + * @param Number2 Any number. + * + * @return The smaller of the two numbers. + */ + static public function min(Number1:Number,Number2:Number):Number + { + return (Number1 <= Number2)?Number1:Number2; + } + + /** + * Figure out which number is larger. + * + * @param Number1 Any number. + * @param Number2 Any number. + * + * @return The larger of the two numbers. + */ + static public function max(Number1:Number,Number2:Number):Number + { + return (Number1 >= Number2)?Number1:Number2; + } + + /** + * Bound a number by a minimum and maximum. + * Ensures that this number is no smaller than the minimum, + * and no larger than the maximum. + * + * @param Value Any number. + * @param Min Any number. + * @param Max Any number. + * + * @return The bounded value of the number. + */ + static public function bound(Value:Number,Min:Number,Max:Number):Number + { + var lowerBound:Number = (ValueMax)?Max:lowerBound; + } + + /** + * Generates a random number based on the seed provided. + * + * @param Seed A number between 0 and 1, used to generate a predictable random number (very optional). + * + * @return A Number between 0 and 1. + */ + static public function srand(Seed:Number):Number + { + return ((69621 * int(Seed * 0x7FFFFFFF)) % 0x7FFFFFFF) / 0x7FFFFFFF; + } + + /** + * Shuffles the entries in an array into a new random order. + * FlxG.shuffle() is deterministic and safe for use with replays/recordings. + * HOWEVER, FlxU.shuffle() is NOT deterministic and unsafe for use with replays/recordings. + * + * @param A A Flash Array object containing...stuff. + * @param HowManyTimes How many swaps to perform during the shuffle operation. Good rule of thumb is 2-4 times as many objects are in the list. + * + * @return The same Flash Array object that you passed in in the first place. + */ + static public function shuffle(Objects:Array,HowManyTimes:uint):Array + { + var i:uint = 0; + var index1:uint; + var index2:uint; + var object:Object; + while(i < HowManyTimes) + { + index1 = Math.random()*Objects.length; + index2 = Math.random()*Objects.length; + object = Objects[index2]; + Objects[index2] = Objects[index1]; + Objects[index1] = object; + i++; + } + return Objects; + } + + /** + * Fetch a random entry from the given array. + * Will return null if random selection is missing, or array has no entries. + * FlxG.getRandom() is deterministic and safe for use with replays/recordings. + * HOWEVER, FlxU.getRandom() is NOT deterministic and unsafe for use with replays/recordings. + * + * @param Objects A Flash array of objects. + * @param StartIndex Optional offset off the front of the array. Default value is 0, or the beginning of the array. + * @param Length Optional restriction on the number of values you want to randomly select from. + * + * @return The random object that was selected. + */ + static public function getRandom(Objects:Array,StartIndex:uint=0,Length:uint=0):Object + { + if(Objects != null) + { + var l:uint = Length; + if((l == 0) || (l > Objects.length - StartIndex)) + l = Objects.length - StartIndex; + if(l > 0) + return Objects[StartIndex + uint(Math.random()*l)]; + } + return null; + } + + /** + * Just grabs the current "ticks" or time in milliseconds that has passed since Flash Player started up. + * Useful for finding out how long it takes to execute specific blocks of code. + * + * @return A uint to be passed to FlxU.endProfile(). + */ + static public function getTicks():uint + { + return getTimer(); + } + + /** + * Takes two "ticks" timestamps and formats them into the number of seconds that passed as a String. + * Useful for logging, debugging, the watch window, or whatever else. + * + * @param StartTicks The first timestamp from the system. + * @param EndTicks The second timestamp from the system. + * + * @return A String containing the formatted time elapsed information. + */ + static public function formatTicks(StartTicks:uint,EndTicks:uint):String + { + return ((EndTicks-StartTicks)/1000)+"s" + } + + /** + * Generate a Flash uint color from RGBA components. + * + * @param Red The red component, between 0 and 255. + * @param Green The green component, between 0 and 255. + * @param Blue The blue component, between 0 and 255. + * @param Alpha How opaque the color should be, either between 0 and 1 or 0 and 255. + * + * @return The color as a uint. + */ + static public function makeColor(Red:uint, Green:uint, Blue:uint, Alpha:Number=1.0):uint + { + return (((Alpha>1)?Alpha:(Alpha * 255)) & 0xFF) << 24 | (Red & 0xFF) << 16 | (Green & 0xFF) << 8 | (Blue & 0xFF); + } + + /** + * Generate a Flash uint color from HSB components. + * + * @param Hue A number between 0 and 360, indicating position on a color strip or wheel. + * @param Saturation A number between 0 and 1, indicating how colorful or gray the color should be. 0 is gray, 1 is vibrant. + * @param Brightness A number between 0 and 1, indicating how bright the color should be. 0 is black, 1 is full bright. + * @param Alpha How opaque the color should be, either between 0 and 1 or 0 and 255. + * + * @return The color as a uint. + */ + static public function makeColorFromHSB(Hue:Number,Saturation:Number,Brightness:Number,Alpha:Number=1.0):uint + { + var red:Number; + var green:Number; + var blue:Number; + if(Saturation == 0.0) + { + red = Brightness; + green = Brightness; + blue = Brightness; + } + else + { + if(Hue == 360) + Hue = 0; + var slice:int = Hue/60; + var hf:Number = Hue/60 - slice; + var aa:Number = Brightness*(1 - Saturation); + var bb:Number = Brightness*(1 - Saturation*hf); + var cc:Number = Brightness*(1 - Saturation*(1.0 - hf)); + switch (slice) + { + case 0: red = Brightness; green = cc; blue = aa; break; + case 1: red = bb; green = Brightness; blue = aa; break; + case 2: red = aa; green = Brightness; blue = cc; break; + case 3: red = aa; green = bb; blue = Brightness; break; + case 4: red = cc; green = aa; blue = Brightness; break; + case 5: red = Brightness; green = aa; blue = bb; break; + default: red = 0; green = 0; blue = 0; break; + } + } + + return (((Alpha>1)?Alpha:(Alpha * 255)) & 0xFF) << 24 | uint(red*255) << 16 | uint(green*255) << 8 | uint(blue*255); + } + + /** + * Loads an array with the RGBA values of a Flash uint color. + * RGB values are stored 0-255. Alpha is stored as a floating point number between 0 and 1. + * + * @param Color The color you want to break into components. + * @param Results An optional parameter, allows you to use an array that already exists in memory to store the result. + * + * @return An Array object containing the Red, Green, Blue and Alpha values of the given color. + */ + static public function getRGBA(Color:uint,Results:Array=null):Array + { + if(Results == null) + Results = new Array(); + Results[0] = (Color >> 16) & 0xFF; + Results[1] = (Color >> 8) & 0xFF; + Results[2] = Color & 0xFF; + Results[3] = Number((Color >> 24) & 0xFF) / 255; + return Results; + } + + /** + * Loads an array with the HSB values of a Flash uint color. + * Hue is a value between 0 and 360. Saturation, Brightness and Alpha + * are as floating point numbers between 0 and 1. + * + * @param Color The color you want to break into components. + * @param Results An optional parameter, allows you to use an array that already exists in memory to store the result. + * + * @return An Array object containing the Red, Green, Blue and Alpha values of the given color. + */ + static public function getHSB(Color:uint,Results:Array=null):Array + { + if(Results == null) + Results = new Array(); + + var red:Number = Number((Color >> 16) & 0xFF) / 255; + var green:Number = Number((Color >> 8) & 0xFF) / 255; + var blue:Number = Number((Color) & 0xFF) / 255; + + var m:Number = (red>green)?red:green; + var dmax:Number = (m>blue)?m:blue; + m = (red>green)?green:red; + var dmin:Number = (m>blue)?blue:m; + var range:Number = dmax - dmin; + + Results[2] = dmax; + Results[1] = 0; + Results[0] = 0; + + if(dmax != 0) + Results[1] = range / dmax; + if(Results[1] != 0) + { + if (red == dmax) + Results[0] = (green - blue) / range; + else if (green == dmax) + Results[0] = 2 + (blue - red) / range; + else if (blue == dmax) + Results[0] = 4 + (red - green) / range; + Results[0] *= 60; + if(Results[0] < 0) + Results[0] += 360; + } + + Results[3] = Number((Color >> 24) & 0xFF) / 255; + return Results; + } + + /** + * Format seconds as minutes with a colon, an optionally with milliseconds too. + * + * @param Seconds The number of seconds (for example, time remaining, time spent, etc). + * @param ShowMS Whether to show milliseconds after a "." as well. Default value is false. + * + * @return A nicely formatted String, like "1:03". + */ + static public function formatTime(Seconds:Number,ShowMS:Boolean=false):String + { + var timeString:String = int(Seconds/60) + ":"; + var timeStringHelper:int = int(Seconds)%60; + if(timeStringHelper < 10) + timeString += "0"; + timeString += timeStringHelper; + if(ShowMS) + { + timeString += "."; + timeStringHelper = (Seconds-int(Seconds))*100; + if(timeStringHelper < 10) + timeString += "0"; + timeString += timeStringHelper; + } + return timeString; + } + + /** + * Generate a comma-separated string from an array. + * Especially useful for tracing or other debug output. + * + * @param AnyArray Any Array object. + * + * @return A comma-separated String containing the .toString() output of each element in the array. + */ + static public function formatArray(AnyArray:Array):String + { + if((AnyArray == null) || (AnyArray.length <= 0)) + return ""; + var string:String = AnyArray[0].toString(); + var i:uint = 1; + var l:uint = AnyArray.length; + while(i < l) + string += ", " + AnyArray[i++].toString(); + return string; + } + + /** + * Automatically commas and decimals in the right places for displaying money amounts. + * Does not include a dollar sign or anything, so doesn't really do much + * if you call say var results:String = FlxU.formatMoney(10,false); + * However, very handy for displaying large sums or decimal money values. + * + * @param Amount How much moneys (in dollars, or the equivalent "main" currency - i.e. not cents). + * @param ShowDecimal Whether to show the decimals/cents component. Default value is true. + * @param EnglishStyle Major quantities (thousands, millions, etc) separated by commas, and decimal by a period. Default value is true. + * + * @return A nicely formatted String. Does not include a dollar sign or anything! + */ + static public function formatMoney(Amount:Number,ShowDecimal:Boolean=true,EnglishStyle:Boolean=true):String + { + var helper:int; + var amount:int = Amount; + var string:String = ""; + var comma:String = ""; + var zeroes:String = ""; + while(amount > 0) + { + if((string.length > 0) && comma.length <= 0) + { + if(EnglishStyle) + comma = ","; + else + comma = "."; + } + zeroes = ""; + helper = amount - int(amount/1000)*1000; + amount /= 1000; + if(amount > 0) + { + if(helper < 100) + zeroes += "0"; + if(helper < 10) + zeroes += "0"; + } + string = zeroes + helper + comma + string; + } + if(ShowDecimal) + { + amount = int(Amount*100)-(int(Amount)*100); + string += (EnglishStyle?".":",") + amount; + if(amount < 10) + string += "0"; + } + return string; + } + + /** + * Get the String name of any Object. + * + * @param Obj The Object object in question. + * @param Simple Returns only the class name, not the package or packages. + * + * @return The name of the Class as a String object. + */ + static public function getClassName(Obj:Object,Simple:Boolean=false):String + { + var string:String = getQualifiedClassName(Obj); + string = string.replace("::","."); + if(Simple) + string = string.substr(string.lastIndexOf(".")+1); + return string; + } + + /** + * Check to see if two objects have the same class name. + * + * @param Object1 The first object you want to check. + * @param Object2 The second object you want to check. + * + * @return Whether they have the same class name or not. + */ + static public function compareClassNames(Object1:Object,Object2:Object):Boolean + { + return getQualifiedClassName(Object1) == getQualifiedClassName(Object2); + } + + /** + * Look up a Class object by its string name. + * + * @param Name The String name of the Class you are interested in. + * + * @return A Class object. + */ + static public function getClass(Name:String):Class + { + return getDefinitionByName(Name) as Class; + } + + /** + * A tween-like function that takes a starting velocity + * and some other factors and returns an altered velocity. + * + * @param Velocity Any component of velocity (e.g. 20). + * @param Acceleration Rate at which the velocity is changing. + * @param Drag Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set. + * @param Max An absolute value cap for the velocity. + * + * @return The altered Velocity value. + */ + static public function computeVelocity(Velocity:Number, Acceleration:Number=0, Drag:Number=0, Max:Number=10000):Number + { + if(Acceleration != 0) + Velocity += Acceleration*FlxG.elapsed; + else if(Drag != 0) + { + var drag:Number = Drag*FlxG.elapsed; + if(Velocity - drag > 0) + Velocity = Velocity - drag; + else if(Velocity + drag < 0) + Velocity += drag; + else + Velocity = 0; + } + if((Velocity != 0) && (Max != 10000)) + { + if(Velocity > Max) + Velocity = Max; + else if(Velocity < -Max) + Velocity = -Max; + } + return Velocity; + } + + //*** NOTE: THESE LAST THREE FUNCTIONS REQUIRE FLXPOINT ***// + + /** + * Rotates a point in 2D space around another point by the given angle. + * + * @param X The X coordinate of the point you want to rotate. + * @param Y The Y coordinate of the point you want to rotate. + * @param PivotX The X coordinate of the point you want to rotate around. + * @param PivotY The Y coordinate of the point you want to rotate around. + * @param Angle Rotate the point by this many degrees. + * @param Point Optional FlxPoint to store the results in. + * + * @return A FlxPoint containing the coordinates of the rotated point. + */ + static public function rotatePoint(X:Number, Y:Number, PivotX:Number, PivotY:Number, Angle:Number,Point:FlxPoint=null):FlxPoint + { + var sin:Number = 0; + var cos:Number = 0; + var radians:Number = Angle * -0.017453293; + while (radians < -3.14159265) + radians += 6.28318531; + while (radians > 3.14159265) + radians = radians - 6.28318531; + + if (radians < 0) + { + sin = 1.27323954 * radians + .405284735 * radians * radians; + if (sin < 0) + sin = .225 * (sin *-sin - sin) + sin; + else + sin = .225 * (sin * sin - sin) + sin; + } + else + { + sin = 1.27323954 * radians - 0.405284735 * radians * radians; + if (sin < 0) + sin = .225 * (sin *-sin - sin) + sin; + else + sin = .225 * (sin * sin - sin) + sin; + } + + radians += 1.57079632; + if (radians > 3.14159265) + radians = radians - 6.28318531; + if (radians < 0) + { + cos = 1.27323954 * radians + 0.405284735 * radians * radians; + if (cos < 0) + cos = .225 * (cos *-cos - cos) + cos; + else + cos = .225 * (cos * cos - cos) + cos; + } + else + { + cos = 1.27323954 * radians - 0.405284735 * radians * radians; + if (cos < 0) + cos = .225 * (cos *-cos - cos) + cos; + else + cos = .225 * (cos * cos - cos) + cos; + } + + var dx:Number = X-PivotX; + var dy:Number = PivotY-Y; + if(Point == null) + Point = new FlxPoint(); + Point.x = PivotX + cos*dx - sin*dy; + Point.y = PivotY - sin*dx - cos*dy; + return Point; + }; + + /** + * Calculates the angle between two points. 0 degrees points straight up. + * + * @param Point1 The X coordinate of the point. + * @param Point2 The Y coordinate of the point. + * + * @return The angle in degrees, between -180 and 180. + */ + static public function getAngle(Point1:FlxPoint, Point2:FlxPoint):Number + { + var x:Number = Point2.x - Point1.x; + var y:Number = Point2.y - Point1.y; + if((x == 0) && (y == 0)) + return 0; + var c1:Number = 3.14159265 * 0.25; + var c2:Number = 3 * c1; + var ay:Number = (y < 0)?-y:y; + var angle:Number = 0; + if (x >= 0) + angle = c1 - c1 * ((x - ay) / (x + ay)); + else + angle = c2 - c1 * ((x + ay) / (ay - x)); + angle = ((y < 0)?-angle:angle)*57.2957796; + if(angle > 90) + angle = angle - 270; + else + angle += 90; + return angle; + }; + + /** + * Calculate the distance between two points. + * + * @param Point1 A FlxPoint object referring to the first location. + * @param Point2 A FlxPoint object referring to the second location. + * + * @return The distance between the two points as a floating point Number object. + */ + static public function getDistance(Point1:FlxPoint,Point2:FlxPoint):Number + { + var dx:Number = Point1.x - Point2.x; + var dy:Number = Point1.y - Point2.y; + return Math.sqrt(dx * dx + dy * dy); + } + } +}