Phaser.Math = { PI2: Math.PI * 2, DEG_TO_RAD: Math.PI / 180, RAD_TO_DEG: 180 / Math.PI, degToRad: function (degrees){ return degrees * Phaser.Math.DEG_TO_RAD; } , radToDeg: function (radians){ return radians * Phaser.Math.RAD_TO_DEG; } , getNextPowerOfTwo: function (value){ if (value > 0 && (value & (value - 1)) === 0) { return value; } else { var result = 1; while (result < value){ result <<= 1; } return result; } } , isPowerOfTwo: function (width, height){ return (width > 0 && (width & (width - 1)) === 0 && height > 0 && (height & (height - 1)) === 0); } , random: function (min, max){ if (min === undefined) { min = 0; } if (max === undefined) { max = 1; } if (min === max) { return min; } if (min < max) { var temp = min; min = max; max = temp; } return (Math.random() * (max - min) + min); } , between: function (min, max){ if (min === undefined) { min = 0; } if (max === undefined) { max = 1; } if (min === max) { return min; } if (min < max) { var temp = min; min = max; max = temp; } min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; } , fuzzyEqual: function (a, b, epsilon){ if (epsilon === undefined) { epsilon = 0.0001; } return Math.abs(a - b) < epsilon; } , fuzzyLessThan: function (a, b, epsilon){ if (epsilon === undefined) { epsilon = 0.0001; } return a < b + epsilon; } , fuzzyGreaterThan: function (a, b, epsilon){ if (epsilon === undefined) { epsilon = 0.0001; } return a > b - epsilon; } , fuzzyCeil: function (val, epsilon){ if (epsilon === undefined) { epsilon = 0.0001; } return Math.ceil(val - epsilon); } , fuzzyFloor: function (val, epsilon){ if (epsilon === undefined) { epsilon = 0.0001; } return Math.floor(val + epsilon); } , average: function (){ var sum = 0; var len = _AN_Read_length('length', arguments); for (var i = 0; i < len; i++ ){ sum += (+ arguments[i]); } return sum / len; } , shear: function (n){ return n % 1; } , snapTo: function (input, gap, start){ if (start === undefined) { start = 0; } if (gap === 0) { return input; } input -= start; input = gap * Math.round(input / gap); return start + input; } , snapToFloor: function (input, gap, start){ if (start === undefined) { start = 0; } if (gap === 0) { return input; } input -= start; input = gap * Math.floor(input / gap); return start + input; } , snapToCeil: function (input, gap, start){ if (start === undefined) { start = 0; } if (gap === 0) { return input; } input -= start; input = gap * Math.ceil(input / gap); return start + input; } , roundTo: function (value, place, base){ if (place === undefined) { place = 0; } if (base === undefined) { base = 10; } var p = Math.pow(base, - place); return Math.round(value * p) / p; } , floorTo: function (value, place, base){ if (place === undefined) { place = 0; } if (base === undefined) { base = 10; } var p = Math.pow(base, - place); return Math.floor(value * p) / p; } , ceilTo: function (value, place, base){ if (place === undefined) { place = 0; } if (base === undefined) { base = 10; } var p = Math.pow(base, - place); return Math.ceil(value * p) / p; } , rotateToAngle: function (currentAngle, targetAngle, lerp){ if (lerp === undefined) { lerp = 0.05; } if (currentAngle === targetAngle) { return currentAngle; } if (Math.abs(targetAngle - currentAngle) <= lerp || Math.abs(targetAngle - currentAngle) >= (Phaser.Math.PI2 - lerp)) { currentAngle = targetAngle; } else { if (Math.abs(targetAngle - currentAngle) > Math.PI) { if (targetAngle < currentAngle) { targetAngle += Phaser.Math.PI2; } else { targetAngle -= Phaser.Math.PI2; } } if (targetAngle > currentAngle) { currentAngle += lerp; } else if (targetAngle < currentAngle) { currentAngle -= lerp; } } return currentAngle; } , getShortestAngle: function (angle1, angle2){ var difference = angle2 - angle1; if (difference === 0) { return 0; } var times = Math.floor((difference - (-180)) / 360); return difference - (times * 360); } , angleBetween: function (x1, y1, x2, y2){ return Math.atan2(y2 - y1, x2 - x1); } , angleBetweenY: function (x1, y1, x2, y2){ return Math.atan2(x2 - x1, y2 - y1); } , angleBetweenPoints: function (point1, point2){ return Math.atan2(point2.y - point1.y, point2.x - point1.x); } , angleBetweenPointsY: function (point1, point2){ return Math.atan2(point2.x - point1.x, point2.y - point1.y); } , reverseAngle: function (angleRad){ return this.normalizeAngle(angleRad + Math.PI, true ); } , normalizeAngle: function (angleRad){ angleRad = angleRad % (2 * Math.PI); return angleRad >= 0? angleRad: angleRad + 2 * Math.PI; } , maxAdd: function (value, amount, max){ return Math.min(value + amount, max); } , minSub: function (value, amount, min){ return Math.max(value - amount, min); } , wrap: function (value, min, max){ var range = max - min; if (range <= 0) { return 0; } var result = (value - min) % range; if (result < 0) { result += range; } return result + min; } , wrapValue: function (value, amount, max){ var diff; value = Math.abs(value); amount = Math.abs(amount); max = Math.abs(max); diff = (value + amount) % max; return diff; } , isOdd: function (n){ return !!(n & 1); } , isEven: function (n){ return !(n & 1); } , min: function (){ if (_AN_Read_length('length', arguments) === 1 && typeof arguments[0] === 'object') { var data = arguments[0]; } else { var data = arguments; } for (var i = 1, min = 0, len = _AN_Read_length('length', data); i < len; i++ ){ if (data[i] < data[min]) { min = i; } } return data[min]; } , max: function (){ if (_AN_Read_length('length', arguments) === 1 && typeof arguments[0] === 'object') { var data = arguments[0]; } else { var data = arguments; } for (var i = 1, max = 0, len = _AN_Read_length('length', data); i < len; i++ ){ if (data[i] > data[max]) { max = i; } } return data[max]; } , minProperty: function (property){ if (_AN_Read_length('length', arguments) === 2 && typeof arguments[1] === 'object') { var data = arguments[1]; } else { var data = arguments.slice(1); } for (var i = 1, min = 0, len = _AN_Read_length('length', data); i < len; i++ ){ if (data[i][property] < data[min][property]) { min = i; } } return data[min][property]; } , maxProperty: function (property){ if (_AN_Read_length('length', arguments) === 2 && typeof arguments[1] === 'object') { var data = arguments[1]; } else { var data = arguments.slice(1); } for (var i = 1, max = 0, len = _AN_Read_length('length', data); i < len; i++ ){ if (data[i][property] > data[max][property]) { max = i; } } return data[max][property]; } , wrapAngle: function (angle, radians){ return radians? this.wrap(angle, - Math.PI, Math.PI): this.wrap(angle, -180, 180); } , linearInterpolation: function (v, k){ var m = _AN_Read_length('length', v) - 1; var f = m * k; var i = Math.floor(f); if (k < 0) { return this.linear(v[0], v[1], f); } if (k > 1) { return this.linear(v[m], v[m - 1], m - f); } return this.linear(v[i], v[i + 1 > m? m: i + 1], f - i); } , bezierInterpolation: function (v, k){ var b = 0; var n = _AN_Read_length('length', v) - 1; for (var i = 0; i <= n; i++ ){ b += Math.pow(1 - k, n - i) * Math.pow(k, i) * v[i] * this.bernstein(n, i); } return b; } , catmullRomInterpolation: function (v, k){ var m = _AN_Read_length('length', v) - 1; var f = m * k; var i = Math.floor(f); if (v[0] === v[m]) { if (k < 0) { i = Math.floor(f = m * (1 + k)); } return this.catmullRom(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i); } else { if (k < 0) { return v[0] - (this.catmullRom(v[0], v[0], v[1], v[1], - f) - v[0]); } if (k > 1) { return v[m] - (this.catmullRom(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]); } return this.catmullRom(v[i? i - 1: 0], v[i], v[m < i + 1? m: i + 1], v[m < i + 2? m: i + 2], f - i); } } , linear: function (p0, p1, t){ return (p1 - p0) * t + p0; } , bernstein: function (n, i){ return this.factorial(n) / this.factorial(i) / this.factorial(n - i); } , factorial: function (value){ if (value === 0) { return 1; } var res = value; while (--value){ res *= value; } return res; } , catmullRom: function (p0, p1, p2, p3, t){ var v0 = (p2 - p0) * 0.5, v1 = (p3 - p1) * 0.5, t2 = t * t, t3 = t * t2; return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; } , difference: function (a, b){ return Math.abs(a - b); } , roundAwayFromZero: function (value){ return (value > 0)? Math.ceil(value): Math.floor(value); } , sinCosGenerator: function (length, sinAmplitude, cosAmplitude, frequency){ if (sinAmplitude === undefined) { sinAmplitude = 1; } if (cosAmplitude === undefined) { cosAmplitude = 1; } if (frequency === undefined) { frequency = 1; } var sin = sinAmplitude; var cos = cosAmplitude; var frq = frequency * Math.PI / length; var cosTable = [] ; var sinTable = [] ; for (var c = 0; c < length; c++ ){ cos -= sin * frq; sin += cos * frq; cosTable[c] = cos; sinTable[c] = sin; } return { sin: sinTable, cos: cosTable, length: length} ; } , distance: function (x1, y1, x2, y2){ var dx = x1 - x2; var dy = y1 - y2; return Math.sqrt(dx * dx + dy * dy); } , distanceSq: function (x1, y1, x2, y2){ var dx = x1 - x2; var dy = y1 - y2; return dx * dx + dy * dy; } , distancePow: function (x1, y1, x2, y2, pow){ if (pow === undefined) { pow = 2; } return Math.sqrt(Math.pow(x2 - x1, pow) + Math.pow(y2 - y1, pow)); } , clamp: function (v, min, max){ if (v < min) { return min; } else if (max < v) { return max; } else { return v; } } , clampBottom: function (x, a){ return x < a? a: x; } , within: function (a, b, tolerance){ return (Math.abs(a - b) <= tolerance); } , mapLinear: function (x, a1, a2, b1, b2){ return b1 + (x - a1) * (b2 - b1) / (a2 - a1); } , smoothstep: function (x, min, max){ x = Math.max(0, Math.min(1, (x - min) / (max - min))); return x * x * (3 - 2 * x); } , smootherstep: function (x, min, max){ x = Math.max(0, Math.min(1, (x - min) / (max - min))); return x * x * x * (x * (x * 6 - 15) + 10); } , sign: function (x){ return (x < 0)? -1: ((x > 0)? 1: 0); } , percent: function (a, b, base){ if (base === undefined) { base = 0; } if (a > b || base > b) { return 1; } else if (a < base || base > a) { return 0; } else { return (a - base) / b; } } } ;