diff --git a/Phaser/gameobjects/GeomSprite.ts b/Phaser/gameobjects/GeomSprite.ts index ac76c7d3..589d4302 100644 --- a/Phaser/gameobjects/GeomSprite.ts +++ b/Phaser/gameobjects/GeomSprite.ts @@ -301,15 +301,24 @@ module Phaser { // And now the edge points this._game.stage.context.fillStyle = 'rgb(255,255,255)'; - this.renderPoint(this._dx, this._dy, this.rect.topLeft, 2); - this.renderPoint(this._dx, this._dy, this.rect.topCenter, 2); - this.renderPoint(this._dx, this._dy, this.rect.topRight, 2); - this.renderPoint(this._dx, this._dy, this.rect.leftCenter, 2); - this.renderPoint(this._dx, this._dy, this.rect.center, 2); - this.renderPoint(this._dx, this._dy, this.rect.rightCenter, 2); - this.renderPoint(this._dx, this._dy, this.rect.bottomLeft, 2); - this.renderPoint(this._dx, this._dy, this.rect.bottomCenter, 2); - this.renderPoint(this._dx, this._dy, this.rect.bottomRight, 2); + //this.renderPoint(this.rect.topLeft, this._dx, this._dy, 2); + //this.renderPoint(this.rect.topCenter, this._dx, this._dy, 2); + //this.renderPoint(this.rect.topRight, this._dx, this._dy, 2); + //this.renderPoint(this.rect.leftCenter, this._dx, this._dy, 2); + //this.renderPoint(this.rect.center, this._dx, this._dy, 2); + //this.renderPoint(this.rect.rightCenter, this._dx, this._dy, 2); + //this.renderPoint(this.rect.bottomLeft, this._dx, this._dy, 2); + //this.renderPoint(this.rect.bottomCenter, this._dx, this._dy, 2); + //this.renderPoint(this.rect.bottomRight, this._dx, this._dy, 2); + this.renderPoint(this.rect.topLeft, 0, 0, 2); + this.renderPoint(this.rect.topCenter, 0, 0, 2); + this.renderPoint(this.rect.topRight, 0, 0, 2); + this.renderPoint(this.rect.leftCenter, 0, 0, 2); + this.renderPoint(this.rect.center, 0, 0, 2); + this.renderPoint(this.rect.rightCenter, 0, 0, 2); + this.renderPoint(this.rect.bottomLeft, 0, 0, 2); + this.renderPoint(this.rect.bottomCenter, 0, 0, 2); + this.renderPoint(this.rect.bottomRight, 0, 0, 2); } @@ -330,11 +339,9 @@ module Phaser { } - public renderPoint(offsetX, offsetY, point, size) { + public renderPoint(point, offsetX?: number = 0, offsetY?: number = 0, size?: number = 1) { - offsetX = 0; - offsetY = 0; - this._game.stage.context.fillRect(offsetX + point.x, offsetY + point.y, 1, 1); + this._game.stage.context.fillRect(offsetX + point.x, offsetY + point.y, size, size); } diff --git a/Phaser/system/Camera.ts b/Phaser/system/Camera.ts index 11014c92..9eb2d439 100644 --- a/Phaser/system/Camera.ts +++ b/Phaser/system/Camera.ts @@ -62,6 +62,7 @@ module Phaser { public deadzone: Rectangle = null; // Camera Border + public disableClipping: bool = false; public showBorder: bool = false; public borderColor: string = 'rgb(255,255,255)'; @@ -317,7 +318,7 @@ module Phaser { this.fx.render(this, this._stageX, this._stageY, this.worldView.width, this.worldView.height); // Clip the camera so we don't get sprites appearing outside the edges - if (this._clip) + if (this._clip && this.disableClipping == false) { this._game.stage.context.beginPath(); this._game.stage.context.rect(this._sx, this._sy, this.worldView.width, this.worldView.height); @@ -343,7 +344,7 @@ module Phaser { this.fx.postRender(this, this._sx, this._sy, this.worldView.width, this.worldView.height); - if (this._rotation !== 0 || this._clip) + if (this._rotation !== 0 || (this._clip && this.disableClipping == false)) { this._game.stage.context.translate(0, 0); } diff --git a/README.md b/README.md index cc2f8fd2..69fc97dd 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ By Richard Davey, [Photon Storm](http://www.photonstorm.com) Phaser is a 2D JavaScript/TypeScript HTML5 Game Framework based heavily on [Flixel](http://www.flixel.org). -[Twitter](https://twitter.com/photonstorm) -[Development Blog](http://www.photonstorm.com) +[Twitter](https://twitter.com/photonstorm)
+[Development Blog](http://www.photonstorm.com)
[Support Forum](http://www.html5gamedevs.com/forum/14-phaser/) Try out the [Phaser Test Suite](http://gametest.mobi/phaser/) @@ -33,6 +33,11 @@ V0.9.5 * Fixed a bug in Flash, Fade and Shake where the duration would fail on anything above 3 seconds. * Fixed a bug in Camera Shake that made it go a bit haywire, now shakes correctly. * Added new Scanlines Camera FX. +* Fixed offset values being ignored in GeomSprite.renderPoint (thanks bapuna). +* Added new Mirror Camera FX. Can mirror the camera image horizontally, vertically or both with an optional fill color overlay. +* Added Camera.disableClipping for when you don't care about things being drawn outside the edge (usful for some FX). + + Requirements diff --git a/SpecialFX/Camera/Mirror.js b/SpecialFX/Camera/Mirror.js new file mode 100644 index 00000000..2f9b5688 --- /dev/null +++ b/SpecialFX/Camera/Mirror.js @@ -0,0 +1,19 @@ +var Shapes; +(function (Shapes) { + + var Point = Shapes.Point = (function () { + function Point(x, y) { + this.x = x; + this.y = y; + } + Point.prototype.getDist = function () { + return Math.sqrt((this.x * this.x) + (this.y * this.y)); + }; + Point.origin = new Point(0, 0); + return Point; + })(); + +})(Shapes || (Shapes = {})); + +var p = new Shapes.Point(3, 4); +var dist = p.getDist(); diff --git a/SpecialFX/Camera/Mirror.ts b/SpecialFX/Camera/Mirror.ts new file mode 100644 index 00000000..211da2f1 --- /dev/null +++ b/SpecialFX/Camera/Mirror.ts @@ -0,0 +1,130 @@ +/// +/// +/// + +/** +* Phaser - FX - Camera - Mirror +* +* Creates a mirror effect for a camera. +* Can mirror the camera image horizontally, vertically or both with an optional fill color overlay. +*/ + +module Phaser.FX.Camera { + + export class Mirror { + + constructor(game: Game, parent: Phaser.Camera) { + + this._game = game; + this._parent = parent; + + this._canvas = document.createElement('canvas'); + this._canvas.width = parent.width; + this._canvas.height = parent.height; + this._context = this._canvas.getContext('2d'); + + } + + private _game: Game; + private _parent: Phaser.Camera; + private _canvas: HTMLCanvasElement; + private _context: CanvasRenderingContext2D; + + private _sx: number; + private _sy: number; + private _mirrorX: number; + private _mirrorY: number; + private _mirrorWidth: number; + private _mirrorHeight: number; + private _mirrorColor: string = null; + + public flipX: bool = false; + public flipY: bool = true; + + public x: number; + public y: number; + public cls: bool = false; + + /** + * This is the rectangular region to grab from the Camera used in the Mirror effect + * It is rendered to the Stage at Mirror.x/y (note the use of Stage coordinates, not World coordinates) + */ + public start(x: number, y: number, region: Phaser.Quad, fillColor?: string = 'rgba(0, 0, 100, 0.5)') { + + this.x = x; + this.y = y; + + this._mirrorX = region.x; + this._mirrorY = region.y; + this._mirrorWidth = region.width; + this._mirrorHeight = region.height; + + if (fillColor) + { + this._mirrorColor = fillColor; + this._context.fillStyle = this._mirrorColor; + } + + } + + /** + * Post-render is called during the objects render cycle, after the children/image data has been rendered. + * It happens directly BEFORE a canvas context.restore has happened if added to a Camera. + */ + public postRender(camera: Camera, cameraX: number, cameraY: number, cameraWidth: number, cameraHeight: number) { + + if (this.cls) + { + this._context.clearRect(0, 0, this._mirrorWidth, this._mirrorHeight); + } + + this._sx = cameraX + this._mirrorX; + this._sy = cameraY + this._mirrorY; + + if (this.flipX == true && this.flipY == false) + { + this._sx = 0; + } + else if (this.flipY == true && this.flipX == false) + { + this._sy = 0; + } + + this._context.drawImage( + this._game.stage.canvas, // Source Image + this._sx, // Source X (location within the source image) + this._sy, // Source Y + this._mirrorWidth, // Source Width + this._mirrorHeight, // Source Height + 0, // Destination X (where on the canvas it'll be drawn) + 0, // Destination Y + this._mirrorWidth, // Destination Width (always same as Source Width unless scaled) + this._mirrorHeight // Destination Height (always same as Source Height unless scaled) + ); + + if (this._mirrorColor) + { + this._context.fillRect(0, 0, this._mirrorWidth, this._mirrorHeight); + } + + if (this.flipX && this.flipY) + { + this._game.stage.context.transform(-1, 0, 0, -1, this._mirrorWidth, this._mirrorHeight); + this._game.stage.context.drawImage(this._canvas, -this.x, -this.y); + } + else if (this.flipX) + { + this._game.stage.context.transform(-1, 0, 0, 1, this._mirrorWidth, 0); + this._game.stage.context.drawImage(this._canvas, -this.x, this.y); + } + else if (this.flipY) + { + this._game.stage.context.transform(1, 0, 0, -1, 0, this._mirrorHeight); + this._game.stage.context.drawImage(this._canvas, this.x, -this.y); + } + + } + + } + +} diff --git a/SpecialFX/SpecialFX.csproj b/SpecialFX/SpecialFX.csproj index ce3499ee..8cc354e3 100644 --- a/SpecialFX/SpecialFX.csproj +++ b/SpecialFX/SpecialFX.csproj @@ -1,4 +1,4 @@ - + Debug @@ -48,6 +48,7 @@ false ../build/phaser-fx.js true + true ES5 @@ -55,6 +56,7 @@ false ../build/phaser-fx.js true + true @@ -64,6 +66,10 @@ Fade.ts + + + Mirror.ts + Template.ts @@ -80,6 +86,9 @@ Flash.ts + + + cd $(ProjectDir)..\build diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 509609db..a33830a4 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -107,6 +107,10 @@ + + + mirror.ts + scanlines.ts diff --git a/Tests/camera fx/mirror.js b/Tests/camera fx/mirror.js new file mode 100644 index 00000000..f32b4105 --- /dev/null +++ b/Tests/camera fx/mirror.js @@ -0,0 +1,40 @@ +/// +/// +(function () { + var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update); + function init() { + myGame.world.setSize(1216, 896); + myGame.loader.addImageFile('backdrop', 'assets/pics/ninja-masters2.png'); + myGame.loader.load(); + } + var mirror; + var cam; + function create() { + // What we need is a camera 800x400 pixels in size, the mirror effect will sit below it. + // So we resize our default camera to 400px + myGame.camera.height = 400; + // Because it's our default camera we need to tell it to disable clipping, otherwise we'll never see the mirror effect + myGame.camera.disableClipping = true; + // Add our effect to the camera + mirror = myGame.camera.fx.add(Phaser.FX.Camera.Mirror); + // The first 2 parameters are the x and y coordinates we're going to display the mirror effect in STAGE coordinates + // The next is the rectangular region of the Camera that we'll create the effect from (in this case the whole camera) + // Finally we set the fill color that is put over the top of the mirror effect + mirror.start(0, 400, new Phaser.Quad(0, 0, 800, 400), 'rgba(0, 0, 100, 0.7)'); + mirror.flipX = true; + mirror.flipY = true; + myGame.createSprite(0, 0, 'backdrop'); + } + function update() { + if(myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { + myGame.camera.scroll.x -= 4; + } else if(myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { + myGame.camera.scroll.x += 4; + } + if(myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) { + myGame.camera.scroll.y -= 4; + } else if(myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { + myGame.camera.scroll.y += 4; + } + } +})(); diff --git a/Tests/camera fx/mirror.ts b/Tests/camera fx/mirror.ts new file mode 100644 index 00000000..95158467 --- /dev/null +++ b/Tests/camera fx/mirror.ts @@ -0,0 +1,68 @@ +/// +/// + +(function () { + + var myGame = new Phaser.Game(this, 'game', 800, 600, init, create, update); + + function init() { + + // Just set the world to be the size of the image we're loading in + myGame.world.setSize(1216, 896); + + myGame.loader.addImageFile('backdrop', 'assets/pics/ninja-masters2.png'); + + myGame.loader.load(); + + } + + var mirror: Phaser.FX.Camera.Mirror; + + function create() { + + // What we need is a camera 800x400 pixels in size, the mirror effect will sit below it. + // So we resize our default camera to 400px + myGame.camera.height = 400; + + // Because it's our default camera we need to tell it to disable clipping, otherwise we'll never see the mirror effect + myGame.camera.disableClipping = true; + + // Add our effect to the camera + mirror = myGame.camera.fx.add(Phaser.FX.Camera.Mirror); + + // The first 2 parameters are the x and y coordinates we're going to display the mirror effect in STAGE coordinates + // The next is the rectangular region of the Camera that we'll create the effect from (in this case the whole camera) + // Finally we set the fill color that is put over the top of the mirror effect + mirror.start(0, 400, new Phaser.Quad(0, 0, 800, 400), 'rgba(0, 0, 100, 0.7)'); + + // Experiment with variations on these to see the different mirror effects that can be achieved. + //mirror.flipX = true; + //mirror.flipY = true; + + myGame.createSprite(0, 0, 'backdrop'); + + } + + function update() { + + if (myGame.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + { + myGame.camera.scroll.x -= 4; + } + else if (myGame.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + { + myGame.camera.scroll.x += 4; + } + + if (myGame.input.keyboard.isDown(Phaser.Keyboard.UP)) + { + myGame.camera.scroll.y -= 4; + } + else if (myGame.input.keyboard.isDown(Phaser.Keyboard.DOWN)) + { + myGame.camera.scroll.y += 4; + } + + } + +})(); diff --git a/Tests/camera fx/scanlines.js b/Tests/camera fx/scanlines.js index f1a3b175..43f68fb9 100644 --- a/Tests/camera fx/scanlines.js +++ b/Tests/camera fx/scanlines.js @@ -11,7 +11,9 @@ function create() { // Add our effect to the camera scanlines = myGame.camera.fx.add(Phaser.FX.Camera.Scanlines); - scanlines.spacing = 3; + // We'll have the scanlines spaced out every 2 pixels + scanlines.spacing = 2; + // This is the color the lines will be drawn in scanlines.color = 'rgba(0, 0, 0, 0.8)'; myGame.createSprite(0, 0, 'backdrop'); } diff --git a/Tests/phaser-fx.js b/Tests/phaser-fx.js index a4d44bfb..bde85275 100644 --- a/Tests/phaser-fx.js +++ b/Tests/phaser-fx.js @@ -129,6 +129,98 @@ var Phaser; var FX = Phaser.FX; })(Phaser || (Phaser = {})); var Phaser; +(function (Phaser) { + (function (FX) { + /// + /// + /// + /** + * Phaser - FX - Camera - Mirror + * + * A Template FX file you can use to create your own Camera FX. + * If you don't use any of the methods below (i.e. preUpdate, render, etc) then DELETE THEM to avoid un-necessary calls by the FXManager. + */ + (function (Camera) { + var Mirror = (function () { + function Mirror(game, parent) { + this._mirrorColor = null; + this.flipX = false; + this.flipY = true; + this.cls = false; + this._game = game; + this._parent = parent; + this._canvas = document.createElement('canvas'); + this._canvas.width = parent.width; + this._canvas.height = parent.height; + this._context = this._canvas.getContext('2d'); + } + Mirror.prototype.start = /** + * This is the rectangular region to grab from the Camera used in the Mirror effect + * It is rendered to the Stage at Mirror.x/y (note the use of Stage coordinates, not World coordinates) + */ + function (x, y, region, fillColor) { + if (typeof fillColor === "undefined") { fillColor = 'rgba(0,0,100,0.5)'; } + this.x = x; + this.y = y; + this._mirrorX = region.x; + this._mirrorY = region.y; + this._mirrorWidth = region.width; + this._mirrorHeight = region.height; + if(fillColor) { + this._mirrorColor = fillColor; + this._context.fillStyle = this._mirrorColor; + } + }; + Mirror.prototype.postRender = /** + * Post-render is called during the objects render cycle, after the children/image data has been rendered. + * It happens directly BEFORE a canvas context.restore has happened if added to a Camera. + */ + function (camera, cameraX, cameraY, cameraWidth, cameraHeight) { + if(this.cls) { + this._context.clearRect(0, 0, this._mirrorWidth, this._mirrorHeight); + } + this._sx = cameraX + this._mirrorX; + this._sy = cameraY + this._mirrorY; + if(this.flipX == true && this.flipY == false) { + this._sx = 0; + } else if(this.flipY == true && this.flipX == false) { + this._sy = 0; + } + this._context.drawImage(this._game.stage.canvas, // Source Image + this._sx, // Source X (location within the source image) + this._sy, // Source Y + this._mirrorWidth, // Source Width + this._mirrorHeight, // Source Height + 0, // Destination X (where on the canvas it'll be drawn) + 0, // Destination Y + this._mirrorWidth, // Destination Width (always same as Source Width unless scaled) + this._mirrorHeight); + // Destination Height (always same as Source Height unless scaled) + if(this._mirrorColor) { + this._context.fillRect(0, 0, this._mirrorWidth, this._mirrorHeight); + } + //this._game.stage.context.save(); + if(this.flipX && this.flipY) { + this._game.stage.context.transform(-1, 0, 0, -1, this._mirrorWidth, this._mirrorHeight); + this._game.stage.context.drawImage(this._canvas, -this.x, -this.y); + } else if(this.flipX) { + this._game.stage.context.transform(-1, 0, 0, 1, this._mirrorWidth, 0); + this._game.stage.context.drawImage(this._canvas, -this.x, this.y); + } else if(this.flipY) { + this._game.stage.context.transform(1, 0, 0, -1, 0, this._mirrorHeight); + this._game.stage.context.drawImage(this._canvas, this.x, -this.y); + } + //this._game.stage.context.restore(); + }; + return Mirror; + })(); + Camera.Mirror = Mirror; + })(FX.Camera || (FX.Camera = {})); + var Camera = FX.Camera; + })(Phaser.FX || (Phaser.FX = {})); + var FX = Phaser.FX; +})(Phaser || (Phaser = {})); +var Phaser; (function (Phaser) { (function (FX) { /// diff --git a/Tests/phaser.js b/Tests/phaser.js index 59fe8d15..5ac07e62 100644 --- a/Tests/phaser.js +++ b/Tests/phaser.js @@ -925,6 +925,7 @@ var Phaser; this.bounds = null; this.deadzone = null; // Camera Border + this.disableClipping = false; this.showBorder = false; this.borderColor = 'rgb(255,255,255)'; // Camera Background Color @@ -1113,7 +1114,7 @@ var Phaser; } this.fx.render(this, this._stageX, this._stageY, this.worldView.width, this.worldView.height); // Clip the camera so we don't get sprites appearing outside the edges - if(this._clip) { + if(this._clip && this.disableClipping == false) { this._game.stage.context.beginPath(); this._game.stage.context.rect(this._sx, this._sy, this.worldView.width, this.worldView.height); this._game.stage.context.closePath(); @@ -1131,7 +1132,7 @@ var Phaser; this._game.stage.context.scale(1, 1); } this.fx.postRender(this, this._sx, this._sy, this.worldView.width, this.worldView.height); - if(this._rotation !== 0 || this._clip) { + if(this._rotation !== 0 || (this._clip && this.disableClipping == false)) { this._game.stage.context.translate(0, 0); } this._game.stage.context.restore(); @@ -10927,15 +10928,24 @@ var Phaser; } // And now the edge points this._game.stage.context.fillStyle = 'rgb(255,255,255)'; - this.renderPoint(this._dx, this._dy, this.rect.topLeft, 2); - this.renderPoint(this._dx, this._dy, this.rect.topCenter, 2); - this.renderPoint(this._dx, this._dy, this.rect.topRight, 2); - this.renderPoint(this._dx, this._dy, this.rect.leftCenter, 2); - this.renderPoint(this._dx, this._dy, this.rect.center, 2); - this.renderPoint(this._dx, this._dy, this.rect.rightCenter, 2); - this.renderPoint(this._dx, this._dy, this.rect.bottomLeft, 2); - this.renderPoint(this._dx, this._dy, this.rect.bottomCenter, 2); - this.renderPoint(this._dx, this._dy, this.rect.bottomRight, 2); + //this.renderPoint(this.rect.topLeft, this._dx, this._dy, 2); + //this.renderPoint(this.rect.topCenter, this._dx, this._dy, 2); + //this.renderPoint(this.rect.topRight, this._dx, this._dy, 2); + //this.renderPoint(this.rect.leftCenter, this._dx, this._dy, 2); + //this.renderPoint(this.rect.center, this._dx, this._dy, 2); + //this.renderPoint(this.rect.rightCenter, this._dx, this._dy, 2); + //this.renderPoint(this.rect.bottomLeft, this._dx, this._dy, 2); + //this.renderPoint(this.rect.bottomCenter, this._dx, this._dy, 2); + //this.renderPoint(this.rect.bottomRight, this._dx, this._dy, 2); + this.renderPoint(this.rect.topLeft, 0, 0, 2); + this.renderPoint(this.rect.topCenter, 0, 0, 2); + this.renderPoint(this.rect.topRight, 0, 0, 2); + this.renderPoint(this.rect.leftCenter, 0, 0, 2); + this.renderPoint(this.rect.center, 0, 0, 2); + this.renderPoint(this.rect.rightCenter, 0, 0, 2); + this.renderPoint(this.rect.bottomLeft, 0, 0, 2); + this.renderPoint(this.rect.bottomCenter, 0, 0, 2); + this.renderPoint(this.rect.bottomRight, 0, 0, 2); } this._game.stage.restoreCanvasValues(); if(this.rotation !== 0) { @@ -10947,10 +10957,11 @@ var Phaser; } return true; }; - GeomSprite.prototype.renderPoint = function (offsetX, offsetY, point, size) { - offsetX = 0; - offsetY = 0; - this._game.stage.context.fillRect(offsetX + point.x, offsetY + point.y, 1, 1); + GeomSprite.prototype.renderPoint = function (point, offsetX, offsetY, size) { + if (typeof offsetX === "undefined") { offsetX = 0; } + if (typeof offsetY === "undefined") { offsetY = 0; } + if (typeof size === "undefined") { size = 1; } + this._game.stage.context.fillRect(offsetX + point.x, offsetY + point.y, size, size); }; GeomSprite.prototype.renderDebugInfo = function (x, y, color) { if (typeof color === "undefined") { color = 'rgb(255,255,255)'; } diff --git a/build/phaser-fx.d.ts b/build/phaser-fx.d.ts index 661c3f12..da160062 100644 --- a/build/phaser-fx.d.ts +++ b/build/phaser-fx.d.ts @@ -64,6 +64,43 @@ module Phaser.FX.Camera { } } /** +* Phaser - FX - Camera - Mirror +* +* A Template FX file you can use to create your own Camera FX. +* If you don't use any of the methods below (i.e. preUpdate, render, etc) then DELETE THEM to avoid un-necessary calls by the FXManager. +*/ +module Phaser.FX.Camera { + class Mirror { + constructor(game: Game, parent: Camera); + private _game; + private _parent; + private _canvas; + private _context; + private _sx; + private _sy; + private _mirrorX; + private _mirrorY; + private _mirrorWidth; + private _mirrorHeight; + private _mirrorColor; + public flipX: bool; + public flipY: bool; + public x: number; + public y: number; + public cls: bool; + /** + * This is the rectangular region to grab from the Camera used in the Mirror effect + * It is rendered to the Stage at Mirror.x/y (note the use of Stage coordinates, not World coordinates) + */ + public start(x: number, y: number, region: Quad, fillColor?: string): void; + /** + * Post-render is called during the objects render cycle, after the children/image data has been rendered. + * It happens directly BEFORE a canvas context.restore has happened if added to a Camera. + */ + public postRender(camera: Camera, cameraX: number, cameraY: number, cameraWidth: number, cameraHeight: number): void; + } +} +/** * Phaser - FX - Camera - Scanlines * * Give your game that classic retro feel! diff --git a/build/phaser-fx.js b/build/phaser-fx.js index a4d44bfb..bde85275 100644 --- a/build/phaser-fx.js +++ b/build/phaser-fx.js @@ -129,6 +129,98 @@ var Phaser; var FX = Phaser.FX; })(Phaser || (Phaser = {})); var Phaser; +(function (Phaser) { + (function (FX) { + /// + /// + /// + /** + * Phaser - FX - Camera - Mirror + * + * A Template FX file you can use to create your own Camera FX. + * If you don't use any of the methods below (i.e. preUpdate, render, etc) then DELETE THEM to avoid un-necessary calls by the FXManager. + */ + (function (Camera) { + var Mirror = (function () { + function Mirror(game, parent) { + this._mirrorColor = null; + this.flipX = false; + this.flipY = true; + this.cls = false; + this._game = game; + this._parent = parent; + this._canvas = document.createElement('canvas'); + this._canvas.width = parent.width; + this._canvas.height = parent.height; + this._context = this._canvas.getContext('2d'); + } + Mirror.prototype.start = /** + * This is the rectangular region to grab from the Camera used in the Mirror effect + * It is rendered to the Stage at Mirror.x/y (note the use of Stage coordinates, not World coordinates) + */ + function (x, y, region, fillColor) { + if (typeof fillColor === "undefined") { fillColor = 'rgba(0,0,100,0.5)'; } + this.x = x; + this.y = y; + this._mirrorX = region.x; + this._mirrorY = region.y; + this._mirrorWidth = region.width; + this._mirrorHeight = region.height; + if(fillColor) { + this._mirrorColor = fillColor; + this._context.fillStyle = this._mirrorColor; + } + }; + Mirror.prototype.postRender = /** + * Post-render is called during the objects render cycle, after the children/image data has been rendered. + * It happens directly BEFORE a canvas context.restore has happened if added to a Camera. + */ + function (camera, cameraX, cameraY, cameraWidth, cameraHeight) { + if(this.cls) { + this._context.clearRect(0, 0, this._mirrorWidth, this._mirrorHeight); + } + this._sx = cameraX + this._mirrorX; + this._sy = cameraY + this._mirrorY; + if(this.flipX == true && this.flipY == false) { + this._sx = 0; + } else if(this.flipY == true && this.flipX == false) { + this._sy = 0; + } + this._context.drawImage(this._game.stage.canvas, // Source Image + this._sx, // Source X (location within the source image) + this._sy, // Source Y + this._mirrorWidth, // Source Width + this._mirrorHeight, // Source Height + 0, // Destination X (where on the canvas it'll be drawn) + 0, // Destination Y + this._mirrorWidth, // Destination Width (always same as Source Width unless scaled) + this._mirrorHeight); + // Destination Height (always same as Source Height unless scaled) + if(this._mirrorColor) { + this._context.fillRect(0, 0, this._mirrorWidth, this._mirrorHeight); + } + //this._game.stage.context.save(); + if(this.flipX && this.flipY) { + this._game.stage.context.transform(-1, 0, 0, -1, this._mirrorWidth, this._mirrorHeight); + this._game.stage.context.drawImage(this._canvas, -this.x, -this.y); + } else if(this.flipX) { + this._game.stage.context.transform(-1, 0, 0, 1, this._mirrorWidth, 0); + this._game.stage.context.drawImage(this._canvas, -this.x, this.y); + } else if(this.flipY) { + this._game.stage.context.transform(1, 0, 0, -1, 0, this._mirrorHeight); + this._game.stage.context.drawImage(this._canvas, this.x, -this.y); + } + //this._game.stage.context.restore(); + }; + return Mirror; + })(); + Camera.Mirror = Mirror; + })(FX.Camera || (FX.Camera = {})); + var Camera = FX.Camera; + })(Phaser.FX || (Phaser.FX = {})); + var FX = Phaser.FX; +})(Phaser || (Phaser = {})); +var Phaser; (function (Phaser) { (function (FX) { /// diff --git a/build/phaser.d.ts b/build/phaser.d.ts index c89c85e3..b088bca4 100644 --- a/build/phaser.d.ts +++ b/build/phaser.d.ts @@ -564,6 +564,7 @@ module Phaser { public scroll: MicroPoint; public bounds: Rectangle; public deadzone: Rectangle; + public disableClipping: bool; public showBorder: bool; public borderColor: string; public opaque: bool; @@ -5274,7 +5275,7 @@ module Phaser { public update(): void; public inCamera(camera: Rectangle): bool; public render(camera: Camera, cameraOffsetX: number, cameraOffsetY: number): bool; - public renderPoint(offsetX, offsetY, point, size): void; + public renderPoint(point, offsetX?: number, offsetY?: number, size?: number): void; public renderDebugInfo(x: number, y: number, color?: string): void; public collide(source: GeomSprite): bool; } diff --git a/build/phaser.js b/build/phaser.js index 59fe8d15..5ac07e62 100644 --- a/build/phaser.js +++ b/build/phaser.js @@ -925,6 +925,7 @@ var Phaser; this.bounds = null; this.deadzone = null; // Camera Border + this.disableClipping = false; this.showBorder = false; this.borderColor = 'rgb(255,255,255)'; // Camera Background Color @@ -1113,7 +1114,7 @@ var Phaser; } this.fx.render(this, this._stageX, this._stageY, this.worldView.width, this.worldView.height); // Clip the camera so we don't get sprites appearing outside the edges - if(this._clip) { + if(this._clip && this.disableClipping == false) { this._game.stage.context.beginPath(); this._game.stage.context.rect(this._sx, this._sy, this.worldView.width, this.worldView.height); this._game.stage.context.closePath(); @@ -1131,7 +1132,7 @@ var Phaser; this._game.stage.context.scale(1, 1); } this.fx.postRender(this, this._sx, this._sy, this.worldView.width, this.worldView.height); - if(this._rotation !== 0 || this._clip) { + if(this._rotation !== 0 || (this._clip && this.disableClipping == false)) { this._game.stage.context.translate(0, 0); } this._game.stage.context.restore(); @@ -10927,15 +10928,24 @@ var Phaser; } // And now the edge points this._game.stage.context.fillStyle = 'rgb(255,255,255)'; - this.renderPoint(this._dx, this._dy, this.rect.topLeft, 2); - this.renderPoint(this._dx, this._dy, this.rect.topCenter, 2); - this.renderPoint(this._dx, this._dy, this.rect.topRight, 2); - this.renderPoint(this._dx, this._dy, this.rect.leftCenter, 2); - this.renderPoint(this._dx, this._dy, this.rect.center, 2); - this.renderPoint(this._dx, this._dy, this.rect.rightCenter, 2); - this.renderPoint(this._dx, this._dy, this.rect.bottomLeft, 2); - this.renderPoint(this._dx, this._dy, this.rect.bottomCenter, 2); - this.renderPoint(this._dx, this._dy, this.rect.bottomRight, 2); + //this.renderPoint(this.rect.topLeft, this._dx, this._dy, 2); + //this.renderPoint(this.rect.topCenter, this._dx, this._dy, 2); + //this.renderPoint(this.rect.topRight, this._dx, this._dy, 2); + //this.renderPoint(this.rect.leftCenter, this._dx, this._dy, 2); + //this.renderPoint(this.rect.center, this._dx, this._dy, 2); + //this.renderPoint(this.rect.rightCenter, this._dx, this._dy, 2); + //this.renderPoint(this.rect.bottomLeft, this._dx, this._dy, 2); + //this.renderPoint(this.rect.bottomCenter, this._dx, this._dy, 2); + //this.renderPoint(this.rect.bottomRight, this._dx, this._dy, 2); + this.renderPoint(this.rect.topLeft, 0, 0, 2); + this.renderPoint(this.rect.topCenter, 0, 0, 2); + this.renderPoint(this.rect.topRight, 0, 0, 2); + this.renderPoint(this.rect.leftCenter, 0, 0, 2); + this.renderPoint(this.rect.center, 0, 0, 2); + this.renderPoint(this.rect.rightCenter, 0, 0, 2); + this.renderPoint(this.rect.bottomLeft, 0, 0, 2); + this.renderPoint(this.rect.bottomCenter, 0, 0, 2); + this.renderPoint(this.rect.bottomRight, 0, 0, 2); } this._game.stage.restoreCanvasValues(); if(this.rotation !== 0) { @@ -10947,10 +10957,11 @@ var Phaser; } return true; }; - GeomSprite.prototype.renderPoint = function (offsetX, offsetY, point, size) { - offsetX = 0; - offsetY = 0; - this._game.stage.context.fillRect(offsetX + point.x, offsetY + point.y, 1, 1); + GeomSprite.prototype.renderPoint = function (point, offsetX, offsetY, size) { + if (typeof offsetX === "undefined") { offsetX = 0; } + if (typeof offsetY === "undefined") { offsetY = 0; } + if (typeof size === "undefined") { size = 1; } + this._game.stage.context.fillRect(offsetX + point.x, offsetY + point.y, size, size); }; GeomSprite.prototype.renderDebugInfo = function (x, y, color) { if (typeof color === "undefined") { color = 'rgb(255,255,255)'; }