From 2de70d07a5032df8a7cabfed74ac2f4151d6f6fd Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Mon, 3 Jun 2013 02:38:08 +0100 Subject: [PATCH] Fixed issue in Camera.inCamera check where it wouldn't take into consideration the Sprites scrollFactor. --- Phaser/Game.ts | 3 + Phaser/Phaser.csproj | 8 + Phaser/cameras/Camera.ts | 5 + Phaser/gameobjects/DynamicTexture.ts | 36 +- Phaser/input/Pointer.ts | 2 - Phaser/renderers/CanvasRenderer.ts | 6 +- Phaser/utils/ColorUtils.ts | 561 +++++++++++++++++++++++++++ Phaser/utils/PixelUtils.ts | 49 +++ README.md | 3 + Tests/Tests.csproj | 16 + Tests/assets/sprites/parsec.png | Bin 0 -> 6409 bytes Tests/input/motion lock 2.js | 26 ++ Tests/input/motion lock 2.ts | 43 ++ Tests/input/motion lock.js | 26 ++ Tests/input/motion lock.ts | 43 ++ Tests/input/snap 1.js | 33 ++ Tests/input/snap 1.ts | 49 +++ Tests/input/world drag.js | 36 ++ Tests/input/world drag.ts | 59 +++ Tests/phaser.js | 540 ++++++++++++++++++++++++-- build/phaser.d.ts | 291 +++++++++++++- build/phaser.js | 540 ++++++++++++++++++++++++-- 22 files changed, 2254 insertions(+), 121 deletions(-) create mode 100644 Phaser/utils/ColorUtils.ts create mode 100644 Phaser/utils/PixelUtils.ts create mode 100644 Tests/assets/sprites/parsec.png create mode 100644 Tests/input/motion lock 2.js create mode 100644 Tests/input/motion lock 2.ts create mode 100644 Tests/input/motion lock.js create mode 100644 Tests/input/motion lock.ts create mode 100644 Tests/input/snap 1.js create mode 100644 Tests/input/snap 1.ts create mode 100644 Tests/input/world drag.js create mode 100644 Tests/input/world drag.ts diff --git a/Phaser/Game.ts b/Phaser/Game.ts index e8bbf764f..3d92a6d1a 100644 --- a/Phaser/Game.ts +++ b/Phaser/Game.ts @@ -302,6 +302,9 @@ module Phaser { this.framerate = 60; this.isBooted = true; + // Set-up some static helper references + ColorUtils.game = this; + // Display the default game screen? if (this.onInitCallback == null && this.onCreateCallback == null && this.onUpdateCallback == null && this.onRenderCallback == null && this._pendingState == null) { diff --git a/Phaser/Phaser.csproj b/Phaser/Phaser.csproj index 2f0f60912..4076c036b 100644 --- a/Phaser/Phaser.csproj +++ b/Phaser/Phaser.csproj @@ -173,6 +173,14 @@ CircleUtils.ts + + + + ColorUtils.ts + + + PixelUtils.ts + PointUtils.ts diff --git a/Phaser/cameras/Camera.ts b/Phaser/cameras/Camera.ts index 6d997fef6..aee5cbc49 100644 --- a/Phaser/cameras/Camera.ts +++ b/Phaser/cameras/Camera.ts @@ -474,6 +474,11 @@ module Phaser { this._game.stage.context.globalAlpha = 1; } + // Debug test + this._game.stage.context.fillStyle = 'rgba(255,0,0,0.3)'; + //this._game.stage.context.fillRect(this.scaledX, this.scaledY, this.worldView.width, this.worldView.height); + this._game.stage.context.fillRect(this.worldView.x, this.worldView.y, this.worldView.width, this.worldView.height); + } /** diff --git a/Phaser/gameobjects/DynamicTexture.ts b/Phaser/gameobjects/DynamicTexture.ts index b06eb423a..ffee34c24 100644 --- a/Phaser/gameobjects/DynamicTexture.ts +++ b/Phaser/gameobjects/DynamicTexture.ts @@ -1,5 +1,6 @@ /// /// +/// /// /** @@ -90,7 +91,7 @@ module Phaser { //a = imageData.data[3]; var imageData = this.context.getImageData(x, y, 1, 1); - return this.getColor(imageData.data[0], imageData.data[1], imageData.data[2]); + return ColorUtils.getColor(imageData.data[0], imageData.data[1], imageData.data[2]); } @@ -104,7 +105,7 @@ module Phaser { var imageData = this.context.getImageData(x, y, 1, 1); - return this.getColor32(imageData.data[3], imageData.data[0], imageData.data[1], imageData.data[2]); + return ColorUtils.getColor32(imageData.data[3], imageData.data[0], imageData.data[1], imageData.data[2]); } @@ -288,37 +289,6 @@ module Phaser { return this.bounds.height; } - /** - * Given an alpha and 3 color values this will return an integer representation of it - * - * @param alpha {number} The Alpha value (between 0 and 255) - * @param red {number} The Red channel value (between 0 and 255) - * @param green {number} The Green channel value (between 0 and 255) - * @param blue {number} The Blue channel value (between 0 and 255) - * - * @return A native color value integer (format: 0xAARRGGBB) - */ - private getColor32(alpha: number, red: number, green: number, blue: number): number { - - return alpha << 24 | red << 16 | green << 8 | blue; - - } - - /** - * Given 3 color values this will return an integer representation of it - * - * @param red {number} The Red channel value (between 0 and 255) - * @param green {number} The Green channel value (between 0 and 255) - * @param blue {number} The Blue channel value (between 0 and 255) - * - * @return A native color value integer (format: 0xRRGGBB) - */ - private getColor(red: number, green: number, blue: number): number { - - return red << 16 | green << 8 | blue; - - } - } } \ No newline at end of file diff --git a/Phaser/input/Pointer.ts b/Phaser/input/Pointer.ts index e69998c9b..1284fee64 100644 --- a/Phaser/input/Pointer.ts +++ b/Phaser/input/Pointer.ts @@ -374,8 +374,6 @@ module Phaser { } } - //console.log('highest priority was', _highestPriority); - if (this.isDown) { // Now update all objects with the highest priority ID (can be more than 1) diff --git a/Phaser/renderers/CanvasRenderer.ts b/Phaser/renderers/CanvasRenderer.ts index 51f9becee..2fc79a809 100644 --- a/Phaser/renderers/CanvasRenderer.ts +++ b/Phaser/renderers/CanvasRenderer.ts @@ -90,12 +90,12 @@ module Phaser { return true; } - this._dx = sprite.frameBounds.x - camera.worldView.x; - this._dy = sprite.frameBounds.y - camera.worldView.y; + this._dx = sprite.frameBounds.x - (camera.worldView.x * sprite.scrollFactor.x); + this._dy = sprite.frameBounds.y - (camera.worldView.y * sprite.scrollFactor.y); this._dw = sprite.frameBounds.width * sprite.scale.x; this._dh = sprite.frameBounds.height * sprite.scale.y; - return (camera.worldView.right > this._dx) && (camera.worldView.x < this._dx + this._dw) && (camera.worldView.bottom > this._dy) && (camera.worldView.y < this._dy + this._dh); + return (camera.scaledX + camera.worldView.width > this._dx) && (camera.scaledX < this._dx + this._dw) && (camera.scaledY + camera.worldView.height > this._dy) && (camera.scaledY < this._dy + this._dh); } diff --git a/Phaser/utils/ColorUtils.ts b/Phaser/utils/ColorUtils.ts new file mode 100644 index 000000000..426bff917 --- /dev/null +++ b/Phaser/utils/ColorUtils.ts @@ -0,0 +1,561 @@ +/// +/// +/// +/// + +/** +* Phaser - ColorUtils +* +* A collection of methods useful for manipulating color values. +*/ + +module Phaser { + + export class ColorUtils { + + static game: Game; + + /** + * Given an alpha and 3 color values this will return an integer representation of it + * + * @param alpha {number} The Alpha value (between 0 and 255) + * @param red {number} The Red channel value (between 0 and 255) + * @param green {number} The Green channel value (between 0 and 255) + * @param blue {number} The Blue channel value (between 0 and 255) + * + * @return A native color value integer (format: 0xAARRGGBB) + */ + static getColor32(alpha: number, red: number, green: number, blue: number): number { + return alpha << 24 | red << 16 | green << 8 | blue; + } + + /** + * Given 3 color values this will return an integer representation of it + * + * @param red {number} The Red channel value (between 0 and 255) + * @param green {number} The Green channel value (between 0 and 255) + * @param blue {number} The Blue channel value (between 0 and 255) + * + * @return A native color value integer (format: 0xRRGGBB) + */ + static getColor(red: number, green: number, blue: number): number { + return red << 16 | green << 8 | blue; + } + + /** + * Get HSV color wheel values in an array which will be 360 elements in size + * + * @param alpha Alpha value for each color of the color wheel, between 0 (transparent) and 255 (opaque) + * + * @return Array + */ + static public getHSVColorWheel(alpha: number = 255) { + + var colors = []; + + for (var c: number = 0; c <= 359; c++) + { + //colors[c] = HSVtoRGB(c, 1.0, 1.0, alpha); + colors[c] = getWebRGB(HSVtoRGB(c, 1.0, 1.0, alpha)); + } + + return colors; + + } + + /** + * Returns a Complementary Color Harmony for the given color. + *

A complementary hue is one directly opposite the color given on the color wheel

+ *

Value returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * + * @return 0xAARRGGBB format color value + */ + static public getComplementHarmony(color: number): number { + + var hsv: any = RGBtoHSV(color); + + var opposite: number = ColorUtils.game.math.wrapValue(hsv.hue, 180, 359); + + return HSVtoRGB(opposite, 1.0, 1.0); + + } + + /** + * Returns an Analogous Color Harmony for the given color. + *

An Analogous harmony are hues adjacent to each other on the color wheel

+ *

Values returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * @param threshold Control how adjacent the colors will be (default +- 30 degrees) + * + * @return Object containing 3 properties: color1 (the original color), color2 (the warmer analogous color) and color3 (the colder analogous color) + */ + static public getAnalogousHarmony(color: number, threshold: number = 30) { + + var hsv: any = RGBtoHSV(color); + + if (threshold > 359 || threshold < 0) + { + throw Error("Color Warning: Invalid threshold given to getAnalogousHarmony()"); + } + + var warmer: number = ColorUtils.game.math.wrapValue(hsv.hue, 359 - threshold, 359); + var colder: number = ColorUtils.game.math.wrapValue(hsv.hue, threshold, 359); + + return { color1: color, color2: HSVtoRGB(warmer, 1.0, 1.0), color3: HSVtoRGB(colder, 1.0, 1.0), hue1: hsv.hue, hue2: warmer, hue3: colder } + + } + + /** + * Returns an Split Complement Color Harmony for the given color. + *

A Split Complement harmony are the two hues on either side of the color's Complement

+ *

Values returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * @param threshold Control how adjacent the colors will be to the Complement (default +- 30 degrees) + * + * @return Object containing 3 properties: color1 (the original color), color2 (the warmer analogous color) and color3 (the colder analogous color) + */ + static public getSplitComplementHarmony(color: number, threshold: number = 30): any { + + var hsv: any = RGBtoHSV(color); + + if (threshold >= 359 || threshold <= 0) + { + throw Error("FlxColor Warning: Invalid threshold given to getSplitComplementHarmony()"); + } + + var opposite: number = ColorUtils.game.math.wrapValue(hsv.hue, 180, 359); + + var warmer: number = ColorUtils.game.math.wrapValue(hsv.hue, opposite - threshold, 359); + var colder: number = ColorUtils.game.math.wrapValue(hsv.hue, opposite + threshold, 359); + + return { color1: color, color2: HSVtoRGB(warmer, hsv.saturation, hsv.value), color3: HSVtoRGB(colder, hsv.saturation, hsv.value), hue1: hsv.hue, hue2: warmer, hue3: colder } + } + + /** + * Returns a Triadic Color Harmony for the given color. + *

A Triadic harmony are 3 hues equidistant from each other on the color wheel

+ *

Values returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * + * @return Object containing 3 properties: color1 (the original color), color2 and color3 (the equidistant colors) + */ + static public getTriadicHarmony(color: number): any { + + var hsv: any = RGBtoHSV(color); + + var triadic1: number = ColorUtils.game.math.wrapValue(hsv.hue, 120, 359); + var triadic2: number = ColorUtils.game.math.wrapValue(triadic1, 120, 359); + + return { color1: color, color2: HSVtoRGB(triadic1, 1.0, 1.0), color3: HSVtoRGB(triadic2, 1.0, 1.0) } + + } + + /** + * Returns a string containing handy information about the given color including string hex value, + * RGB format information and HSL information. Each section starts on a newline, 3 lines in total. + * + * @param color A color value in the format 0xAARRGGBB + * + * @return string containing the 3 lines of information + */ + static public getColorInfo(color: number): string { + + var argb: any = getRGB(color); + var hsl: any = RGBtoHSV(color); + + // Hex format + var result: string = RGBtoHexstring(color) + "\n"; + + // RGB format + result = result.concat("Alpha: " + argb.alpha + " Red: " + argb.red + " Green: " + argb.green + " Blue: " + argb.blue) + "\n"; + + // HSL info + result = result.concat("Hue: " + hsl.hue + " Saturation: " + hsl.saturation + " Lightnes: " + hsl.lightness); + + return result; + + } + + /** + * Return a string representation of the color in the format 0xAARRGGBB + * + * @param color The color to get the string representation for + * + * @return A string of length 10 characters in the format 0xAARRGGBB + */ + static public RGBtoHexstring(color: number): string { + + var argb: any = getRGB(color); + + return "0x" + colorToHexstring(argb.alpha) + colorToHexstring(argb.red) + colorToHexstring(argb.green) + colorToHexstring(argb.blue); + + } + + /** + * Return a string representation of the color in the format #RRGGBB + * + * @param color The color to get the string representation for + * + * @return A string of length 10 characters in the format 0xAARRGGBB + */ + static public RGBtoWebstring(color: number): string { + + var argb: any = getRGB(color); + + return "#" + colorToHexstring(argb.red) + colorToHexstring(argb.green) + colorToHexstring(argb.blue); + + } + + /** + * Return a string containing a hex representation of the given color + * + * @param color The color channel to get the hex value for, must be a value between 0 and 255) + * + * @return A string of length 2 characters, i.e. 255 = FF, 0 = 00 + */ + static public colorToHexstring(color: number): string { + + var digits: string = "0123456789ABCDEF"; + + var lsd: number = color % 16; + var msd: number = (color - lsd) / 16; + + var hexified: string = digits.charAt(msd) + digits.charAt(lsd); + + return hexified; + + } + + /** + * Convert a HSV (hue, saturation, lightness) color space value to an RGB color + * + * @param h Hue degree, between 0 and 359 + * @param s Saturation, between 0.0 (grey) and 1.0 + * @param v Value, between 0.0 (black) and 1.0 + * @param alpha Alpha value to set per color (between 0 and 255) + * + * @return 32-bit ARGB color value (0xAARRGGBB) + */ + static HSVtoRGB(h: number, s: number, v: number, alpha: number = 255): number { + + var result: number; + + if (s == 0.0) + { + result = ColorUtils.getColor32(alpha, v * 255, v * 255, v * 255); + } + else + { + h = h / 60.0; + var f: number = h - Math.floor(h); + var p: number = v * (1.0 - s); + var q: number = v * (1.0 - s * f); + var t: number = v * (1.0 - s * (1.0 - f)); + + switch (Math.floor(h)) + { + case 0: + result = ColorUtils.getColor32(alpha, v * 255, t * 255, p * 255); + break; + + case 1: + result = ColorUtils.getColor32(alpha, q * 255, v * 255, p * 255); + break; + + case 2: + result = ColorUtils.getColor32(alpha, p * 255, v * 255, t * 255); + break; + + case 3: + result = ColorUtils.getColor32(alpha, p * 255, q * 255, v * 255); + break; + + case 4: + result = ColorUtils.getColor32(alpha, t * 255, p * 255, v * 255); + break; + + case 5: + result = ColorUtils.getColor32(alpha, v * 255, p * 255, q * 255); + break; + + default: + throw new Error("ColorUtils.HSVtoRGB : Unknown color"); + } + } + + return result; + + } + + /** + * Convert an RGB color value to an object containing the HSV color space values: Hue, Saturation and Lightness + * + * @param color In format 0xRRGGBB + * + * @return Object with the properties hue (from 0 to 360), saturation (from 0 to 1.0) and lightness (from 0 to 1.0, also available under .value) + */ + static public RGBtoHSV(color: number): any { + + var rgb: any = ColorUtils.getRGB(color); + + var red: number = rgb.red / 255; + var green: number = rgb.green / 255; + var blue: number = rgb.blue / 255; + + var min: number = Math.min(red, green, blue); + var max: number = Math.max(red, green, blue); + var delta: number = max - min; + var lightness: number = (max + min) / 2; + var hue: number; + var saturation: number; + + // Grey color, no chroma + if (delta == 0) + { + hue = 0; + saturation = 0; + } + else + { + if (lightness < 0.5) + { + saturation = delta / (max + min); + } + else + { + saturation = delta / (2 - max - min); + } + + var delta_r: number = (((max - red) / 6) + (delta / 2)) / delta; + var delta_g: number = (((max - green) / 6) + (delta / 2)) / delta; + var delta_b: number = (((max - blue) / 6) + (delta / 2)) / delta; + + if (red == max) + { + hue = delta_b - delta_g; + } + else if (green == max) + { + hue = (1 / 3) + delta_r - delta_b; + } + else if (blue == max) + { + hue = (2 / 3) + delta_g - delta_r; + } + + if (hue < 0) + { + hue += 1; + } + + if (hue > 1) + { + hue -= 1; + } + } + + // Keep the value with 0 to 359 + hue *= 360; + hue = Math.round(hue); + + return { hue: hue, saturation: saturation, lightness: lightness, value: lightness }; + + } + + /** + * + * @method interpolateColor + * @param {Number} color1 + * @param {Number} color2 + * @param {Number} steps + * @param {Number} currentStep + * @param {Number} alpha + * @return {Number} + * @static + */ + static public interpolateColor(color1: number, color2: number, steps: number, currentStep: number, alpha: number = 255): number { + + var src1: any = ColorUtils.getRGB(color1); + var src2: any = ColorUtils.getRGB(color2); + + var r: number = (((src2.red - src1.red) * currentStep) / steps) + src1.red; + var g: number = (((src2.green - src1.green) * currentStep) / steps) + src1.green; + var b: number = (((src2.blue - src1.blue) * currentStep) / steps) + src1.blue; + + return ColorUtils.getColor32(alpha, r, g, b); + + } + + /** + * + * @method interpolateColorWithRGB + * @param {Number} color + * @param {Number} r2 + * @param {Number} g2 + * @param {Number} b2 + * @param {Number} steps + * @param {Number} currentStep + * @return {Number} + * @static + */ + static public interpolateColorWithRGB(color: number, r2: number, g2: number, b2: number, steps: number, currentStep: number): number { + + var src: any = ColorUtils.getRGB(color); + + var r: number = (((r2 - src.red) * currentStep) / steps) + src.red; + var g: number = (((g2 - src.green) * currentStep) / steps) + src.green; + var b: number = (((b2 - src.blue) * currentStep) / steps) + src.blue; + + return ColorUtils.getColor(r, g, b); + + } + + /** + * + * @method interpolateRGB + * @param {Number} r1 + * @param {Number} g1 + * @param {Number} b1 + * @param {Number} r2 + * @param {Number} g2 + * @param {Number} b2 + * @param {Number} steps + * @param {Number} currentStep + * @return {Number} + * @static + */ + static public interpolateRGB(r1: number, g1: number, b1: number, r2: number, g2: number, b2: number, steps: number, currentStep: number): number { + + var r: number = (((r2 - r1) * currentStep) / steps) + r1; + var g: number = (((g2 - g1) * currentStep) / steps) + g1; + var b: number = (((b2 - b1) * currentStep) / steps) + b1; + + return ColorUtils.getColor(r, g, b); + + } + + /** + * Returns a random color value between black and white + *

Set the min value to start each channel from the given offset.

+ *

Set the max value to restrict the maximum color used per channel

+ * + * @param min The lowest value to use for the color + * @param max The highest value to use for the color + * @param alpha The alpha value of the returning color (default 255 = fully opaque) + * + * @return 32-bit color value with alpha + */ + static public getRandomColor(min: number = 0, max: number = 255, alpha: number = 255): number { + + // Sanity checks + if (max > 255) + { + return ColorUtils.getColor(255, 255, 255); + } + + if (min > max) + { + return ColorUtils.getColor(255, 255, 255); + } + + var red: number = min + Math.round(Math.random() * (max - min)); + var green: number = min + Math.round(Math.random() * (max - min)); + var blue: number = min + Math.round(Math.random() * (max - min)); + + return ColorUtils.getColor32(alpha, red, green, blue); + + } + + /** + * Return the component parts of a color as an Object with the properties alpha, red, green, blue + * + *

Alpha will only be set if it exist in the given color (0xAARRGGBB)

+ * + * @param color in RGB (0xRRGGBB) or ARGB format (0xAARRGGBB) + * + * @return Object with properties: alpha, red, green, blue + */ + static public getRGB(color: number): any { + return { alpha: color >>> 24, red: color >> 16 & 0xFF, green: color >> 8 & 0xFF, blue: color & 0xFF }; + } + + /** + * + * @method getWebRGB + * @param {Number} color + * @return {Any} + */ + static public getWebRGB(color: number): any { + + var alpha: number = (color >>> 24) / 255; + var red: number = color >> 16 & 0xFF; + var green: number = color >> 8 & 0xFF; + var blue: number = color & 0xFF; + + return 'rgba(' + red.toString() + ',' + green.toString() + ',' + blue.toString() + ',' + alpha.toString() + ')'; + + } + + /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Alpha component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Alpha component of the color, will be between 0 and 255 (0 being no Alpha, 255 full Alpha) + */ + static public getAlpha(color: number): number { + return color >>> 24; + } + + /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Alpha component as a value between 0 and 1 + * + * @param color In the format 0xAARRGGBB + * + * @return The Alpha component of the color, will be between 0 and 1 (0 being no Alpha (opaque), 1 full Alpha (transparent)) + */ + static public getAlphaFloat(color: number): number { + return (color >>> 24) / 255; + } + + /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Red component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Red component of the color, will be between 0 and 255 (0 being no color, 255 full Red) + */ + static public getRed(color: number): number { + return color >> 16 & 0xFF; + } + + /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Green component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Green component of the color, will be between 0 and 255 (0 being no color, 255 full Green) + */ + static public getGreen(color: number): number { + return color >> 8 & 0xFF; + } + + /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Blue component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Blue component of the color, will be between 0 and 255 (0 being no color, 255 full Blue) + */ + static public getBlue(color: number): number { + return color & 0xFF; + } + + } + +} \ No newline at end of file diff --git a/Phaser/utils/PixelUtils.ts b/Phaser/utils/PixelUtils.ts new file mode 100644 index 000000000..21ec835ff --- /dev/null +++ b/Phaser/utils/PixelUtils.ts @@ -0,0 +1,49 @@ +/// +/// +/// +/// + +/** +* Phaser - PixelUtils +* +* A collection of methods useful for manipulating pixels. +*/ + +module Phaser { + + export class PixelUtils { + + static boot() { + + PixelUtils.pixelCanvas = document.createElement('canvas'); + PixelUtils.pixelCanvas.width = 1; + PixelUtils.pixelCanvas.height = 1; + PixelUtils.pixelContext = PixelUtils.pixelCanvas.getContext('2d'); + + } + + /** + * Canvas element used in 1x1 pixel checks. + * @type {HTMLCanvasElement} + */ + static pixelCanvas: HTMLCanvasElement; + + /** + * Render context of pixelCanvas + * @type {CanvasRenderingContext2D} + */ + static pixelContext: CanvasRenderingContext2D; + + static getPixel(key: string, x: number, y: number): number { + + // write out a single pixel (won't help with rotated sprites though.. hmm) + + var imageData = PixelUtils.pixelContext.getImageData(0, 0, 1, 1); + + return ColorUtils.getColor32(imageData.data[3], imageData.data[0], imageData.data[1], imageData.data[2]); + + } + + } + +} \ No newline at end of file diff --git a/README.md b/README.md index c3a4489c8..74f0a4785 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,9 @@ V1.0.0 * Added Group.swap(a,b) to swap the z-index of 2 objects with optional rendering update boolean * Sprites dispatch killed/revived and added to and removed from Group events. * Added Input drag, bounds, sprite bounds and snapping support. +* Added the new ColorUtils class full of lots of handy color manipulation functions. +* Fixed issue in Camera.inCamera check where it wouldn't take into consideration the Sprites scrollFactor. + V0.9.6 diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 67aec3152..3e9c47aa1 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -88,6 +88,14 @@ drag sprite 2.ts + + + + motion lock 2.ts + + + motion lock.ts + over sprite 1.ts @@ -96,9 +104,17 @@ over sprite 2.ts + + + snap 1.ts + touch priority.ts + + + world drag.ts + graphic emitter.ts diff --git a/Tests/assets/sprites/parsec.png b/Tests/assets/sprites/parsec.png new file mode 100644 index 0000000000000000000000000000000000000000..a3af6d71149dd1170aa9b30337ae8fcab46183a7 GIT binary patch literal 6409 zcmV+k8TRIhP)7 zp$WjepZE9o&BMb(_q^{vel)l>aJ6<#?aRYMKdkSE!{+Nz*uQ@Ln$(@RIiX=g*VJA>>On0S>-z&h^KSAKlN-<9#r! z_XNaikpTO3n#-$nwV4Y5pmn?b{lruPt{&uU*#q=QM&K={rmT#_mcY% zlhJB&-*PWAssi9pc)D;&(R)h&(F{O{Q^EIKUWH7@SDMR z#{Fw)hA>GjXbpt}|L|wlns*lioCmrw;MPpV8QSOF?t@oc0L3x^S-4oRM5uCMrOiwJ z>|6)<7+2OBQ-CW47eC(;4E5DrH>}vC^-?pY@N?m_Ak;bE zQTk4<0w(<5f>@^=yu9=p7G5V~1(0a%s1zo#J_2O9PuYBBzaDGaOTf(A#${<=kIhu9 z!vy4k!ow2`#Yv0B8zPPc@57!i7Wa>MmI%uB@Lkp$^!%9|dUK!0iD*<6eKC7W-ViYLHdxYSL z17EV@Qw>S048KjLc{t?S?K(JqhG<(UKNc@0?707)0VxX}9ANRHkTHmIqOHt7&Tq5w z0xg)u(s5GY8yi?n;~EMp(U1bHcw*{78xvN#v`me#ib1RQ!+1hJLP|tT)6EGYc&!`v z0Iiz#dgg+U8%%4t57F?)@`3SZvWbn~r$~)x;JOf2ECetOE`e3;W?-pri|;!IE-}I6 zwO&TN<>z9b7)UU zqU$xcCGJ`GH_wyT-R@%uz_zypsyoN`#IRz!pM}qY)e}VmJ>C~e`A451F~~`AI-+twx6|XMr&Qba;{ipM5cx$?p~d#s7n+BR901lSbhtKvn^Oz zW{sFF0G5Uoez(ld*h-~WDQ(KkVN&Ego@(7f5iu2YN`#fO^#Lnev*GnajpCrJReEua@U6Db7 zigSu&avwq#y{?i`1EjQ*d5-HfwBGVL4&~GFM`i$)uQ$mw*}wPjl1To~_xDd%2`&I@ zr}qAJj=tbz7lDx9Ibjfv_Kos$#bA~4$5?)uPRkOZb0*&)2pF$>56Q1yF+utJoNxl7 z`m0gQ&${xV7h+O~ziO=9qA{V=+OUR7CNj1HFBy5jYj^zT5V}{g{@)7%G^;TcpP!yS z?hRP+B$vsLNFH~Zye0=$x+W5Y3H~nmJC{9SKUxRXqqgT&DeZ-zk^+9&EjF1#N{6nF zFr)+v*OD(ar%Pbf+Op>2u{FBTpI!hQe;9!AEKyj;ZO7$o99?HJOIU}A+-7j+ghTPjy;9=lucTMbf zv0^y7sNwY%<|zEYsR&~=;1XbQhs3n2(yVjuaj#k@{4FtI&Y5hU#x>T8y+$}$_kjOn za-(S9(DyC9?q`JJ6CJDOCG^$^o=bNdpnlp;9Q00iztNbdw5~Ajm`bz>q_apg*m{qt4zHcF&roe*ZQvO? z2l%s*jJk8a!v5}bv5IM3i+~HjvLb{!vR4`vD%~d+gBOGa$*egUz@^|C3aBNuC#ynd z4wNhiX&6agd(Qcs6LN+$jPYEpX7FUoaH!&;wbnc3!{hW8*1ArBWf+Jxy=Y6C1Q>g}3syTU;I&&g=I*C{M6?Lz2e3Tb!Kw&()G?h@0 zaMEk=;jO)W{``6KU=`O#JkO}U%yWNF8*Ug>p9U_D=p$OSR7nlgfQ3qDp~zY zOoLQ*b__Ze#Jscdu=>;ps2n)ON(!fd7E5j5ikw)*y(*(t|4g+FDA$A^GG}GJaGCBk zHta#<#Tz?Dc1knU5#pR^JyMu{?f1)oDe3$O8p_N+FSMs))k7tfOt6E?La4S@&DyO?u+ zJ0-9l9D&URPp-h}Gw1YcI8x~y6Q-SsxxO{LpFF1v_a1>Irp{cD8UiPM<+|h^)IH6| z(}bX94)H_fJXZiGeXYk^gZI)1+?3BB0!wQ$r9zdX>GWH8 zaw9c#B8->$j=ESSzBb-wG&Zz`_?${iIz3L_DmpfZ5w!*EOC9Ry?>WuIF-*l8i$7ux z10?;<6ZsqUwTxA)80L^eg0b-9b91)*jAAOLOu}5>N$$WG!zu$}e2lxNZAAMZgnGpp znd_rTX-reV$ph08J~qjeN0U8@@_*5!a!WY#>(^u|YKQflumzAjIOX)?3z_qmekazv zy5ryGs1D(2STVsH>Zd|Fg6G#j_BwAHz^2XqdVKAP79|dLI`{68O5pH!%n@p64qgtL z7iF6ZPBreIMAd+y&T4V|CQZc>p}c~ofiM_Qz94pEHpHrkRnRSg)?jcUt>M8qTwn@^ zy4;j#G~Nn;Lnj16T=wPc8dO|97x833qoZMs2`koQ_%I8!u25j; z{BFQ#uija0D87chf?cVb0HYHJZU7kjt8g!zf8tH%*u?bmoN|3mt)0(}Y!FmpDx%8k zP`?!WcJAuPG@tdgNFE~a8sh7+pe23sc4P|&*;0pRY{vlBRA~xk$eUIS9)wNq zXA9)WnZBor4ZPwYOJ4iFawAna8keO#wN_?o!q?)N;k88;b@bK8xiM=GPMP;AveY)nx&!u8Og$kjrudh{^Ts;o(dh z+r}L4JL6D^oJ{o&IthDO{9{m?Qzih+v%R-^h5&)AW_;p{PNIxOBw+@2Wn!qaEqKMC zeZRH}rz?k6c4V;v6A{{0Y4r*VT1&};r*)il z$K<8NlgihnVZLs~(DJa{F=gZGi==2`~ zB^t2qJ8U*4ymYz;Uk^7FwW_UUMHUw}6&YHktqV*Mv^HUWE-4R|)|KNn!BKKnlw9w! z(C!mXQhh#ZU|S8Wug4#W;2}gkq>i`H{y9{{@9Qbx_xt}p$9gY;#MvGw4F*|F!T{Ze zGzX@(S51KdgF({+#)HLvGtnZwRiU+I+7d~qrKTdAQ)57j^TC#s2Ub!Z!)K-XOKVZ+ zA8qbiuwoGRJ}!Y4ho$9BU?O?v2ztps# z{?6fBp7b4Rzpi#OgK~a_(7?fB~DEJh5u~MYjpFL3k?<~&4Jm)0(WQwg+i?G8Vo6oXn!#j&APqdYKBbp3qG9Q4l1jKPXOgOgOZ z@_~l}VJr>bd;661B(qFJUR}IFLXH_uI7|eemkXk z%@tY9F%@AR4uMu*)KF0s8XCG83$G~X zcrLGuzq88BgDXGsK3Hw!d2)phfZVCAnYf=Ds!Mci&hk+21tzs z74Ptk*#D=1gY>(M4eCCn0z>>gib~wfplJ;Smp&?O4f3!VSTK?szQZhKZ6?#Wlr68} zhQWco4o9O5B37sSP&)ZwWCUYiPTtC336ZGHPZ1c!3iailP&3z2@->|hJ(l@B<;Ha{ zR6j>Q)+!G}T8UX`f(ymO+%2ZiOj2k-pYUh&LyV~m7W24?akY)KKcBsAduqCn>EQp&irLZ{}5oEfGf4qc^ZUe-lX<3rp&JX zxuh1e{q9X{PP)?_&#Mk^?2f%ZJA5tB^7Ah-+ge$hdE69UUk};RHWsLO9($l(g*;@; zUp5Ob0agz#IlJuhX7e#c71P+s!>JnV=qP}d&*8-LRo#X66L-;32^4W_aD zTCGJK(=%tdPYErnqHRpzF;~|t51ve4Y8JZAd4boLySoovKWZ)?LCl_yO>*R_Nau4n z7>>#AxbHByR%UU`$AW=&oH6D-S@yqohMec`tJ$QP8eHQ1g$6KoiQ_R$_SoM`^3sM> zx2-`QT;(P>|1Gm{XldpwaDjwh9v(h)dj1$-vbJ-W>Tu+Jkd=EjQI5|OyPH9Sfy4@f zQ+$Rvfw9#hbuf54w0a|n4GjAKhHP^gL9b8fhso3AwBo7EyjICvv z;OgOZG#g9c6+6|&>U2wpy^${{mqgIgR7w}e-uIQPODZDfKhKmfA zo``+RelBEp3$&I<>dh$A+}{`StcSJY!;|W@{nS}YaNNSr-9;*<3Yp9pmSKfLDGYP+TA=*u@G~v zpG)^+gH}GYJO~X1($c4O7i(NrvA#9PgD@f#I^>hLc52=WYwiq)mBMTbIB`cDjItVD zZdR^cpQ^uP33e>&7f}-{`h+qkyoZZdpSMtB=ucQ(cyMwC%F_^X&Ba@W7(?r>;Dnl7 zKhib(32T*yzTaU*10r{?OdodWQgkb4K9y+nx6rDT2gA&dL5$~v1{lMO zA!dEnr;lKF4iPFol(GbHR?5KHK^dWOMMa&>%LfAR3d5hXqtj0`NbsKDjsyJj<)wdL zL|XQ|YS0e-m!rmj6%5x~gVNFv9J;X93_!?1Ecv!Nc_ea8sjyrCuQPC20PCs~ikcssYyF$6g7=fPaMY7^Fn~S~zzZ%*{<`PmaXT|H373EC}z#q(c~e(s&uZi=HzXx z9#So0Fu2A59Rtssl&NgpArQ-j)h@ADbL_!rEq}h`E|Av%Ok8taE~NlV!OF_7T6&Jp z2Cku#)dX4OM3iVWBerTeD@ub=17;1tj9Dihcm~OX1FPERe^ubhnM~a2ScOU*>g-6b zZ6#@~wGtmQTO~2eq|`rFyDY2%TsZ@pqm2Pn_&>w2fvUB&&VQ}_oxp5>Jgh+${wKfy XvGyC$9In<<00000NkvXXu0mjf9~)nH literal 0 HcmV?d00001 diff --git a/Tests/input/motion lock 2.js b/Tests/input/motion lock 2.js new file mode 100644 index 000000000..73669aebc --- /dev/null +++ b/Tests/input/motion lock 2.js @@ -0,0 +1,26 @@ +/// +(function () { + var game = new Phaser.Game(this, 'game', 800, 600, init, create, null, render); + function init() { + // Using Phasers asset loader we load up a PNG from the assets folder + game.loader.addImageFile('sprite', 'assets/sprites/darkwing_crazy.png'); + game.loader.load(); + } + var sprite; + function create() { + game.stage.backgroundColor = 'rgb(85,85,85)'; + sprite = game.add.sprite(200, 200, 'sprite'); + // Enable Input detection. Sprites have this disabled by default, + // so you have to start it if you want to interact with them. + sprite.input.start(0, false, true); + // This allows you to drag the sprite. The parameter controls if you drag from the position you touched it (false) + // or if it will snap to the center (true) + sprite.input.enableDrag(); + // This will lock the sprite so it can only be dragged vertically, not horizontally + sprite.input.allowHorizontalDrag = false; + } + function render() { + game.input.renderDebugInfo(32, 32); + sprite.input.renderDebugInfo(300, 32); + } +})(); diff --git a/Tests/input/motion lock 2.ts b/Tests/input/motion lock 2.ts new file mode 100644 index 000000000..dc22bad97 --- /dev/null +++ b/Tests/input/motion lock 2.ts @@ -0,0 +1,43 @@ +/// + +(function () { + + var game = new Phaser.Game(this, 'game', 800, 600, init, create, null, render); + + function init() { + + // Using Phasers asset loader we load up a PNG from the assets folder + game.loader.addImageFile('sprite', 'assets/sprites/darkwing_crazy.png'); + game.loader.load(); + + } + + var sprite: Phaser.Sprite; + + function create() { + + game.stage.backgroundColor = 'rgb(85,85,85)'; + + sprite = game.add.sprite(200, 200, 'sprite'); + + // Enable Input detection. Sprites have this disabled by default, + // so you have to start it if you want to interact with them. + sprite.input.start(0, false, true); + + // This allows you to drag the sprite. The parameter controls if you drag from the position you touched it (false) + // or if it will snap to the center (true) + sprite.input.enableDrag(); + + // This will lock the sprite so it can only be dragged vertically, not horizontally + sprite.input.allowHorizontalDrag = false; + + } + + function render() { + + game.input.renderDebugInfo(32, 32); + sprite.input.renderDebugInfo(300, 32); + + } + +})(); diff --git a/Tests/input/motion lock.js b/Tests/input/motion lock.js new file mode 100644 index 000000000..b0d7b52ac --- /dev/null +++ b/Tests/input/motion lock.js @@ -0,0 +1,26 @@ +/// +(function () { + var game = new Phaser.Game(this, 'game', 800, 600, init, create, null, render); + function init() { + // Using Phasers asset loader we load up a PNG from the assets folder + game.loader.addImageFile('sprite', 'assets/sprites/parsec.png'); + game.loader.load(); + } + var sprite; + function create() { + game.stage.backgroundColor = 'rgb(85,85,85)'; + sprite = game.add.sprite(200, 400, 'sprite'); + // Enable Input detection. Sprites have this disabled by default, + // so you have to start it if you want to interact with them. + sprite.input.start(0, false, true); + // This allows you to drag the sprite. The parameter controls if you drag from the position you touched it (false) + // or if it will snap to the center (true) + sprite.input.enableDrag(); + // This will lock the sprite so it can only be dragged horizontally, not vertically + sprite.input.allowVerticalDrag = false; + } + function render() { + game.input.renderDebugInfo(32, 32); + sprite.input.renderDebugInfo(300, 32); + } +})(); diff --git a/Tests/input/motion lock.ts b/Tests/input/motion lock.ts new file mode 100644 index 000000000..3d7c2cce8 --- /dev/null +++ b/Tests/input/motion lock.ts @@ -0,0 +1,43 @@ +/// + +(function () { + + var game = new Phaser.Game(this, 'game', 800, 600, init, create, null, render); + + function init() { + + // Using Phasers asset loader we load up a PNG from the assets folder + game.loader.addImageFile('sprite', 'assets/sprites/parsec.png'); + game.loader.load(); + + } + + var sprite: Phaser.Sprite; + + function create() { + + game.stage.backgroundColor = 'rgb(85,85,85)'; + + sprite = game.add.sprite(200, 400, 'sprite'); + + // Enable Input detection. Sprites have this disabled by default, + // so you have to start it if you want to interact with them. + sprite.input.start(0, false, true); + + // This allows you to drag the sprite. The parameter controls if you drag from the position you touched it (false) + // or if it will snap to the center (true) + sprite.input.enableDrag(); + + // This will lock the sprite so it can only be dragged horizontally, not vertically + sprite.input.allowVerticalDrag = false; + + } + + function render() { + + game.input.renderDebugInfo(32, 32); + sprite.input.renderDebugInfo(300, 32); + + } + +})(); diff --git a/Tests/input/snap 1.js b/Tests/input/snap 1.js new file mode 100644 index 000000000..9e64b8de3 --- /dev/null +++ b/Tests/input/snap 1.js @@ -0,0 +1,33 @@ +/// +(function () { + var game = new Phaser.Game(this, 'game', 800, 600, init, create, null, render); + function init() { + // Using Phasers asset loader we load up a PNG from the assets folder + game.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png'); + game.loader.addImageFile('atari1', 'assets/sprites/atari130xe.png'); + game.loader.addImageFile('atari2', 'assets/sprites/atari800xl.png'); + game.loader.load(); + } + var atari1; + var atari2; + var sonic; + function create() { + game.add.sprite(0, 0, 'grid'); + atari1 = game.add.sprite(128, 128, 'atari1'); + atari2 = game.add.sprite(256, 256, 'atari2'); + // Input Enable the sprites + atari1.input.start(0, false, true); + atari2.input.start(1, false, true); + // Allow dragging + atari1.input.enableDrag(); + atari2.input.enableDrag(); + // Enable snapping. For the atari1 sprite it will snap as its dragged around and on release. + // The snap is set to every 32x32 pixels. + atari1.input.enableSnap(32, 32, true, true); + // For the atari2 sprite it will snap only when released, not on drag. + atari2.input.enableSnap(32, 32, false, true); + } + function render() { + game.input.renderDebugInfo(32, 32); + } +})(); diff --git a/Tests/input/snap 1.ts b/Tests/input/snap 1.ts new file mode 100644 index 000000000..0dc624775 --- /dev/null +++ b/Tests/input/snap 1.ts @@ -0,0 +1,49 @@ +/// + +(function () { + + var game = new Phaser.Game(this, 'game', 800, 600, init, create, null, render); + + function init() { + + // Using Phasers asset loader we load up a PNG from the assets folder + game.loader.addImageFile('grid', 'assets/tests/debug-grid-1920x1920.png'); + game.loader.addImageFile('atari1', 'assets/sprites/atari130xe.png'); + game.loader.addImageFile('atari2', 'assets/sprites/atari800xl.png'); + game.loader.load(); + + } + + var atari1: Phaser.Sprite; + var atari2: Phaser.Sprite; + var sonic: Phaser.Sprite; + + function create() { + + game.add.sprite(0, 0, 'grid'); + + atari1 = game.add.sprite(128, 128, 'atari1'); + atari2 = game.add.sprite(256, 256, 'atari2'); + + // Input Enable the sprites + atari1.input.start(0, false, true); + atari2.input.start(1, false, true); + + // Allow dragging + atari1.input.enableDrag(); + atari2.input.enableDrag(); + + // Enable snapping. For the atari1 sprite it will snap as its dragged around and on release. + // The snap is set to every 32x32 pixels. + atari1.input.enableSnap(32, 32, true, true); + + // For the atari2 sprite it will snap only when released, not on drag. + atari2.input.enableSnap(32, 32, false, true); + + } + + function render() { + game.input.renderDebugInfo(32, 32); + } + +})(); diff --git a/Tests/input/world drag.js b/Tests/input/world drag.js new file mode 100644 index 000000000..46c0779b2 --- /dev/null +++ b/Tests/input/world drag.js @@ -0,0 +1,36 @@ +/// +(function () { + var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); + function init() { + game.world.setSize(1920, 1200, true); + game.loader.addImageFile('backdrop', 'assets/pics/remember-me.jpg'); + game.loader.addImageFile('melon', 'assets/sprites/melon.png'); + game.loader.load(); + } + function create() { + game.add.sprite(0, 0, 'backdrop'); + for(var i = 0; i < 1; i++) { + //var sprite: Phaser.Sprite = game.add.sprite(game.world.randomX, game.world.randomY, 'melon'); + var sprite = game.add.sprite(200, 200, 'melon'); + sprite.scrollFactor.setTo(2, 2); + sprite.scale.setTo(2, 2); + sprite.input.start(i, false, true); + sprite.input.enableDrag(); + } + } + function update() { + if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { + game.camera.scroll.x -= 4; + } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { + game.camera.scroll.x += 4; + } + if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) { + game.camera.scroll.y -= 4; + } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { + game.camera.scroll.y += 4; + } + } + function render() { + game.camera.renderDebugInfo(32, 32); + } +})(); diff --git a/Tests/input/world drag.ts b/Tests/input/world drag.ts new file mode 100644 index 000000000..b17ea12f8 --- /dev/null +++ b/Tests/input/world drag.ts @@ -0,0 +1,59 @@ +/// + +(function () { + + var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); + + function init() { + + game.world.setSize(1920, 1200, true); + + game.loader.addImageFile('backdrop', 'assets/pics/remember-me.jpg'); + game.loader.addImageFile('melon', 'assets/sprites/melon.png'); + + game.loader.load(); + + } + + function create() { + + game.add.sprite(0, 0, 'backdrop'); + + for (var i = 0; i < 1; i++) + { + var sprite: Phaser.Sprite = game.add.sprite(game.world.randomX, game.world.randomY, 'melon'); + sprite.input.start(i, false, true); + sprite.input.enableDrag(); + } + + } + + function update() { + + if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + { + game.camera.scroll.x -= 4; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + { + game.camera.scroll.x += 4; + } + + if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + { + game.camera.scroll.y -= 4; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) + { + game.camera.scroll.y += 4; + } + + } + + function render() { + + game.camera.renderDebugInfo(32, 32); + + } + +})(); diff --git a/Tests/phaser.js b/Tests/phaser.js index 379d16ac9..c744697ca 100644 --- a/Tests/phaser.js +++ b/Tests/phaser.js @@ -4890,7 +4890,476 @@ var Phaser; Phaser.RectangleUtils = RectangleUtils; })(Phaser || (Phaser = {})); /// +/// +/// +/// +/** +* Phaser - ColorUtils +* +* A collection of methods useful for manipulating color values. +*/ +var Phaser; +(function (Phaser) { + var ColorUtils = (function () { + function ColorUtils() { } + ColorUtils.getColor32 = /** + * Given an alpha and 3 color values this will return an integer representation of it + * + * @param alpha {number} The Alpha value (between 0 and 255) + * @param red {number} The Red channel value (between 0 and 255) + * @param green {number} The Green channel value (between 0 and 255) + * @param blue {number} The Blue channel value (between 0 and 255) + * + * @return A native color value integer (format: 0xAARRGGBB) + */ + function getColor32(alpha, red, green, blue) { + return alpha << 24 | red << 16 | green << 8 | blue; + }; + ColorUtils.getColor = /** + * Given 3 color values this will return an integer representation of it + * + * @param red {number} The Red channel value (between 0 and 255) + * @param green {number} The Green channel value (between 0 and 255) + * @param blue {number} The Blue channel value (between 0 and 255) + * + * @return A native color value integer (format: 0xRRGGBB) + */ + function getColor(red, green, blue) { + return red << 16 | green << 8 | blue; + }; + ColorUtils.getHSVColorWheel = /** + * Get HSV color wheel values in an array which will be 360 elements in size + * + * @param alpha Alpha value for each color of the color wheel, between 0 (transparent) and 255 (opaque) + * + * @return Array + */ + function getHSVColorWheel(alpha) { + if (typeof alpha === "undefined") { alpha = 255; } + var colors = []; + for(var c = 0; c <= 359; c++) { + //colors[c] = HSVtoRGB(c, 1.0, 1.0, alpha); + colors[c] = ColorUtils.getWebRGB(ColorUtils.HSVtoRGB(c, 1.0, 1.0, alpha)); + } + return colors; + }; + ColorUtils.getComplementHarmony = /** + * Returns a Complementary Color Harmony for the given color. + *

A complementary hue is one directly opposite the color given on the color wheel

+ *

Value returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * + * @return 0xAARRGGBB format color value + */ + function getComplementHarmony(color) { + var hsv = ColorUtils.RGBtoHSV(color); + var opposite = ColorUtils.game.math.wrapValue(hsv.hue, 180, 359); + return ColorUtils.HSVtoRGB(opposite, 1.0, 1.0); + }; + ColorUtils.getAnalogousHarmony = /** + * Returns an Analogous Color Harmony for the given color. + *

An Analogous harmony are hues adjacent to each other on the color wheel

+ *

Values returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * @param threshold Control how adjacent the colors will be (default +- 30 degrees) + * + * @return Object containing 3 properties: color1 (the original color), color2 (the warmer analogous color) and color3 (the colder analogous color) + */ + function getAnalogousHarmony(color, threshold) { + if (typeof threshold === "undefined") { threshold = 30; } + var hsv = ColorUtils.RGBtoHSV(color); + if(threshold > 359 || threshold < 0) { + throw Error("Color Warning: Invalid threshold given to getAnalogousHarmony()"); + } + var warmer = ColorUtils.game.math.wrapValue(hsv.hue, 359 - threshold, 359); + var colder = ColorUtils.game.math.wrapValue(hsv.hue, threshold, 359); + return { + color1: color, + color2: ColorUtils.HSVtoRGB(warmer, 1.0, 1.0), + color3: ColorUtils.HSVtoRGB(colder, 1.0, 1.0), + hue1: hsv.hue, + hue2: warmer, + hue3: colder + }; + }; + ColorUtils.getSplitComplementHarmony = /** + * Returns an Split Complement Color Harmony for the given color. + *

A Split Complement harmony are the two hues on either side of the color's Complement

+ *

Values returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * @param threshold Control how adjacent the colors will be to the Complement (default +- 30 degrees) + * + * @return Object containing 3 properties: color1 (the original color), color2 (the warmer analogous color) and color3 (the colder analogous color) + */ + function getSplitComplementHarmony(color, threshold) { + if (typeof threshold === "undefined") { threshold = 30; } + var hsv = ColorUtils.RGBtoHSV(color); + if(threshold >= 359 || threshold <= 0) { + throw Error("FlxColor Warning: Invalid threshold given to getSplitComplementHarmony()"); + } + var opposite = ColorUtils.game.math.wrapValue(hsv.hue, 180, 359); + var warmer = ColorUtils.game.math.wrapValue(hsv.hue, opposite - threshold, 359); + var colder = ColorUtils.game.math.wrapValue(hsv.hue, opposite + threshold, 359); + return { + color1: color, + color2: ColorUtils.HSVtoRGB(warmer, hsv.saturation, hsv.value), + color3: ColorUtils.HSVtoRGB(colder, hsv.saturation, hsv.value), + hue1: hsv.hue, + hue2: warmer, + hue3: colder + }; + }; + ColorUtils.getTriadicHarmony = /** + * Returns a Triadic Color Harmony for the given color. + *

A Triadic harmony are 3 hues equidistant from each other on the color wheel

+ *

Values returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * + * @return Object containing 3 properties: color1 (the original color), color2 and color3 (the equidistant colors) + */ + function getTriadicHarmony(color) { + var hsv = ColorUtils.RGBtoHSV(color); + var triadic1 = ColorUtils.game.math.wrapValue(hsv.hue, 120, 359); + var triadic2 = ColorUtils.game.math.wrapValue(triadic1, 120, 359); + return { + color1: color, + color2: ColorUtils.HSVtoRGB(triadic1, 1.0, 1.0), + color3: ColorUtils.HSVtoRGB(triadic2, 1.0, 1.0) + }; + }; + ColorUtils.getColorInfo = /** + * Returns a string containing handy information about the given color including string hex value, + * RGB format information and HSL information. Each section starts on a newline, 3 lines in total. + * + * @param color A color value in the format 0xAARRGGBB + * + * @return string containing the 3 lines of information + */ + function getColorInfo(color) { + var argb = ColorUtils.getRGB(color); + var hsl = ColorUtils.RGBtoHSV(color); + // Hex format + var result = ColorUtils.RGBtoHexstring(color) + "\n"; + // RGB format + result = result.concat("Alpha: " + argb.alpha + " Red: " + argb.red + " Green: " + argb.green + " Blue: " + argb.blue) + "\n"; + // HSL info + result = result.concat("Hue: " + hsl.hue + " Saturation: " + hsl.saturation + " Lightnes: " + hsl.lightness); + return result; + }; + ColorUtils.RGBtoHexstring = /** + * Return a string representation of the color in the format 0xAARRGGBB + * + * @param color The color to get the string representation for + * + * @return A string of length 10 characters in the format 0xAARRGGBB + */ + function RGBtoHexstring(color) { + var argb = ColorUtils.getRGB(color); + return "0x" + ColorUtils.colorToHexstring(argb.alpha) + ColorUtils.colorToHexstring(argb.red) + ColorUtils.colorToHexstring(argb.green) + ColorUtils.colorToHexstring(argb.blue); + }; + ColorUtils.RGBtoWebstring = /** + * Return a string representation of the color in the format #RRGGBB + * + * @param color The color to get the string representation for + * + * @return A string of length 10 characters in the format 0xAARRGGBB + */ + function RGBtoWebstring(color) { + var argb = ColorUtils.getRGB(color); + return "#" + ColorUtils.colorToHexstring(argb.red) + ColorUtils.colorToHexstring(argb.green) + ColorUtils.colorToHexstring(argb.blue); + }; + ColorUtils.colorToHexstring = /** + * Return a string containing a hex representation of the given color + * + * @param color The color channel to get the hex value for, must be a value between 0 and 255) + * + * @return A string of length 2 characters, i.e. 255 = FF, 0 = 00 + */ + function colorToHexstring(color) { + var digits = "0123456789ABCDEF"; + var lsd = color % 16; + var msd = (color - lsd) / 16; + var hexified = digits.charAt(msd) + digits.charAt(lsd); + return hexified; + }; + ColorUtils.HSVtoRGB = /** + * Convert a HSV (hue, saturation, lightness) color space value to an RGB color + * + * @param h Hue degree, between 0 and 359 + * @param s Saturation, between 0.0 (grey) and 1.0 + * @param v Value, between 0.0 (black) and 1.0 + * @param alpha Alpha value to set per color (between 0 and 255) + * + * @return 32-bit ARGB color value (0xAARRGGBB) + */ + function HSVtoRGB(h, s, v, alpha) { + if (typeof alpha === "undefined") { alpha = 255; } + var result; + if(s == 0.0) { + result = ColorUtils.getColor32(alpha, v * 255, v * 255, v * 255); + } else { + h = h / 60.0; + var f = h - Math.floor(h); + var p = v * (1.0 - s); + var q = v * (1.0 - s * f); + var t = v * (1.0 - s * (1.0 - f)); + switch(Math.floor(h)) { + case 0: + result = ColorUtils.getColor32(alpha, v * 255, t * 255, p * 255); + break; + case 1: + result = ColorUtils.getColor32(alpha, q * 255, v * 255, p * 255); + break; + case 2: + result = ColorUtils.getColor32(alpha, p * 255, v * 255, t * 255); + break; + case 3: + result = ColorUtils.getColor32(alpha, p * 255, q * 255, v * 255); + break; + case 4: + result = ColorUtils.getColor32(alpha, t * 255, p * 255, v * 255); + break; + case 5: + result = ColorUtils.getColor32(alpha, v * 255, p * 255, q * 255); + break; + default: + throw new Error("ColorUtils.HSVtoRGB : Unknown color"); + } + } + return result; + }; + ColorUtils.RGBtoHSV = /** + * Convert an RGB color value to an object containing the HSV color space values: Hue, Saturation and Lightness + * + * @param color In format 0xRRGGBB + * + * @return Object with the properties hue (from 0 to 360), saturation (from 0 to 1.0) and lightness (from 0 to 1.0, also available under .value) + */ + function RGBtoHSV(color) { + var rgb = ColorUtils.getRGB(color); + var red = rgb.red / 255; + var green = rgb.green / 255; + var blue = rgb.blue / 255; + var min = Math.min(red, green, blue); + var max = Math.max(red, green, blue); + var delta = max - min; + var lightness = (max + min) / 2; + var hue; + var saturation; + // Grey color, no chroma + if(delta == 0) { + hue = 0; + saturation = 0; + } else { + if(lightness < 0.5) { + saturation = delta / (max + min); + } else { + saturation = delta / (2 - max - min); + } + var delta_r = (((max - red) / 6) + (delta / 2)) / delta; + var delta_g = (((max - green) / 6) + (delta / 2)) / delta; + var delta_b = (((max - blue) / 6) + (delta / 2)) / delta; + if(red == max) { + hue = delta_b - delta_g; + } else if(green == max) { + hue = (1 / 3) + delta_r - delta_b; + } else if(blue == max) { + hue = (2 / 3) + delta_g - delta_r; + } + if(hue < 0) { + hue += 1; + } + if(hue > 1) { + hue -= 1; + } + } + // Keep the value with 0 to 359 + hue *= 360; + hue = Math.round(hue); + return { + hue: hue, + saturation: saturation, + lightness: lightness, + value: lightness + }; + }; + ColorUtils.interpolateColor = /** + * + * @method interpolateColor + * @param {Number} color1 + * @param {Number} color2 + * @param {Number} steps + * @param {Number} currentStep + * @param {Number} alpha + * @return {Number} + * @static + */ + function interpolateColor(color1, color2, steps, currentStep, alpha) { + if (typeof alpha === "undefined") { alpha = 255; } + var src1 = ColorUtils.getRGB(color1); + var src2 = ColorUtils.getRGB(color2); + var r = (((src2.red - src1.red) * currentStep) / steps) + src1.red; + var g = (((src2.green - src1.green) * currentStep) / steps) + src1.green; + var b = (((src2.blue - src1.blue) * currentStep) / steps) + src1.blue; + return ColorUtils.getColor32(alpha, r, g, b); + }; + ColorUtils.interpolateColorWithRGB = /** + * + * @method interpolateColorWithRGB + * @param {Number} color + * @param {Number} r2 + * @param {Number} g2 + * @param {Number} b2 + * @param {Number} steps + * @param {Number} currentStep + * @return {Number} + * @static + */ + function interpolateColorWithRGB(color, r2, g2, b2, steps, currentStep) { + var src = ColorUtils.getRGB(color); + var r = (((r2 - src.red) * currentStep) / steps) + src.red; + var g = (((g2 - src.green) * currentStep) / steps) + src.green; + var b = (((b2 - src.blue) * currentStep) / steps) + src.blue; + return ColorUtils.getColor(r, g, b); + }; + ColorUtils.interpolateRGB = /** + * + * @method interpolateRGB + * @param {Number} r1 + * @param {Number} g1 + * @param {Number} b1 + * @param {Number} r2 + * @param {Number} g2 + * @param {Number} b2 + * @param {Number} steps + * @param {Number} currentStep + * @return {Number} + * @static + */ + function interpolateRGB(r1, g1, b1, r2, g2, b2, steps, currentStep) { + var r = (((r2 - r1) * currentStep) / steps) + r1; + var g = (((g2 - g1) * currentStep) / steps) + g1; + var b = (((b2 - b1) * currentStep) / steps) + b1; + return ColorUtils.getColor(r, g, b); + }; + ColorUtils.getRandomColor = /** + * Returns a random color value between black and white + *

Set the min value to start each channel from the given offset.

+ *

Set the max value to restrict the maximum color used per channel

+ * + * @param min The lowest value to use for the color + * @param max The highest value to use for the color + * @param alpha The alpha value of the returning color (default 255 = fully opaque) + * + * @return 32-bit color value with alpha + */ + function getRandomColor(min, max, alpha) { + if (typeof min === "undefined") { min = 0; } + if (typeof max === "undefined") { max = 255; } + if (typeof alpha === "undefined") { alpha = 255; } + // Sanity checks + if(max > 255) { + return ColorUtils.getColor(255, 255, 255); + } + if(min > max) { + return ColorUtils.getColor(255, 255, 255); + } + var red = min + Math.round(Math.random() * (max - min)); + var green = min + Math.round(Math.random() * (max - min)); + var blue = min + Math.round(Math.random() * (max - min)); + return ColorUtils.getColor32(alpha, red, green, blue); + }; + ColorUtils.getRGB = /** + * Return the component parts of a color as an Object with the properties alpha, red, green, blue + * + *

Alpha will only be set if it exist in the given color (0xAARRGGBB)

+ * + * @param color in RGB (0xRRGGBB) or ARGB format (0xAARRGGBB) + * + * @return Object with properties: alpha, red, green, blue + */ + function getRGB(color) { + return { + alpha: color >>> 24, + red: color >> 16 & 0xFF, + green: color >> 8 & 0xFF, + blue: color & 0xFF + }; + }; + ColorUtils.getWebRGB = /** + * + * @method getWebRGB + * @param {Number} color + * @return {Any} + */ + function getWebRGB(color) { + var alpha = (color >>> 24) / 255; + var red = color >> 16 & 0xFF; + var green = color >> 8 & 0xFF; + var blue = color & 0xFF; + return 'rgba(' + red.toString() + ',' + green.toString() + ',' + blue.toString() + ',' + alpha.toString() + ')'; + }; + ColorUtils.getAlpha = /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Alpha component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Alpha component of the color, will be between 0 and 255 (0 being no Alpha, 255 full Alpha) + */ + function getAlpha(color) { + return color >>> 24; + }; + ColorUtils.getAlphaFloat = /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Alpha component as a value between 0 and 1 + * + * @param color In the format 0xAARRGGBB + * + * @return The Alpha component of the color, will be between 0 and 1 (0 being no Alpha (opaque), 1 full Alpha (transparent)) + */ + function getAlphaFloat(color) { + return (color >>> 24) / 255; + }; + ColorUtils.getRed = /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Red component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Red component of the color, will be between 0 and 255 (0 being no color, 255 full Red) + */ + function getRed(color) { + return color >> 16 & 0xFF; + }; + ColorUtils.getGreen = /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Green component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Green component of the color, will be between 0 and 255 (0 being no color, 255 full Green) + */ + function getGreen(color) { + return color >> 8 & 0xFF; + }; + ColorUtils.getBlue = /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Blue component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Blue component of the color, will be between 0 and 255 (0 being no color, 255 full Blue) + */ + function getBlue(color) { + return color & 0xFF; + }; + return ColorUtils; + })(); + Phaser.ColorUtils = ColorUtils; +})(Phaser || (Phaser = {})); +/// /// +/// /// /** * Phaser - DynamicTexture @@ -4940,7 +5409,7 @@ var Phaser; //b = imageData.data[2]; //a = imageData.data[3]; var imageData = this.context.getImageData(x, y, 1, 1); - return this.getColor(imageData.data[0], imageData.data[1], imageData.data[2]); + return Phaser.ColorUtils.getColor(imageData.data[0], imageData.data[1], imageData.data[2]); }; DynamicTexture.prototype.getPixel32 = /** * Get a color of a specific pixel (including alpha value). @@ -4950,7 +5419,7 @@ var Phaser; */ function (x, y) { var imageData = this.context.getImageData(x, y, 1, 1); - return this.getColor32(imageData.data[3], imageData.data[0], imageData.data[1], imageData.data[2]); + return Phaser.ColorUtils.getColor32(imageData.data[3], imageData.data[0], imageData.data[1], imageData.data[2]); }; DynamicTexture.prototype.getPixels = /** * Get pixels in array in a specific rectangle. @@ -5101,31 +5570,6 @@ var Phaser; enumerable: true, configurable: true }); - DynamicTexture.prototype.getColor32 = /** - * Given an alpha and 3 color values this will return an integer representation of it - * - * @param alpha {number} The Alpha value (between 0 and 255) - * @param red {number} The Red channel value (between 0 and 255) - * @param green {number} The Green channel value (between 0 and 255) - * @param blue {number} The Blue channel value (between 0 and 255) - * - * @return A native color value integer (format: 0xAARRGGBB) - */ - function (alpha, red, green, blue) { - return alpha << 24 | red << 16 | green << 8 | blue; - }; - DynamicTexture.prototype.getColor = /** - * Given 3 color values this will return an integer representation of it - * - * @param red {number} The Red channel value (between 0 and 255) - * @param green {number} The Green channel value (between 0 and 255) - * @param blue {number} The Blue channel value (between 0 and 255) - * - * @return A native color value integer (format: 0xRRGGBB) - */ - function (red, green, blue) { - return red << 16 | green << 8 | blue; - }; return DynamicTexture; })(); Phaser.DynamicTexture = DynamicTexture; @@ -7289,6 +7733,10 @@ var Phaser; if(this.alpha !== 1) { this._game.stage.context.globalAlpha = 1; } + // Debug test + this._game.stage.context.fillStyle = 'rgba(255,0,0,0.3)'; + //this._game.stage.context.fillRect(this.scaledX, this.scaledY, this.worldView.width, this.worldView.height); + this._game.stage.context.fillRect(this.worldView.x, this.worldView.y, this.worldView.width, this.worldView.height); }; Camera.prototype.setPosition = /** * Set position of this camera. @@ -13544,7 +13992,6 @@ var Phaser; } } } - //console.log('highest priority was', _highestPriority); if(this.isDown) { // Now update all objects with the highest priority ID (can be more than 1) for(var i = 0; i < this.game.input.totalTrackedObjects; i++) { @@ -15029,11 +15476,11 @@ var Phaser; if(sprite.scrollFactor.x == 0 && sprite.scrollFactor.y == 0) { return true; } - this._dx = sprite.frameBounds.x - camera.worldView.x; - this._dy = sprite.frameBounds.y - camera.worldView.y; + this._dx = sprite.frameBounds.x - (camera.worldView.x * sprite.scrollFactor.x); + this._dy = sprite.frameBounds.y - (camera.worldView.y * sprite.scrollFactor.y); this._dw = sprite.frameBounds.width * sprite.scale.x; this._dh = sprite.frameBounds.height * sprite.scale.y; - return (camera.worldView.right > this._dx) && (camera.worldView.x < this._dx + this._dw) && (camera.worldView.bottom > this._dy) && (camera.worldView.y < this._dy + this._dh); + return (camera.scaledX + camera.worldView.width > this._dx) && (camera.scaledX < this._dx + this._dw) && (camera.scaledY + camera.worldView.height > this._dy) && (camera.scaledY < this._dy + this._dh); }; CanvasRenderer.prototype.renderSprite = /** * Render this sprite to specific camera. Called by game loop after update(). @@ -15042,6 +15489,7 @@ var Phaser; */ function (camera, sprite) { if(sprite.scale.x == 0 || sprite.scale.y == 0 || sprite.texture.alpha < 0.1 || this.inCamera(camera, sprite) == false) { + console.log('out of camera', sprite.frameBounds.x, sprite.frameBounds.y, sprite.frameBounds.width, sprite.frameBounds.height); return false; } this._count++; @@ -15412,6 +15860,8 @@ var Phaser; this.input.boot(); this.framerate = 60; this.isBooted = true; + // Set-up some static helper references + Phaser.ColorUtils.game = this; // Display the default game screen? if(this.onInitCallback == null && this.onCreateCallback == null && this.onUpdateCallback == null && this.onRenderCallback == null && this._pendingState == null) { this._raf = new Phaser.RequestAnimationFrame(this, this.bootLoop); @@ -15799,6 +16249,34 @@ var Phaser; Phaser.Polygon = Polygon; })(Phaser || (Phaser = {})); /// +/// +/// +/// +/** +* Phaser - PixelUtils +* +* A collection of methods useful for manipulating pixels. +*/ +var Phaser; +(function (Phaser) { + var PixelUtils = (function () { + function PixelUtils() { } + PixelUtils.boot = function boot() { + PixelUtils.pixelCanvas = document.createElement('canvas'); + PixelUtils.pixelCanvas.width = 1; + PixelUtils.pixelCanvas.height = 1; + PixelUtils.pixelContext = PixelUtils.pixelCanvas.getContext('2d'); + }; + PixelUtils.getPixel = function getPixel(key, x, y) { + // write out a single pixel (won't help with rotated sprites though.. hmm) + var imageData = PixelUtils.pixelContext.getImageData(0, 0, 1, 1); + return Phaser.ColorUtils.getColor32(imageData.data[3], imageData.data[0], imageData.data[1], imageData.data[2]); + }; + return PixelUtils; + })(); + Phaser.PixelUtils = PixelUtils; +})(Phaser || (Phaser = {})); +/// /** * Phaser - Line * diff --git a/build/phaser.d.ts b/build/phaser.d.ts index 6771c6bbc..4635f7332 100644 --- a/build/phaser.d.ts +++ b/build/phaser.d.ts @@ -2928,6 +2928,255 @@ module Phaser { } } /** +* Phaser - ColorUtils +* +* A collection of methods useful for manipulating color values. +*/ +module Phaser { + class ColorUtils { + static game: Game; + /** + * Given an alpha and 3 color values this will return an integer representation of it + * + * @param alpha {number} The Alpha value (between 0 and 255) + * @param red {number} The Red channel value (between 0 and 255) + * @param green {number} The Green channel value (between 0 and 255) + * @param blue {number} The Blue channel value (between 0 and 255) + * + * @return A native color value integer (format: 0xAARRGGBB) + */ + static getColor32(alpha: number, red: number, green: number, blue: number): number; + /** + * Given 3 color values this will return an integer representation of it + * + * @param red {number} The Red channel value (between 0 and 255) + * @param green {number} The Green channel value (between 0 and 255) + * @param blue {number} The Blue channel value (between 0 and 255) + * + * @return A native color value integer (format: 0xRRGGBB) + */ + static getColor(red: number, green: number, blue: number): number; + /** + * Get HSV color wheel values in an array which will be 360 elements in size + * + * @param alpha Alpha value for each color of the color wheel, between 0 (transparent) and 255 (opaque) + * + * @return Array + */ + static getHSVColorWheel(alpha?: number): any[]; + /** + * Returns a Complementary Color Harmony for the given color. + *

A complementary hue is one directly opposite the color given on the color wheel

+ *

Value returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * + * @return 0xAARRGGBB format color value + */ + static getComplementHarmony(color: number): number; + /** + * Returns an Analogous Color Harmony for the given color. + *

An Analogous harmony are hues adjacent to each other on the color wheel

+ *

Values returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * @param threshold Control how adjacent the colors will be (default +- 30 degrees) + * + * @return Object containing 3 properties: color1 (the original color), color2 (the warmer analogous color) and color3 (the colder analogous color) + */ + static getAnalogousHarmony(color: number, threshold?: number): { + color1: number; + color2: number; + color3: number; + hue1: any; + hue2: number; + hue3: number; + }; + /** + * Returns an Split Complement Color Harmony for the given color. + *

A Split Complement harmony are the two hues on either side of the color's Complement

+ *

Values returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * @param threshold Control how adjacent the colors will be to the Complement (default +- 30 degrees) + * + * @return Object containing 3 properties: color1 (the original color), color2 (the warmer analogous color) and color3 (the colder analogous color) + */ + static getSplitComplementHarmony(color: number, threshold?: number): any; + /** + * Returns a Triadic Color Harmony for the given color. + *

A Triadic harmony are 3 hues equidistant from each other on the color wheel

+ *

Values returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * + * @return Object containing 3 properties: color1 (the original color), color2 and color3 (the equidistant colors) + */ + static getTriadicHarmony(color: number): any; + /** + * Returns a string containing handy information about the given color including string hex value, + * RGB format information and HSL information. Each section starts on a newline, 3 lines in total. + * + * @param color A color value in the format 0xAARRGGBB + * + * @return string containing the 3 lines of information + */ + static getColorInfo(color: number): string; + /** + * Return a string representation of the color in the format 0xAARRGGBB + * + * @param color The color to get the string representation for + * + * @return A string of length 10 characters in the format 0xAARRGGBB + */ + static RGBtoHexstring(color: number): string; + /** + * Return a string representation of the color in the format #RRGGBB + * + * @param color The color to get the string representation for + * + * @return A string of length 10 characters in the format 0xAARRGGBB + */ + static RGBtoWebstring(color: number): string; + /** + * Return a string containing a hex representation of the given color + * + * @param color The color channel to get the hex value for, must be a value between 0 and 255) + * + * @return A string of length 2 characters, i.e. 255 = FF, 0 = 00 + */ + static colorToHexstring(color: number): string; + /** + * Convert a HSV (hue, saturation, lightness) color space value to an RGB color + * + * @param h Hue degree, between 0 and 359 + * @param s Saturation, between 0.0 (grey) and 1.0 + * @param v Value, between 0.0 (black) and 1.0 + * @param alpha Alpha value to set per color (between 0 and 255) + * + * @return 32-bit ARGB color value (0xAARRGGBB) + */ + static HSVtoRGB(h: number, s: number, v: number, alpha?: number): number; + /** + * Convert an RGB color value to an object containing the HSV color space values: Hue, Saturation and Lightness + * + * @param color In format 0xRRGGBB + * + * @return Object with the properties hue (from 0 to 360), saturation (from 0 to 1.0) and lightness (from 0 to 1.0, also available under .value) + */ + static RGBtoHSV(color: number): any; + /** + * + * @method interpolateColor + * @param {Number} color1 + * @param {Number} color2 + * @param {Number} steps + * @param {Number} currentStep + * @param {Number} alpha + * @return {Number} + * @static + */ + static interpolateColor(color1: number, color2: number, steps: number, currentStep: number, alpha?: number): number; + /** + * + * @method interpolateColorWithRGB + * @param {Number} color + * @param {Number} r2 + * @param {Number} g2 + * @param {Number} b2 + * @param {Number} steps + * @param {Number} currentStep + * @return {Number} + * @static + */ + static interpolateColorWithRGB(color: number, r2: number, g2: number, b2: number, steps: number, currentStep: number): number; + /** + * + * @method interpolateRGB + * @param {Number} r1 + * @param {Number} g1 + * @param {Number} b1 + * @param {Number} r2 + * @param {Number} g2 + * @param {Number} b2 + * @param {Number} steps + * @param {Number} currentStep + * @return {Number} + * @static + */ + static interpolateRGB(r1: number, g1: number, b1: number, r2: number, g2: number, b2: number, steps: number, currentStep: number): number; + /** + * Returns a random color value between black and white + *

Set the min value to start each channel from the given offset.

+ *

Set the max value to restrict the maximum color used per channel

+ * + * @param min The lowest value to use for the color + * @param max The highest value to use for the color + * @param alpha The alpha value of the returning color (default 255 = fully opaque) + * + * @return 32-bit color value with alpha + */ + static getRandomColor(min?: number, max?: number, alpha?: number): number; + /** + * Return the component parts of a color as an Object with the properties alpha, red, green, blue + * + *

Alpha will only be set if it exist in the given color (0xAARRGGBB)

+ * + * @param color in RGB (0xRRGGBB) or ARGB format (0xAARRGGBB) + * + * @return Object with properties: alpha, red, green, blue + */ + static getRGB(color: number): any; + /** + * + * @method getWebRGB + * @param {Number} color + * @return {Any} + */ + static getWebRGB(color: number): any; + /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Alpha component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Alpha component of the color, will be between 0 and 255 (0 being no Alpha, 255 full Alpha) + */ + static getAlpha(color: number): number; + /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Alpha component as a value between 0 and 1 + * + * @param color In the format 0xAARRGGBB + * + * @return The Alpha component of the color, will be between 0 and 1 (0 being no Alpha (opaque), 1 full Alpha (transparent)) + */ + static getAlphaFloat(color: number): number; + /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Red component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Red component of the color, will be between 0 and 255 (0 being no color, 255 full Red) + */ + static getRed(color: number): number; + /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Green component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Green component of the color, will be between 0 and 255 (0 being no color, 255 full Green) + */ + static getGreen(color: number): number; + /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Blue component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Blue component of the color, will be between 0 and 255 (0 being no color, 255 full Blue) + */ + static getBlue(color: number): number; + } +} +/** * Phaser - DynamicTexture * * A DynamicTexture can be thought of as a mini canvas into which you can draw anything. @@ -3052,27 +3301,6 @@ module Phaser { public render(x?: number, y?: number): void; public width : number; public height : number; - /** - * Given an alpha and 3 color values this will return an integer representation of it - * - * @param alpha {number} The Alpha value (between 0 and 255) - * @param red {number} The Red channel value (between 0 and 255) - * @param green {number} The Green channel value (between 0 and 255) - * @param blue {number} The Blue channel value (between 0 and 255) - * - * @return A native color value integer (format: 0xAARRGGBB) - */ - private getColor32(alpha, red, green, blue); - /** - * Given 3 color values this will return an integer representation of it - * - * @param red {number} The Red channel value (between 0 and 255) - * @param green {number} The Green channel value (between 0 and 255) - * @param blue {number} The Blue channel value (between 0 and 255) - * - * @return A native color value integer (format: 0xRRGGBB) - */ - private getColor(red, green, blue); } } /** @@ -8473,6 +8701,27 @@ module Phaser { } } /** +* Phaser - PixelUtils +* +* A collection of methods useful for manipulating pixels. +*/ +module Phaser { + class PixelUtils { + static boot(): void; + /** + * Canvas element used in 1x1 pixel checks. + * @type {HTMLCanvasElement} + */ + static pixelCanvas: HTMLCanvasElement; + /** + * Render context of pixelCanvas + * @type {CanvasRenderingContext2D} + */ + static pixelContext: CanvasRenderingContext2D; + static getPixel(key: string, x: number, y: number): number; + } +} +/** * Phaser - Line * * A Line object is an infinte line through space. The two sets of x/y coordinates define the Line Segment. diff --git a/build/phaser.js b/build/phaser.js index 379d16ac9..c744697ca 100644 --- a/build/phaser.js +++ b/build/phaser.js @@ -4890,7 +4890,476 @@ var Phaser; Phaser.RectangleUtils = RectangleUtils; })(Phaser || (Phaser = {})); /// +/// +/// +/// +/** +* Phaser - ColorUtils +* +* A collection of methods useful for manipulating color values. +*/ +var Phaser; +(function (Phaser) { + var ColorUtils = (function () { + function ColorUtils() { } + ColorUtils.getColor32 = /** + * Given an alpha and 3 color values this will return an integer representation of it + * + * @param alpha {number} The Alpha value (between 0 and 255) + * @param red {number} The Red channel value (between 0 and 255) + * @param green {number} The Green channel value (between 0 and 255) + * @param blue {number} The Blue channel value (between 0 and 255) + * + * @return A native color value integer (format: 0xAARRGGBB) + */ + function getColor32(alpha, red, green, blue) { + return alpha << 24 | red << 16 | green << 8 | blue; + }; + ColorUtils.getColor = /** + * Given 3 color values this will return an integer representation of it + * + * @param red {number} The Red channel value (between 0 and 255) + * @param green {number} The Green channel value (between 0 and 255) + * @param blue {number} The Blue channel value (between 0 and 255) + * + * @return A native color value integer (format: 0xRRGGBB) + */ + function getColor(red, green, blue) { + return red << 16 | green << 8 | blue; + }; + ColorUtils.getHSVColorWheel = /** + * Get HSV color wheel values in an array which will be 360 elements in size + * + * @param alpha Alpha value for each color of the color wheel, between 0 (transparent) and 255 (opaque) + * + * @return Array + */ + function getHSVColorWheel(alpha) { + if (typeof alpha === "undefined") { alpha = 255; } + var colors = []; + for(var c = 0; c <= 359; c++) { + //colors[c] = HSVtoRGB(c, 1.0, 1.0, alpha); + colors[c] = ColorUtils.getWebRGB(ColorUtils.HSVtoRGB(c, 1.0, 1.0, alpha)); + } + return colors; + }; + ColorUtils.getComplementHarmony = /** + * Returns a Complementary Color Harmony for the given color. + *

A complementary hue is one directly opposite the color given on the color wheel

+ *

Value returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * + * @return 0xAARRGGBB format color value + */ + function getComplementHarmony(color) { + var hsv = ColorUtils.RGBtoHSV(color); + var opposite = ColorUtils.game.math.wrapValue(hsv.hue, 180, 359); + return ColorUtils.HSVtoRGB(opposite, 1.0, 1.0); + }; + ColorUtils.getAnalogousHarmony = /** + * Returns an Analogous Color Harmony for the given color. + *

An Analogous harmony are hues adjacent to each other on the color wheel

+ *

Values returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * @param threshold Control how adjacent the colors will be (default +- 30 degrees) + * + * @return Object containing 3 properties: color1 (the original color), color2 (the warmer analogous color) and color3 (the colder analogous color) + */ + function getAnalogousHarmony(color, threshold) { + if (typeof threshold === "undefined") { threshold = 30; } + var hsv = ColorUtils.RGBtoHSV(color); + if(threshold > 359 || threshold < 0) { + throw Error("Color Warning: Invalid threshold given to getAnalogousHarmony()"); + } + var warmer = ColorUtils.game.math.wrapValue(hsv.hue, 359 - threshold, 359); + var colder = ColorUtils.game.math.wrapValue(hsv.hue, threshold, 359); + return { + color1: color, + color2: ColorUtils.HSVtoRGB(warmer, 1.0, 1.0), + color3: ColorUtils.HSVtoRGB(colder, 1.0, 1.0), + hue1: hsv.hue, + hue2: warmer, + hue3: colder + }; + }; + ColorUtils.getSplitComplementHarmony = /** + * Returns an Split Complement Color Harmony for the given color. + *

A Split Complement harmony are the two hues on either side of the color's Complement

+ *

Values returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * @param threshold Control how adjacent the colors will be to the Complement (default +- 30 degrees) + * + * @return Object containing 3 properties: color1 (the original color), color2 (the warmer analogous color) and color3 (the colder analogous color) + */ + function getSplitComplementHarmony(color, threshold) { + if (typeof threshold === "undefined") { threshold = 30; } + var hsv = ColorUtils.RGBtoHSV(color); + if(threshold >= 359 || threshold <= 0) { + throw Error("FlxColor Warning: Invalid threshold given to getSplitComplementHarmony()"); + } + var opposite = ColorUtils.game.math.wrapValue(hsv.hue, 180, 359); + var warmer = ColorUtils.game.math.wrapValue(hsv.hue, opposite - threshold, 359); + var colder = ColorUtils.game.math.wrapValue(hsv.hue, opposite + threshold, 359); + return { + color1: color, + color2: ColorUtils.HSVtoRGB(warmer, hsv.saturation, hsv.value), + color3: ColorUtils.HSVtoRGB(colder, hsv.saturation, hsv.value), + hue1: hsv.hue, + hue2: warmer, + hue3: colder + }; + }; + ColorUtils.getTriadicHarmony = /** + * Returns a Triadic Color Harmony for the given color. + *

A Triadic harmony are 3 hues equidistant from each other on the color wheel

+ *

Values returned in 0xAARRGGBB format with Alpha set to 255.

+ * + * @param color The color to base the harmony on + * + * @return Object containing 3 properties: color1 (the original color), color2 and color3 (the equidistant colors) + */ + function getTriadicHarmony(color) { + var hsv = ColorUtils.RGBtoHSV(color); + var triadic1 = ColorUtils.game.math.wrapValue(hsv.hue, 120, 359); + var triadic2 = ColorUtils.game.math.wrapValue(triadic1, 120, 359); + return { + color1: color, + color2: ColorUtils.HSVtoRGB(triadic1, 1.0, 1.0), + color3: ColorUtils.HSVtoRGB(triadic2, 1.0, 1.0) + }; + }; + ColorUtils.getColorInfo = /** + * Returns a string containing handy information about the given color including string hex value, + * RGB format information and HSL information. Each section starts on a newline, 3 lines in total. + * + * @param color A color value in the format 0xAARRGGBB + * + * @return string containing the 3 lines of information + */ + function getColorInfo(color) { + var argb = ColorUtils.getRGB(color); + var hsl = ColorUtils.RGBtoHSV(color); + // Hex format + var result = ColorUtils.RGBtoHexstring(color) + "\n"; + // RGB format + result = result.concat("Alpha: " + argb.alpha + " Red: " + argb.red + " Green: " + argb.green + " Blue: " + argb.blue) + "\n"; + // HSL info + result = result.concat("Hue: " + hsl.hue + " Saturation: " + hsl.saturation + " Lightnes: " + hsl.lightness); + return result; + }; + ColorUtils.RGBtoHexstring = /** + * Return a string representation of the color in the format 0xAARRGGBB + * + * @param color The color to get the string representation for + * + * @return A string of length 10 characters in the format 0xAARRGGBB + */ + function RGBtoHexstring(color) { + var argb = ColorUtils.getRGB(color); + return "0x" + ColorUtils.colorToHexstring(argb.alpha) + ColorUtils.colorToHexstring(argb.red) + ColorUtils.colorToHexstring(argb.green) + ColorUtils.colorToHexstring(argb.blue); + }; + ColorUtils.RGBtoWebstring = /** + * Return a string representation of the color in the format #RRGGBB + * + * @param color The color to get the string representation for + * + * @return A string of length 10 characters in the format 0xAARRGGBB + */ + function RGBtoWebstring(color) { + var argb = ColorUtils.getRGB(color); + return "#" + ColorUtils.colorToHexstring(argb.red) + ColorUtils.colorToHexstring(argb.green) + ColorUtils.colorToHexstring(argb.blue); + }; + ColorUtils.colorToHexstring = /** + * Return a string containing a hex representation of the given color + * + * @param color The color channel to get the hex value for, must be a value between 0 and 255) + * + * @return A string of length 2 characters, i.e. 255 = FF, 0 = 00 + */ + function colorToHexstring(color) { + var digits = "0123456789ABCDEF"; + var lsd = color % 16; + var msd = (color - lsd) / 16; + var hexified = digits.charAt(msd) + digits.charAt(lsd); + return hexified; + }; + ColorUtils.HSVtoRGB = /** + * Convert a HSV (hue, saturation, lightness) color space value to an RGB color + * + * @param h Hue degree, between 0 and 359 + * @param s Saturation, between 0.0 (grey) and 1.0 + * @param v Value, between 0.0 (black) and 1.0 + * @param alpha Alpha value to set per color (between 0 and 255) + * + * @return 32-bit ARGB color value (0xAARRGGBB) + */ + function HSVtoRGB(h, s, v, alpha) { + if (typeof alpha === "undefined") { alpha = 255; } + var result; + if(s == 0.0) { + result = ColorUtils.getColor32(alpha, v * 255, v * 255, v * 255); + } else { + h = h / 60.0; + var f = h - Math.floor(h); + var p = v * (1.0 - s); + var q = v * (1.0 - s * f); + var t = v * (1.0 - s * (1.0 - f)); + switch(Math.floor(h)) { + case 0: + result = ColorUtils.getColor32(alpha, v * 255, t * 255, p * 255); + break; + case 1: + result = ColorUtils.getColor32(alpha, q * 255, v * 255, p * 255); + break; + case 2: + result = ColorUtils.getColor32(alpha, p * 255, v * 255, t * 255); + break; + case 3: + result = ColorUtils.getColor32(alpha, p * 255, q * 255, v * 255); + break; + case 4: + result = ColorUtils.getColor32(alpha, t * 255, p * 255, v * 255); + break; + case 5: + result = ColorUtils.getColor32(alpha, v * 255, p * 255, q * 255); + break; + default: + throw new Error("ColorUtils.HSVtoRGB : Unknown color"); + } + } + return result; + }; + ColorUtils.RGBtoHSV = /** + * Convert an RGB color value to an object containing the HSV color space values: Hue, Saturation and Lightness + * + * @param color In format 0xRRGGBB + * + * @return Object with the properties hue (from 0 to 360), saturation (from 0 to 1.0) and lightness (from 0 to 1.0, also available under .value) + */ + function RGBtoHSV(color) { + var rgb = ColorUtils.getRGB(color); + var red = rgb.red / 255; + var green = rgb.green / 255; + var blue = rgb.blue / 255; + var min = Math.min(red, green, blue); + var max = Math.max(red, green, blue); + var delta = max - min; + var lightness = (max + min) / 2; + var hue; + var saturation; + // Grey color, no chroma + if(delta == 0) { + hue = 0; + saturation = 0; + } else { + if(lightness < 0.5) { + saturation = delta / (max + min); + } else { + saturation = delta / (2 - max - min); + } + var delta_r = (((max - red) / 6) + (delta / 2)) / delta; + var delta_g = (((max - green) / 6) + (delta / 2)) / delta; + var delta_b = (((max - blue) / 6) + (delta / 2)) / delta; + if(red == max) { + hue = delta_b - delta_g; + } else if(green == max) { + hue = (1 / 3) + delta_r - delta_b; + } else if(blue == max) { + hue = (2 / 3) + delta_g - delta_r; + } + if(hue < 0) { + hue += 1; + } + if(hue > 1) { + hue -= 1; + } + } + // Keep the value with 0 to 359 + hue *= 360; + hue = Math.round(hue); + return { + hue: hue, + saturation: saturation, + lightness: lightness, + value: lightness + }; + }; + ColorUtils.interpolateColor = /** + * + * @method interpolateColor + * @param {Number} color1 + * @param {Number} color2 + * @param {Number} steps + * @param {Number} currentStep + * @param {Number} alpha + * @return {Number} + * @static + */ + function interpolateColor(color1, color2, steps, currentStep, alpha) { + if (typeof alpha === "undefined") { alpha = 255; } + var src1 = ColorUtils.getRGB(color1); + var src2 = ColorUtils.getRGB(color2); + var r = (((src2.red - src1.red) * currentStep) / steps) + src1.red; + var g = (((src2.green - src1.green) * currentStep) / steps) + src1.green; + var b = (((src2.blue - src1.blue) * currentStep) / steps) + src1.blue; + return ColorUtils.getColor32(alpha, r, g, b); + }; + ColorUtils.interpolateColorWithRGB = /** + * + * @method interpolateColorWithRGB + * @param {Number} color + * @param {Number} r2 + * @param {Number} g2 + * @param {Number} b2 + * @param {Number} steps + * @param {Number} currentStep + * @return {Number} + * @static + */ + function interpolateColorWithRGB(color, r2, g2, b2, steps, currentStep) { + var src = ColorUtils.getRGB(color); + var r = (((r2 - src.red) * currentStep) / steps) + src.red; + var g = (((g2 - src.green) * currentStep) / steps) + src.green; + var b = (((b2 - src.blue) * currentStep) / steps) + src.blue; + return ColorUtils.getColor(r, g, b); + }; + ColorUtils.interpolateRGB = /** + * + * @method interpolateRGB + * @param {Number} r1 + * @param {Number} g1 + * @param {Number} b1 + * @param {Number} r2 + * @param {Number} g2 + * @param {Number} b2 + * @param {Number} steps + * @param {Number} currentStep + * @return {Number} + * @static + */ + function interpolateRGB(r1, g1, b1, r2, g2, b2, steps, currentStep) { + var r = (((r2 - r1) * currentStep) / steps) + r1; + var g = (((g2 - g1) * currentStep) / steps) + g1; + var b = (((b2 - b1) * currentStep) / steps) + b1; + return ColorUtils.getColor(r, g, b); + }; + ColorUtils.getRandomColor = /** + * Returns a random color value between black and white + *

Set the min value to start each channel from the given offset.

+ *

Set the max value to restrict the maximum color used per channel

+ * + * @param min The lowest value to use for the color + * @param max The highest value to use for the color + * @param alpha The alpha value of the returning color (default 255 = fully opaque) + * + * @return 32-bit color value with alpha + */ + function getRandomColor(min, max, alpha) { + if (typeof min === "undefined") { min = 0; } + if (typeof max === "undefined") { max = 255; } + if (typeof alpha === "undefined") { alpha = 255; } + // Sanity checks + if(max > 255) { + return ColorUtils.getColor(255, 255, 255); + } + if(min > max) { + return ColorUtils.getColor(255, 255, 255); + } + var red = min + Math.round(Math.random() * (max - min)); + var green = min + Math.round(Math.random() * (max - min)); + var blue = min + Math.round(Math.random() * (max - min)); + return ColorUtils.getColor32(alpha, red, green, blue); + }; + ColorUtils.getRGB = /** + * Return the component parts of a color as an Object with the properties alpha, red, green, blue + * + *

Alpha will only be set if it exist in the given color (0xAARRGGBB)

+ * + * @param color in RGB (0xRRGGBB) or ARGB format (0xAARRGGBB) + * + * @return Object with properties: alpha, red, green, blue + */ + function getRGB(color) { + return { + alpha: color >>> 24, + red: color >> 16 & 0xFF, + green: color >> 8 & 0xFF, + blue: color & 0xFF + }; + }; + ColorUtils.getWebRGB = /** + * + * @method getWebRGB + * @param {Number} color + * @return {Any} + */ + function getWebRGB(color) { + var alpha = (color >>> 24) / 255; + var red = color >> 16 & 0xFF; + var green = color >> 8 & 0xFF; + var blue = color & 0xFF; + return 'rgba(' + red.toString() + ',' + green.toString() + ',' + blue.toString() + ',' + alpha.toString() + ')'; + }; + ColorUtils.getAlpha = /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Alpha component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Alpha component of the color, will be between 0 and 255 (0 being no Alpha, 255 full Alpha) + */ + function getAlpha(color) { + return color >>> 24; + }; + ColorUtils.getAlphaFloat = /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Alpha component as a value between 0 and 1 + * + * @param color In the format 0xAARRGGBB + * + * @return The Alpha component of the color, will be between 0 and 1 (0 being no Alpha (opaque), 1 full Alpha (transparent)) + */ + function getAlphaFloat(color) { + return (color >>> 24) / 255; + }; + ColorUtils.getRed = /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Red component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Red component of the color, will be between 0 and 255 (0 being no color, 255 full Red) + */ + function getRed(color) { + return color >> 16 & 0xFF; + }; + ColorUtils.getGreen = /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Green component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Green component of the color, will be between 0 and 255 (0 being no color, 255 full Green) + */ + function getGreen(color) { + return color >> 8 & 0xFF; + }; + ColorUtils.getBlue = /** + * Given a native color value (in the format 0xAARRGGBB) this will return the Blue component, as a value between 0 and 255 + * + * @param color In the format 0xAARRGGBB + * + * @return The Blue component of the color, will be between 0 and 255 (0 being no color, 255 full Blue) + */ + function getBlue(color) { + return color & 0xFF; + }; + return ColorUtils; + })(); + Phaser.ColorUtils = ColorUtils; +})(Phaser || (Phaser = {})); +/// /// +/// /// /** * Phaser - DynamicTexture @@ -4940,7 +5409,7 @@ var Phaser; //b = imageData.data[2]; //a = imageData.data[3]; var imageData = this.context.getImageData(x, y, 1, 1); - return this.getColor(imageData.data[0], imageData.data[1], imageData.data[2]); + return Phaser.ColorUtils.getColor(imageData.data[0], imageData.data[1], imageData.data[2]); }; DynamicTexture.prototype.getPixel32 = /** * Get a color of a specific pixel (including alpha value). @@ -4950,7 +5419,7 @@ var Phaser; */ function (x, y) { var imageData = this.context.getImageData(x, y, 1, 1); - return this.getColor32(imageData.data[3], imageData.data[0], imageData.data[1], imageData.data[2]); + return Phaser.ColorUtils.getColor32(imageData.data[3], imageData.data[0], imageData.data[1], imageData.data[2]); }; DynamicTexture.prototype.getPixels = /** * Get pixels in array in a specific rectangle. @@ -5101,31 +5570,6 @@ var Phaser; enumerable: true, configurable: true }); - DynamicTexture.prototype.getColor32 = /** - * Given an alpha and 3 color values this will return an integer representation of it - * - * @param alpha {number} The Alpha value (between 0 and 255) - * @param red {number} The Red channel value (between 0 and 255) - * @param green {number} The Green channel value (between 0 and 255) - * @param blue {number} The Blue channel value (between 0 and 255) - * - * @return A native color value integer (format: 0xAARRGGBB) - */ - function (alpha, red, green, blue) { - return alpha << 24 | red << 16 | green << 8 | blue; - }; - DynamicTexture.prototype.getColor = /** - * Given 3 color values this will return an integer representation of it - * - * @param red {number} The Red channel value (between 0 and 255) - * @param green {number} The Green channel value (between 0 and 255) - * @param blue {number} The Blue channel value (between 0 and 255) - * - * @return A native color value integer (format: 0xRRGGBB) - */ - function (red, green, blue) { - return red << 16 | green << 8 | blue; - }; return DynamicTexture; })(); Phaser.DynamicTexture = DynamicTexture; @@ -7289,6 +7733,10 @@ var Phaser; if(this.alpha !== 1) { this._game.stage.context.globalAlpha = 1; } + // Debug test + this._game.stage.context.fillStyle = 'rgba(255,0,0,0.3)'; + //this._game.stage.context.fillRect(this.scaledX, this.scaledY, this.worldView.width, this.worldView.height); + this._game.stage.context.fillRect(this.worldView.x, this.worldView.y, this.worldView.width, this.worldView.height); }; Camera.prototype.setPosition = /** * Set position of this camera. @@ -13544,7 +13992,6 @@ var Phaser; } } } - //console.log('highest priority was', _highestPriority); if(this.isDown) { // Now update all objects with the highest priority ID (can be more than 1) for(var i = 0; i < this.game.input.totalTrackedObjects; i++) { @@ -15029,11 +15476,11 @@ var Phaser; if(sprite.scrollFactor.x == 0 && sprite.scrollFactor.y == 0) { return true; } - this._dx = sprite.frameBounds.x - camera.worldView.x; - this._dy = sprite.frameBounds.y - camera.worldView.y; + this._dx = sprite.frameBounds.x - (camera.worldView.x * sprite.scrollFactor.x); + this._dy = sprite.frameBounds.y - (camera.worldView.y * sprite.scrollFactor.y); this._dw = sprite.frameBounds.width * sprite.scale.x; this._dh = sprite.frameBounds.height * sprite.scale.y; - return (camera.worldView.right > this._dx) && (camera.worldView.x < this._dx + this._dw) && (camera.worldView.bottom > this._dy) && (camera.worldView.y < this._dy + this._dh); + return (camera.scaledX + camera.worldView.width > this._dx) && (camera.scaledX < this._dx + this._dw) && (camera.scaledY + camera.worldView.height > this._dy) && (camera.scaledY < this._dy + this._dh); }; CanvasRenderer.prototype.renderSprite = /** * Render this sprite to specific camera. Called by game loop after update(). @@ -15042,6 +15489,7 @@ var Phaser; */ function (camera, sprite) { if(sprite.scale.x == 0 || sprite.scale.y == 0 || sprite.texture.alpha < 0.1 || this.inCamera(camera, sprite) == false) { + console.log('out of camera', sprite.frameBounds.x, sprite.frameBounds.y, sprite.frameBounds.width, sprite.frameBounds.height); return false; } this._count++; @@ -15412,6 +15860,8 @@ var Phaser; this.input.boot(); this.framerate = 60; this.isBooted = true; + // Set-up some static helper references + Phaser.ColorUtils.game = this; // Display the default game screen? if(this.onInitCallback == null && this.onCreateCallback == null && this.onUpdateCallback == null && this.onRenderCallback == null && this._pendingState == null) { this._raf = new Phaser.RequestAnimationFrame(this, this.bootLoop); @@ -15799,6 +16249,34 @@ var Phaser; Phaser.Polygon = Polygon; })(Phaser || (Phaser = {})); /// +/// +/// +/// +/** +* Phaser - PixelUtils +* +* A collection of methods useful for manipulating pixels. +*/ +var Phaser; +(function (Phaser) { + var PixelUtils = (function () { + function PixelUtils() { } + PixelUtils.boot = function boot() { + PixelUtils.pixelCanvas = document.createElement('canvas'); + PixelUtils.pixelCanvas.width = 1; + PixelUtils.pixelCanvas.height = 1; + PixelUtils.pixelContext = PixelUtils.pixelCanvas.getContext('2d'); + }; + PixelUtils.getPixel = function getPixel(key, x, y) { + // write out a single pixel (won't help with rotated sprites though.. hmm) + var imageData = PixelUtils.pixelContext.getImageData(0, 0, 1, 1); + return Phaser.ColorUtils.getColor32(imageData.data[3], imageData.data[0], imageData.data[1], imageData.data[2]); + }; + return PixelUtils; + })(); + Phaser.PixelUtils = PixelUtils; +})(Phaser || (Phaser = {})); +/// /** * Phaser - Line *